Skip to content

Prioritize .pyi from -stubs packages over bundled .pyi #19001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 1, 2025

Conversation

jorenham
Copy link
Contributor

@jorenham jorenham commented Apr 29, 2025

This fixes the import resolution order for stubs from a -stubs package and stubs bundled with a py.typed package, and fixes #18997.

Besides the unit tests, the effectiveness of this fix is also demonstrated at https://github.com/jorenham/mypy-pep561-numpy-issue#mypy-jorenhamfix-18997-with-numtype

After investigating a bit more, it looks like mypy's incorrect prioritization of stubs was limited to __init__.pyi. I confirmed this by adding reveal_type(np.dtypes.StringDType()) to the main.pyi in https://github.com/jorenham/mypy-pep561-numpy-issue. With mypy==1.15.0 installed, it correctly showed numpy.dtypes.StringDType without NumType, and numpy.dtypes.StringDType[Never] with NumType installed. So both #18997 and this PR only apply to __init__.pyi.

This comment has been minimized.

jorenham added a commit to jorenham/mypy-pep561-numpy-issue that referenced this pull request Apr 30, 2025
@@ -506,21 +506,24 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:
dir_prefix = base_dir
for _ in range(len(components) - 1):
dir_prefix = os.path.dirname(dir_prefix)

# Stubs-only packages always take precedence over py.typed packages
path_stubs = f"{base_path}-stubs{sepinit}.pyi"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm this assumes there is an __init__.pyi, I don't think that's required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's pretty much the same as the path_stubs = base_path + "-stubs" + sepinit + extension from before before 🤷🏻

Should I change it to something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea you're right, apparently this isn't the whole story:
I added some new tests for a.py[i], but those are failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm somehow the tests only fail if it's called a.pyi, and not when called spam.pyi. I'm guessing it's a caching thing. Either way, it's probably out out scope, and might be limited to these unit-tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm this assumes there is an __init__.pyi, I don't think that's required?

See the updated PR description

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I believe namespace packages are handled on L525 afterwards.

@jorenham jorenham marked this pull request as draft April 30, 2025 06:39
@jorenham jorenham marked this pull request as ready for review April 30, 2025 07:16
Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

porcupine (https://github.com/Akuli/porcupine)
- porcupine/plugins/highlight/tree_sitter_highlighter.py:49: error: "Parser" has no attribute "set_language"; maybe "language"?  [attr-defined]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:84: error: Item "None" of "bytes | None" has no attribute "decode"  [union-attr]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:95: error: Item "None" of "Node | None" has no attribute "start_point"  [union-attr]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:96: error: Item "None" of "Node | None" has no attribute "end_point"  [union-attr]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:101: error: Item "None" of "Node | None" has no attribute "type"  [union-attr]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:103: error: Argument 1 to "captures" of "Query" has incompatible type "Node | None"; expected "Node"  [arg-type]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:112: error: Unpacking a string is disallowed  [misc]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:113: error: Cannot determine type of "tag_or_recurse"  [has-type]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:114: error: Cannot determine type of "subnode"  [has-type]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:116: error: Cannot determine type of "subnode"  [has-type]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:116: error: Cannot determine type of "tag_or_recurse"  [has-type]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:126: error: Item "None" of "Node | None" has no attribute "type"  [union-attr]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:132: error: Incompatible types in "yield" (actual type "tuple[Node | None, str]", expected type "tuple[Node, str]")  [misc]
- porcupine/plugins/highlight/tree_sitter_highlighter.py:132: error: Argument 1 to "_decide_tag" of "TreeSitterHighlighter" has incompatible type "Node | None"; expected "Node"  [arg-type]

Copy link
Member

@emmatyping emmatyping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix! Note that the mypy docs do not supersede PEP 561, but rather the typing specification now contains the module resolution order: https://typing.python.org/en/latest/spec/distributing.html#mro

@jorenham
Copy link
Contributor Author

jorenham commented May 1, 2025

Thank you for the fix! Note that the mypy docs do not supersede PEP 561, but rather the typing specification now contains the module resolution order: typing.python.org/en/latest/spec/distributing.html#mro

Oh woops, I meant to reference the typing spec there.
Thanks for the review!

@JelleZijlstra JelleZijlstra merged commit 7f5a8dd into python:master May 1, 2025
18 checks passed
@jorenham jorenham deleted the fix-18997 branch May 1, 2025 02:44
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.

PEP 561 stub packages should take precedence over bundled .pyi stubs
3 participants