Skip to content
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

stubtest: distinguish metaclass attributes from class attributes #18314

Merged
merged 3 commits into from
Dec 20, 2024

Conversation

tungol
Copy link
Contributor

@tungol tungol commented Dec 19, 2024

If the runtime attribute of a class is actually from the metaclass, consider it to be MISSING at runtime.

This only occurs a couple times in the stdlib: it shows up when a descriptor is present on the metaclass but not the class, and we want to lie in the stub and say it's a thing on the class anyway.

I found this after noticing that enum.auto.__or__ had a comment that said it
didn't exist at runtime, but stubtest thought that it actually did. The issue is that on 3.10+, type.__or__ is defined for the purpose of Union types, and stubtest doesn't know the difference between type.__or__ and __or__ on the actual class.

Currently this matches on these things in typeshed's stdlib:

abc.ABCMeta.__abstractmethods__
builtins.object.__annotations__
enum.auto.__or__
enum.auto.__ror__
types.NotImplementedType.__call__

This MR doesn't resolve any allowlist entries for typeshed, and it doesn't create any new ones either, but should generate more accurate error messages in this particular edge case.

If the runtime attribute of a class is actually from the metaclass,
consider it to be MISSING at runtime.
mypy/stubtest.py Outdated

# If it came from the metaclass, consider the runtime_attr to be MISSING
# for a more accurate message
if runtime_attr is not MISSING and type(runtime) != runtime:
Copy link
Member

Choose a reason for hiding this comment

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

Should != be is not?

And can you add a test that changes behavior with this patch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you're right. I'll have a test ready in a little bit.

@tungol
Copy link
Contributor Author

tungol commented Dec 20, 2024

Here's a test. In order to get it to where that test would not generate the error without this change, I had to make a different change so that method-wrapper types can also be considered a function by is_probably_a_function. That's the type that type.__call__ is, and if there's a downside to making is_probably_a_function aware of those it wasn't immediately apparent to me.

@JelleZijlstra JelleZijlstra merged commit d33cef8 into python:master Dec 20, 2024
13 checks passed
@tungol tungol deleted the stubtest_metaclass branch December 20, 2024 02:45
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.

2 participants