From fead69ab4e096af4f2100900f5a35005c7b86631 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 26 Sep 2026 10:10:55 +0200 Subject: [PATCH] Mypy 2.3 update (#11611) * Fix squeeze for non-string dimension names * Update mypy to 2.3.1 * Sync the mypy version in CI with the pre-commit hook * Fix the mypy-based tests for mypy 2 --------- Co-authored-by: Claude --- .pre-commit-config.yaml | 15 +++ _stubtest/allowlist.txt | 134 ----------------------- pixi.toml | 2 +- pyproject.toml | 3 - xarray/computation/computation.py | 5 +- xarray/core/common.py | 2 +- xarray/core/dataset.py | 1 + xarray/indexes/nd_point_index.py | 4 +- xarray/tests/test_dataarray.py | 11 +- xarray/tests/test_dataarray_typing.yml | 22 ++-- xarray/tests/test_dataset_typing.yml | 22 ++-- xarray/tests/test_datatree_typing.yml | 22 ++-- xarray/tests/test_deprecation_helpers.py | 30 ++--- xarray/tests/test_groupby.py | 2 +- xarray/tests/test_indexing.py | 1 + 15 files changed, 78 insertions(+), 198 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9caa6ea1f7b..d5584fc81d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,6 +59,21 @@ repos: typing-extensions>=4.1.0, numpy, ] + # keep the mypy version used in CI (pixi.toml) in sync with the hook above, so that the + # pre-commit.ci autoupdate also updates mypy in CI + - repo: local + hooks: + - id: sync-mypy-version + name: sync the mypy version in pixi.toml + language: python + files: ^\.pre-commit-config\.yaml$ + pass_filenames: false + entry: >- + python -c "import pathlib, re; + config = pathlib.Path('.pre-commit-config.yaml').read_text(); + version = re.search(r'mirrors-mypy\s+rev: v?([0-9.]+)', config).group(1); + pixi = pathlib.Path('pixi.toml'); + pixi.write_text(re.sub(r'(?m)^mypy = \"==[0-9.]+\"', f'mypy = \"=={version}\"', pixi.read_text()))" - repo: https://github.com/citation-file-format/cff-converter-python rev: 5295f87c0e261da61a7b919fc754e3a77edd98a7 hooks: diff --git a/_stubtest/allowlist.txt b/_stubtest/allowlist.txt index eabb0d7999b..d5816eaa595 100644 --- a/_stubtest/allowlist.txt +++ b/_stubtest/allowlist.txt @@ -6,127 +6,22 @@ # Format: Each line is a regex pattern matching fully qualified names to ignore. # See: https://mypy.readthedocs.io/en/stable/stubtest.html#allowlist -# ============================================================================= -# typing module re-exports (metaclass/signature differences) -# ============================================================================= - -# Any has metaclass differences between stub and runtime -xarray\.core\.(dataarray|dataset|variable)\.Any$ -xarray\.core\.(dataarray|dataset|variable)\.Any\.__new__$ - -# Callable also has metaclass differences -xarray\.core\.(dataarray|dataset|variable)\.Callable$ - -# Self is a TYPE_CHECKING import -xarray\.core\.(dataarray|variable)\.Self$ - -# TypeVar has __mro_entries__ at runtime but not in stubs -xarray\.core\.dataarray\.TypeVar\.__mro_entries__$ - # ============================================================================= # TYPE_CHECKING imports - not present at runtime # ============================================================================= -# Type aliases from xarray.core.types -xarray\.core\.(dataarray|dataset|variable)\.Dims$ -xarray\.core\.(dataarray|dataset)\.DatetimeLike$ -xarray\.core\.(dataarray|dataset)\.DatetimeUnitOptions$ -xarray\.core\.(dataarray|dataset)\.ErrorOptions$ -xarray\.core\.(dataarray|dataset|variable)\.ErrorOptionsWithWarn$ -xarray\.core\.(dataarray|dataset)\.GroupIndices$ -xarray\.core\.(dataarray|dataset)\.GroupInput$ -xarray\.core\.(dataarray|dataset)\.Grouper$ -xarray\.core\.(dataarray|dataset)\.InterpOptions$ -xarray\.core\.(dataarray|dataset)\.NetcdfWriteModes$ -xarray\.core\.(dataarray|dataset|variable)\.PadModeOptions$ -xarray\.core\.(dataarray|dataset|variable)\.PadReflectOptions$ -xarray\.core\.(dataarray|dataset|variable)\.QuantileMethods$ -xarray\.core\.(dataarray|dataset)\.QueryEngineOptions$ -xarray\.core\.(dataarray|dataset)\.QueryParserOptions$ -xarray\.core\.(dataarray|dataset)\.ReindexMethodOptions$ -xarray\.core\.(dataarray|dataset)\.ResampleCompatible$ -xarray\.core\.(dataarray|dataset)\.Resampler$ -xarray\.core\.(dataarray|dataset)\.SideOptions$ -xarray\.core\.(dataarray|dataset)\.CoarsenBoundaryOptions$ -xarray\.core\.(dataarray|dataset)\.ZarrWriteModes$ -xarray\.core\.(dataarray|dataset)\.ZarrStore$ -xarray\.core\.(dataarray|dataset)\.ZarrStoreLike$ -xarray\.core\.(dataarray|dataset)\.ArrayLike$ -xarray\.core\.dataset\.CFCalendar$ -xarray\.core\.dataset\.CombineAttrsOptions$ -xarray\.core\.dataset\.CompatOptions$ -xarray\.core\.dataset\.JoinOptions$ -xarray\.core\.dataset\.CoercibleMapping$ -xarray\.core\.dataset\.CoercibleValue$ -xarray\.core\.dataset\.DataVars$ -xarray\.core\.dataset\.DsCompatible$ - # TypeVars -xarray\.core\.(dataarray|dataset)\.T_ChunkDimFreq$ -xarray\.core\.(dataarray|dataset)\.T_ChunksFreq$ -xarray\.core\.(dataarray|dataset|variable)\.T_Chunks$ -xarray\.core\.(dataarray|dataset)\.T_NetcdfEngine$ -xarray\.core\.(dataarray|dataset)\.T_NetcdfTypes$ -xarray\.core\.(dataarray|dataset)\.T_Xarray$ xarray\.core\.dataarray\.T_XarrayOther$ -xarray\.core\.dataset\.T_DatasetPadConstantValues$ -xarray\.core\.variable\.T_DuckArray$ -xarray\.core\.variable\.T_VarPadConstantValues$ # External library types (dask, delayed, etc.) -xarray\.core\.(dataarray|dataset|variable)\.ChunkManagerEntrypoint$ -xarray\.core\.(dataarray|dataset)\.DaskDataFrame$ -xarray\.core\.(dataarray|dataset)\.Delayed$ -xarray\.core\.dataset\.AbstractDataStore$ xarray\.core\.dataarray\.iris_Cube$ -# DataArray TYPE_CHECKING import in dataset module -xarray\.core\.dataset\.DataArray$ - -# NamedArray TYPE_CHECKING import -xarray\.core\.variable\.NamedArray$ - -# ============================================================================= -# GroupBy/Rolling/Coarsen/Weighted/Resample classes (TYPE_CHECKING imports) -# ============================================================================= - -xarray\.core\.dataarray\.DataArrayGroupBy$ -xarray\.core\.dataarray\.DataArrayCoarsen$ -xarray\.core\.dataarray\.DataArrayRolling$ -xarray\.core\.dataarray\.DataArrayWeighted$ -xarray\.core\.dataarray\.DataArrayResample$ -xarray\.core\.dataset\.DatasetGroupBy$ -xarray\.core\.dataset\.DatasetCoarsen$ -xarray\.core\.dataset\.DatasetRolling$ -xarray\.core\.dataset\.DatasetWeighted$ -xarray\.core\.dataset\.DatasetResample$ - -# ============================================================================= -# CFTimeIndex properties - read-only at runtime -# ============================================================================= - -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.date_type$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.day$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.day_of_week$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.dayofweek$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.day_of_year$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.dayofyear$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.days_in_month$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.hour$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.microsecond$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.minute$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.month$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.second$ -xarray\.core\.(dataarray|dataset)\.CFTimeIndex\.year$ - # ============================================================================= # Plot accessors and methods # ============================================================================= xarray\.core\.dataarray\.DataArray\.plot$ xarray\.core\.(dataarray|dataset)\.Dataset\.plot$ -xarray\.core\.dataarray\.DataArrayPlotAccessor\.(contour|contourf|imshow|line|pcolormesh|scatter|step|surface)$ -xarray\.core\.dataset\.DatasetPlotAccessor\.(quiver|scatter|streamplot)$ # ============================================================================= # __array__ method - complex numpy protocol @@ -134,27 +29,6 @@ xarray\.core\.dataset\.DatasetPlotAccessor\.(quiver|scatter|streamplot)$ xarray\.core\.(dataarray|dataset)\.Dataset\.__array__$ -# ============================================================================= -# Mapping/MutableMapping/Sequence/Iterable protocol methods -# ============================================================================= - -xarray\.core\.(dataarray|dataset|variable)\.Mapping\.get$ -xarray\.core\.(dataarray|dataset|variable)\.Mapping\.__reversed__$ -xarray\.core\.(dataarray|dataset|variable)\.Sequence\.index$ -xarray\.core\.(dataarray|dataset)\.Iterable\.__class_getitem__$ -xarray\.core\.(dataarray|dataset)\.MutableMapping\.(pop|setdefault)$ -xarray\.core\.(dataarray|dataset)\.PathLike\.__class_getitem__$ -xarray\.core\.dataset\.FrozenMappingWarningOnValuesAccess\.get$ - -# Number.__hash__ -xarray\.core\.dataset\.Number\.__hash__$ - -# ============================================================================= -# IO protocol (typing.IO) -# ============================================================================= - -xarray\.core\.dataset\.IO\.(closed|mode|name|read|readline|readlines|seek|truncate|write|writelines|__iter__|__next__)$ - # ============================================================================= # Variable/IndexVariable methods inherited from numpy-like interface # ============================================================================= @@ -162,11 +36,3 @@ xarray\.core\.dataset\.IO\.(closed|mode|name|read|readline|readlines|seek|trunca xarray\.core\.(dataarray|dataset|variable)\.Variable\.(item|searchsorted)$ xarray\.core\.(dataarray|dataset|variable)\.IndexVariable\.(item|searchsorted)$ xarray\.core\.dataarray\.DataArray\.(item|searchsorted)$ -xarray\.core\.dataarray\.DataArrayArithmetic\.(item|searchsorted)$ -xarray\.core\.variable\.VariableArithmetic\.(item|searchsorted)$ - -# ============================================================================= -# Subclass pattern for Variable -# ============================================================================= - -xarray\.core\.variable\. None: def test_loc(self) -> None: self.ds["x"] = ("x", np.array(list("abcdefghij"))) da = self.ds["foo"] - # typing issue: see https://github.com/python/mypy/issues/2410 - assert_identical(da[:3], da.loc[:"c"]) # type: ignore[misc] + assert_identical(da[:3], da.loc[:"c"]) assert_identical(da[1], da.loc["b"]) assert_identical(da[1], da.loc[{"x": "b"}]) assert_identical(da[1], da.loc["b", ...]) @@ -1347,8 +1346,7 @@ def test_loc_assign(self) -> None: self.ds["x"] = ("x", np.array(list("abcdefghij"))) da = self.ds["foo"] # assignment - # typing issue: see https://github.com/python/mypy/issues/2410 - da.loc["a":"j"] = 0 # type: ignore[misc] + da.loc["a":"j"] = 0 assert np.all(da.values == 0) da.loc[{"x": slice("a", "j")}] = 2 assert np.all(da.values == 2) @@ -2921,6 +2919,11 @@ def test_transpose(self) -> None: def test_squeeze(self) -> None: assert_equal(self.dv.variable.squeeze(), self.dv.squeeze().variable) + def test_squeeze_non_str_dim_name(self) -> None: + array = DataArray(np.zeros((1, 3)), dims=[0, "y"]) + expected = DataArray(np.zeros(3), dims=["y"]) + assert_identical(array.squeeze(), expected) + def test_squeeze_drop(self) -> None: array = DataArray([1], [("x", [0])]) expected = DataArray(1) diff --git a/xarray/tests/test_dataarray_typing.yml b/xarray/tests/test_dataarray_typing.yml index aa49473b662..05fa4995081 100644 --- a/xarray/tests/test_dataarray_typing.yml +++ b/xarray/tests/test_dataarray_typing.yml @@ -12,7 +12,7 @@ da = DataArray().pipe(lambda data, arg: arg, "foo") - reveal_type(da) # N: Revealed type is "builtins.str" + reveal_type(da) # N: Revealed type is "str" - case: test_mypy_pipe_lambda_chaining_return_type main: | @@ -20,7 +20,7 @@ answer = DataArray().pipe(lambda data, arg: arg, "foo").count("o") - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_lambda_missing_arg main: | @@ -31,7 +31,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[Any, Any], Any]" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_lambda_extra_arg @@ -43,7 +43,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[Any], Any]", "str" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_posarg @@ -58,7 +58,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[DataArray, int], DataArray]" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_extra_posarg @@ -73,7 +73,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[DataArray, int], DataArray]", "int", "str" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_kwarg @@ -88,7 +88,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "def f(da: DataArray, arg: int, *, kwonly: int) -> DataArray", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_keyword @@ -103,7 +103,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "def f(da: DataArray, arg: int, *, kwonly: int) -> DataArray", "int", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_unexpected_keyword @@ -141,7 +141,7 @@ answer = DataArray().pipe((f, "da"), 42) - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_tuple_missing_arg main: | @@ -165,7 +165,7 @@ out: | main:17: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[Any, Any], DataArray]" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_tuple_extra_arg @@ -190,5 +190,5 @@ out: | main:17: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[Any, Any], DataArray]", "int", "str" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[DataArray, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T diff --git a/xarray/tests/test_dataset_typing.yml b/xarray/tests/test_dataset_typing.yml index 5198189935e..acc5fae3b16 100644 --- a/xarray/tests/test_dataset_typing.yml +++ b/xarray/tests/test_dataset_typing.yml @@ -12,7 +12,7 @@ ds = Dataset().pipe(lambda data, arg: arg, "foo") - reveal_type(ds) # N: Revealed type is "builtins.str" + reveal_type(ds) # N: Revealed type is "str" - case: test_mypy_pipe_lambda_chaining_return_type main: | @@ -20,7 +20,7 @@ answer = Dataset().pipe(lambda data, arg: arg, "foo").count("o") - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_lambda_missing_arg main: | @@ -31,7 +31,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[Any, Any], Any]" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_lambda_extra_arg @@ -43,7 +43,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[Any], Any]", "str" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_posarg @@ -58,7 +58,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[Dataset, int], Dataset]" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_extra_posarg @@ -73,7 +73,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[Dataset, int], Dataset]", "int", "str" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_kwarg @@ -88,7 +88,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "def f(ds: Dataset, arg: int, *, kwonly: int) -> Dataset", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_keyword @@ -103,7 +103,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "def f(ds: Dataset, arg: int, *, kwonly: int) -> Dataset", "int", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_unexpected_keyword @@ -140,7 +140,7 @@ answer = Dataset().pipe((f, "ds"), 42) - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_tuple_missing_arg main: | @@ -164,7 +164,7 @@ out: | main:17: error: No overload variant of "pipe" of "DataWithCoords" matches argument type "Callable[[Any, Any], Dataset]" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_tuple_extra_arg @@ -189,5 +189,5 @@ out: | main:17: error: No overload variant of "pipe" of "DataWithCoords" matches argument types "Callable[[Any, Any], Dataset]", "int", "str" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[Dataset, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T diff --git a/xarray/tests/test_datatree_typing.yml b/xarray/tests/test_datatree_typing.yml index fa19515404d..a2984219e0a 100644 --- a/xarray/tests/test_datatree_typing.yml +++ b/xarray/tests/test_datatree_typing.yml @@ -12,7 +12,7 @@ dt = DataTree().pipe(lambda data, arg: arg, "foo") - reveal_type(dt) # N: Revealed type is "builtins.str" + reveal_type(dt) # N: Revealed type is "str" - case: test_mypy_pipe_lambda_chaining_return_type main: | @@ -20,7 +20,7 @@ answer = DataTree().pipe(lambda data, arg: arg, "foo").count("o") - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_lambda_missing_arg main: | @@ -31,7 +31,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataTree" matches argument type "Callable[[Any, Any], Any]" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_lambda_extra_arg @@ -43,7 +43,7 @@ out: | main:4: error: No overload variant of "pipe" of "DataTree" matches argument types "Callable[[Any], Any]", "str" [call-overload] main:4: note: Possible overload variants: - main:4: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:4: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:4: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_posarg @@ -58,7 +58,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataTree" matches argument type "Callable[[DataTree, int], DataTree]" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_extra_posarg @@ -73,7 +73,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataTree" matches argument types "Callable[[DataTree, int], DataTree]", "int", "str" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_kwarg @@ -88,7 +88,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataTree" matches argument types "def f(dt: DataTree, arg: int, *, kwonly: int) -> DataTree", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_missing_keyword @@ -103,7 +103,7 @@ out: | main:7: error: No overload variant of "pipe" of "DataTree" matches argument types "def f(dt: DataTree, arg: int, *, kwonly: int) -> DataTree", "int", "int" [call-overload] main:7: note: Possible overload variants: - main:7: note: def [P`2, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:7: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:7: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_function_unexpected_keyword @@ -141,7 +141,7 @@ answer = DataTree().pipe((f, "dt"), 42) - reveal_type(answer) # N: Revealed type is "builtins.int" + reveal_type(answer) # N: Revealed type is "int" - case: test_mypy_pipe_tuple_missing_arg main: | @@ -165,7 +165,7 @@ out: | main:17: error: No overload variant of "pipe" of "DataTree" matches argument type "Callable[[Any, Any], DataTree]" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T - case: test_mypy_pipe_tuple_extra_arg @@ -190,5 +190,5 @@ out: | main:17: error: No overload variant of "pipe" of "DataTree" matches argument types "Callable[[Any, Any], DataTree]", "int", "str" [call-overload] main:17: note: Possible overload variants: - main:17: note: def [P`9, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T + main:17: note: def [P, T] pipe(self, func: Callable[[DataTree, **P], T], *args: P.args, **kwargs: P.kwargs) -> T main:17: note: def [T] pipe(self, func: tuple[Callable[..., T], str], *args: Any, **kwargs: Any) -> T diff --git a/xarray/tests/test_deprecation_helpers.py b/xarray/tests/test_deprecation_helpers.py index f21c8097060..87ad8a6917d 100644 --- a/xarray/tests/test_deprecation_helpers.py +++ b/xarray/tests/test_deprecation_helpers.py @@ -15,15 +15,15 @@ def f1(a, b, *, c="c", d="d"): assert result == (1, 2, 3, 4) with pytest.warns(FutureWarning, match=r".*v0.1"): - result = f1(1, 2, 3) # type: ignore[misc] + result = f1(1, 2, 3) # type: ignore[call-arg] assert result == (1, 2, 3, "d") with pytest.warns(FutureWarning, match=r"Passing 'c' as positional"): - result = f1(1, 2, 3) # type: ignore[misc] + result = f1(1, 2, 3) # type: ignore[call-arg] assert result == (1, 2, 3, "d") with pytest.warns(FutureWarning, match=r"Passing 'c, d' as positional"): - result = f1(1, 2, 3, 4) # type: ignore[misc] + result = f1(1, 2, 3, 4) # type: ignore[call-arg] assert result == (1, 2, 3, 4) @_deprecate_positional_args("v0.1") @@ -31,7 +31,7 @@ def f2(a="a", *, b="b", c="c", d="d"): return a, b, c, d with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = f2(1, 2) # type: ignore[misc] + result = f2(1, 2) # type: ignore[call-arg] assert result == (1, 2, "c", "d") @_deprecate_positional_args("v0.1") @@ -39,11 +39,11 @@ def f3(a, *, b="b", **kwargs): return a, b, kwargs with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = f3(1, 2) # type: ignore[misc] + result = f3(1, 2) # type: ignore[call-arg] assert result == (1, 2, {}) with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = f3(1, 2, f="f") # type: ignore[misc] + result = f3(1, 2, f="f") # type: ignore[call-arg] assert result == (1, 2, {"f": "f"}) @_deprecate_positional_args("v0.1") @@ -57,7 +57,7 @@ def f4(a, /, *, b="b", **kwargs): assert result == (1, 2, {"f": "f"}) with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = f4(1, 2, f="f") # type: ignore[misc] + result = f4(1, 2, f="f") # type: ignore[call-arg] assert result == (1, 2, {"f": "f"}) with pytest.raises(TypeError, match=r"Keyword-only param without default"): @@ -80,15 +80,15 @@ def method(self, a, b, *, c="c", d="d"): assert result == (1, 2, 3, 4) with pytest.warns(FutureWarning, match=r".*v0.1"): - result = A1().method(1, 2, 3) # type: ignore[misc] + result = A1().method(1, 2, 3) # type: ignore[call-arg] assert result == (1, 2, 3, "d") with pytest.warns(FutureWarning, match=r"Passing 'c' as positional"): - result = A1().method(1, 2, 3) # type: ignore[misc] + result = A1().method(1, 2, 3) # type: ignore[call-arg] assert result == (1, 2, 3, "d") with pytest.warns(FutureWarning, match=r"Passing 'c, d' as positional"): - result = A1().method(1, 2, 3, 4) # type: ignore[misc] + result = A1().method(1, 2, 3, 4) # type: ignore[call-arg] assert result == (1, 2, 3, 4) class A2: @@ -97,11 +97,11 @@ def method(self, a=1, b=1, *, c="c", d="d"): return a, b, c, d with pytest.warns(FutureWarning, match=r"Passing 'c' as positional"): - result = A2().method(1, 2, 3) # type: ignore[misc] + result = A2().method(1, 2, 3) # type: ignore[call-arg] assert result == (1, 2, 3, "d") with pytest.warns(FutureWarning, match=r"Passing 'c, d' as positional"): - result = A2().method(1, 2, 3, 4) # type: ignore[misc] + result = A2().method(1, 2, 3, 4) # type: ignore[call-arg] assert result == (1, 2, 3, 4) class A3: @@ -110,11 +110,11 @@ def method(self, a, *, b="b", **kwargs): return a, b, kwargs with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = A3().method(1, 2) # type: ignore[misc] + result = A3().method(1, 2) # type: ignore[call-arg] assert result == (1, 2, {}) with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = A3().method(1, 2, f="f") # type: ignore[misc] + result = A3().method(1, 2, f="f") # type: ignore[call-arg] assert result == (1, 2, {"f": "f"}) class A4: @@ -129,7 +129,7 @@ def method(self, a, /, *, b="b", **kwargs): assert result == (1, 2, {"f": "f"}) with pytest.warns(FutureWarning, match=r"Passing 'b' as positional"): - result = A4().method(1, 2, f="f") # type: ignore[misc] + result = A4().method(1, 2, f="f") # type: ignore[call-arg] assert result == (1, 2, {"f": "f"}) with pytest.raises(TypeError, match=r"Keyword-only param without default"): diff --git a/xarray/tests/test_groupby.py b/xarray/tests/test_groupby.py index 99db678820f..b00ef4da98c 100644 --- a/xarray/tests/test_groupby.py +++ b/xarray/tests/test_groupby.py @@ -3059,7 +3059,7 @@ def test_multiple_groupers_string(as_dataset) -> None: # warning & type error in the future with pytest.warns(FutureWarning): with pytest.raises(TypeError): - obj.groupby("labels1", "labels2") # type: ignore[arg-type, misc] + obj.groupby("labels1", "labels2") # type: ignore[arg-type, call-arg] with pytest.raises(ValueError): obj.groupby("labels1", foo="bar") # type: ignore[arg-type] with pytest.raises(ValueError): diff --git a/xarray/tests/test_indexing.py b/xarray/tests/test_indexing.py index 36d7d58235c..c8193ac1e64 100644 --- a/xarray/tests/test_indexing.py +++ b/xarray/tests/test_indexing.py @@ -537,6 +537,7 @@ def test_lazily_indexed_array_setitem(self, indexer_class, key, value) -> None: x = indexing.NumpyIndexingAdapter(original) lazy = indexing.LazilyIndexedArray(x) + indexer: indexing.ExplicitIndexer if indexer_class is indexing.BasicIndexer: indexer = indexer_class(key) lazy[indexer] = value