Skip to content

Fix mypy drift: cast xarray returns, drop deprecated numpy plugin#72

Draft
thodson-usgs wants to merge 1 commit intoxarray-contrib:mainfrom
thodson-usgs:mypy-drift-fixes
Draft

Fix mypy drift: cast xarray returns, drop deprecated numpy plugin#72
thodson-usgs wants to merge 1 commit intoxarray-contrib:mainfrom
thodson-usgs:mypy-drift-fixes

Conversation

@thodson-usgs
Copy link
Copy Markdown

@thodson-usgs thodson-usgs commented Apr 20, 2026

Summary

Recent mypy (1.20+) is stricter about no-any-return: functions declared
to return concrete xarray types can no longer silently return Any. Several
xarray operations (reindex_like, transpose, copy, rename, concat,
chunk bookkeeping) now come back typed as Any, tripping the check at 7
return sites across utils.py, methods/_shared.py, methods/interp.py,
and methods/conservative.py.

main last passed CI on 2026-02-06. If the lint job re-ran today against
current package versions it would fail on these 9 pre-existing errors, so
in-flight PRs (#70 / #71) can't go green without resolving the drift.

This PR also drops plugins = numpy.typing.mypy_plugin from [tool.mypy]
since that plugin is deprecated in numpy 2.3+ and slated for removal
(orthogonal to the no-any-return work, but cleaned up here for clarity).

Question to the maintainers — which fix do you prefer?

What this PR currently does is option A below, but it's not the only
reasonable choice and the commit is easy to rewrite. I'd appreciate a
preference before this is merged.

A. Add cast() at each of the 7 return sites (what this PR does).
Preserves warn_return_any = true — future leaks of Any back through
function boundaries still trip mypy, so the strictness is kept where
it's catching real bugs, with explicit acknowledgement at the known
false-positive sites.

  • Pro: keeps the strictness knob on.
  • Con: 7 cast(...) calls, a cast import in 4 files.

B. Drop warn_return_any = true globally from [tool.mypy].
One-line change, all 7 errors disappear. Consistent with the per-module
override that #70 already adds for conservative_2d for exactly this
reason — xarray's stubs don't narrow well enough for this check to be
net-positive project-wide.

  • Pro: minimal code churn.
  • Con: loses a legitimate check elsewhere.

C. Per-return # type: ignore[no-any-return] comments at each site.
Halfway between A and B — no cast import, but an inline waiver at
each site rather than a blanket silencing.

Happy to rewrite to B or C if either is preferred; just drop a comment.

Verified locally (option A)

  • hatch run lint → green (ruff + mypy + ruff format --check)
  • hatch run test → 71 passed, 1 skipped, 1 xfailed
  • hatch build → sdist + wheel built

Test plan

  • CI linting job passes
  • CI build & test matrix passes on all OS/Python combinations

🤖 Generated with Claude Code

Recent mypy (1.20) is stricter about returning Any from functions declared
to return concrete xarray types. Add `cast()` calls at 7 return sites where
xarray operations (reindex_like, transpose, copy, rename, concat, chunk
bookkeeping) come back typed as Any. Drop two `# type: ignore` comments
on xr.concat calls that no longer trip mypy.

Also drop `plugins = numpy.typing.mypy_plugin` from the mypy config —
the plugin is deprecated in numpy 2.3+ and slated for removal.

Runs `hatch run lint` / `hatch run test` / `hatch build` fully green
locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thodson-usgs
Copy link
Copy Markdown
Author

@BSchilperoort , I've left this PR in draft, but it notes three options for getting the CI passing. Do you have a preference? I don't have an opinion on this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant