diff --git a/ci/requirements/environment-windows.yml b/ci/requirements/environment-windows.yml
index 78ead40d5a2..2468ec6267e 100644
--- a/ci/requirements/environment-windows.yml
+++ b/ci/requirements/environment-windows.yml
@@ -39,6 +39,7 @@ dependencies:
- setuptools
- sparse
- toolz
+ - typing_extensions
- zarr
- pip:
- numbagg
diff --git a/ci/requirements/environment.yml b/ci/requirements/environment.yml
index f64ca3677cc..162faa7b74d 100644
--- a/ci/requirements/environment.yml
+++ b/ci/requirements/environment.yml
@@ -43,6 +43,7 @@ dependencies:
- setuptools
- sparse
- toolz
+ - typing_extensions
- zarr
- pip:
- numbagg
diff --git a/ci/requirements/py37-bare-minimum.yml b/ci/requirements/py37-bare-minimum.yml
index 408cf76fdd6..0cecf885436 100644
--- a/ci/requirements/py37-bare-minimum.yml
+++ b/ci/requirements/py37-bare-minimum.yml
@@ -13,3 +13,4 @@ dependencies:
- numpy=1.17
- pandas=1.0
- setuptools=40.4
+ - typing_extensions=3.7
diff --git a/ci/requirements/py37-min-all-deps.yml b/ci/requirements/py37-min-all-deps.yml
index 7c3230f87b0..c73c5327d3b 100644
--- a/ci/requirements/py37-min-all-deps.yml
+++ b/ci/requirements/py37-min-all-deps.yml
@@ -47,6 +47,7 @@ dependencies:
- setuptools=40.4
- sparse=0.8
- toolz=0.10
+ - typing_extensions=3.7
- zarr=2.4
- pip:
- numbagg==0.1
diff --git a/ci/requirements/py38-all-but-dask.yml b/ci/requirements/py38-all-but-dask.yml
index 3f82990f3b5..688dfb7a2bc 100644
--- a/ci/requirements/py38-all-but-dask.yml
+++ b/ci/requirements/py38-all-but-dask.yml
@@ -39,6 +39,7 @@ dependencies:
- setuptools
- sparse
- toolz
+ - typing_extensions
- zarr
- pip:
- numbagg
diff --git a/doc/getting-started-guide/installing.rst b/doc/getting-started-guide/installing.rst
index 93738da9d9b..c6bc84e6ddb 100644
--- a/doc/getting-started-guide/installing.rst
+++ b/doc/getting-started-guide/installing.rst
@@ -8,6 +8,7 @@ Required dependencies
- Python (3.7 or later)
- setuptools (40.4 or later)
+- ``typing_extensions`` (3.7 or later)
- `numpy `__ (1.17 or later)
- `pandas `__ (1.0 or later)
diff --git a/requirements.txt b/requirements.txt
index 732d40cde18..0fa83c8ccc1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,4 +5,4 @@
numpy >= 1.17
pandas >= 1.0
setuptools >= 40.4
-typing-extensions >= 3.10
+typing-extensions >= 3.7
diff --git a/setup.cfg b/setup.cfg
index aa8ca8df0ff..2dc1b7ffeca 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -78,6 +78,7 @@ python_requires = >=3.7
install_requires =
numpy >= 1.17
pandas >= 1.0
+ typing_extensions >= 3.7
setuptools >= 40.4 # For pkg_resources
[options.extras_require]
diff --git a/xarray/core/npcompat.py b/xarray/core/npcompat.py
index 6e22c8cf0a4..09f78c5971c 100644
--- a/xarray/core/npcompat.py
+++ b/xarray/core/npcompat.py
@@ -41,17 +41,10 @@
# fall back for numpy < 1.20, ArrayLike adapted from numpy.typing._array_like
if sys.version_info >= (3, 8):
from typing import Protocol
-
- HAVE_PROTOCOL = True
else:
- try:
- from typing_extensions import Protocol
- except ImportError:
- HAVE_PROTOCOL = False
- else:
- HAVE_PROTOCOL = True
+ from typing_extensions import Protocol
- if TYPE_CHECKING or HAVE_PROTOCOL:
+ if TYPE_CHECKING:
class _SupportsArray(Protocol):
def __array__(self) -> np.ndarray:
diff --git a/xarray/core/options.py b/xarray/core/options.py
index 14f77306316..c9e037e6fd6 100644
--- a/xarray/core/options.py
+++ b/xarray/core/options.py
@@ -6,70 +6,35 @@
# TODO: Remove this check once python 3.7 is not supported:
if sys.version_info >= (3, 8):
from typing import TYPE_CHECKING, Literal, TypedDict, Union
+else:
+ from typing import TYPE_CHECKING, Union
- if TYPE_CHECKING:
- try:
- from matplotlib.colors import Colormap
- except ImportError:
- Colormap = str
-
- class T_Options(TypedDict):
- arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
- cmap_divergent: Union[str, "Colormap"]
- cmap_sequential: Union[str, "Colormap"]
- display_max_rows: int
- display_style: Literal["text", "html"]
- display_width: int
- display_expand_attrs: Literal["default", True, False]
- display_expand_coords: Literal["default", True, False]
- display_expand_data_vars: Literal["default", True, False]
- display_expand_data: Literal["default", True, False]
- enable_cftimeindex: bool
- file_cache_maxsize: int
- keep_attrs: Literal["default", True, False]
- warn_for_unclosed_files: bool
- use_bottleneck: bool
+ from typing_extensions import Literal, TypedDict
-else:
- # See GH5624, this is a convoluted way to allow type-checking to use
- # `TypedDict` and `Literal` without requiring typing_extensions as a
- # required dependency to _run_ the code (it is required to type-check).
+if TYPE_CHECKING:
try:
- from typing import TYPE_CHECKING, Union
-
- from typing_extensions import Literal, TypedDict
-
- if TYPE_CHECKING:
- try:
- from matplotlib.colors import Colormap
- except ImportError:
- Colormap = str
-
- class T_Options(TypedDict):
- arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
- cmap_divergent: Union[str, "Colormap"]
- cmap_sequential: Union[str, "Colormap"]
- display_max_rows: int
- display_style: Literal["text", "html"]
- display_width: int
- display_expand_attrs: Literal["default", True, False]
- display_expand_coords: Literal["default", True, False]
- display_expand_data_vars: Literal["default", True, False]
- display_expand_data: Literal["default", True, False]
- enable_cftimeindex: bool
- file_cache_maxsize: int
- keep_attrs: Literal["default", True, False]
- warn_for_unclosed_files: bool
- use_bottleneck: bool
-
+ from matplotlib.colors import Colormap
except ImportError:
- from typing import TYPE_CHECKING, Any, Dict, Hashable
-
- if TYPE_CHECKING:
- raise
- else:
- T_Options = Dict[Hashable, Any]
+ Colormap = str
+
+
+class T_Options(TypedDict):
+ arithmetic_join: Literal["inner", "outer", "left", "right", "exact"]
+ cmap_divergent: Union[str, "Colormap"]
+ cmap_sequential: Union[str, "Colormap"]
+ display_max_rows: int
+ display_style: Literal["text", "html"]
+ display_width: int
+ display_expand_attrs: Literal["default", True, False]
+ display_expand_coords: Literal["default", True, False]
+ display_expand_data_vars: Literal["default", True, False]
+ display_expand_data: Literal["default", True, False]
+ enable_cftimeindex: bool
+ file_cache_maxsize: int
+ keep_attrs: Literal["default", True, False]
+ warn_for_unclosed_files: bool
+ use_bottleneck: bool
OPTIONS: T_Options = {