-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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: error if a dunder method is missing from a stub #12203
Conversation
This comment has been minimized.
This comment has been minimized.
2 similar comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
mypy/stubtest.py
Outdated
IGNORED_DUNDERS = frozenset({ | ||
# Very special attributes | ||
"__weakref__", | ||
"__slots__", | ||
"__dict__", | ||
"__text_signature__", | ||
"__match_args__", | ||
# Pickle methods | ||
"__setstate__", | ||
"__getstate__", | ||
"__getnewargs__", | ||
"__getinitargs__", | ||
"__reduce_ex__", | ||
"__reduce__", | ||
# typing implementation details | ||
"__parameters__", | ||
"__origin__", | ||
"__args__", | ||
"__orig_bases__", | ||
"__mro_entries__", | ||
"__forward_is_class__", | ||
"__forward_module__", | ||
"__final__", | ||
# isinstance/issubclass hooks that type-checkers don't usually care about | ||
"__instancecheck__", | ||
"__subclasshook__", | ||
"__subclasscheck__", | ||
# Dataclasses implementation details | ||
"__dataclass_fields__", | ||
"__dataclass_params__", | ||
# ctypes weirdness | ||
"__ctype_be__", | ||
"__ctype_le__", | ||
"__ctypes_from_outparam__", | ||
# Two float methods only used internally for CPython test suite, not for public use | ||
"__set_format__", | ||
"__getformat__", | ||
# These two are basically useless for type checkers | ||
"__hash__", | ||
"__getattr__", | ||
# For some reason, mypy doesn't infer classes with metaclass=ABCMeta inherit this attribute | ||
"__abstractmethods__", | ||
"__doc__", # Can only ever be str | None, who cares? | ||
"__del__", # Only ever called when an object is being deleted, who cares? | ||
"__new_member__", # If an enum defines __new__, the method is renamed as __new_member__ | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fairly arbitrary ignorelist, based on the hits that this patch initially came up with, combined with my judgement as to which were worth fixing and which weren't. I'm happy to add or remove items!
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, thanks for doing this!
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
Thanks! :D |
Basically a follow up to #12203 New errors in typeshed from this: ``` _decimal.__libmpdec_version__ is not present in stub _heapq.__about__ is not present in stub builtins.__build_class__ is not present in stub cgitb.__UNDEF__ is not present in stub decimal.__libmpdec_version__ is not present in stub sys.__unraisablehook__ is not present in stub ``` Some general housekeeping, moving things around, renaming things, adding some comments.
This isn't actually a reversion. This logic was asymmetrical for reasons lost to time. Although I suspect it was this way because it introduced only a few errors on typeshed. What changed was that as a result of python#12203 we actually started checking a lot more dunder methods. Previously, we only checked dunders if either: a) it was a special dunder, like __init__ or __call, or b) the dunder was defined on the actual stub class itself In particular, we started checking every dunder redefined at runtime that the stub just inherited from object. A possible intermediate option would be to not check positional-only arguments in the case where a stub inherits the definition. I'll experiment with that once typeshed CI is green.
This isn't actually a reversion. This logic was asymmetrical for reasons lost to time. Although I suspect it was this way because the delta only a few errors on typeshed. What changed was that as a result of #12203 we actually started checking a lot more dunder methods. Previously, we only checked dunders if either: a) it was a special dunder, like `__init__` or `__call__`, or b) the dunder was defined on the actual stub class itself In particular, we started checking every dunder redefined at runtime that the stub just inherited from object. A possible intermediate option would be to not check positional-only arguments in the case where a stub inherits the definition. I'll experiment with that once typeshed CI is green. Co-authored-by: hauntsaninja <>
Description
This PR alters stubtest so that it raises an error if a dunder method is missing from a stub. Currently, stubtest does raise an error for a few missing dunders (
__call__
,__class_getitem__
, etc.). However, for the vast majority of them, it does not raise an error.I have been using this patch to provide a number of fixes to typeshed over the past week or so:
array
,tracemalloc
andunittest.mock
typeshed#7248ipaddress
dunders typeshed#7244__(deep)copy__
methods typeshed#7242types
: Add several missing__(qual)name__
attributes typeshed#7216builtins
typeshed#7214itertools.repeat.__length_hint__
method typeshed#7212traceback.FrameSummary
typeshed#7210traceback.FrameSummary
typeshed#7210collections
: Add missing reflected BinOp methods typeshed#7207EnumMeta.__bool__
typeshed#7206__isabstractmethods__
attributes inabc
andfunctools
typeshed#7205dataclasses
andfunctools
typeshed#7203With these typeshed fixes merged, here are the new errors stubtest reports from checking typeshed, with this patch applied:
Notes on the new errors reported
typing
andcollections.abc
. These just need to be allowlisted imo, unless and until we find a good general solution to that problem (refs Decouple collections.abc types from typing aliases typeshed#6257)dict_keys
,dict_values
anddict_items
having positional-only differences withtyping.KeysView
,typing.ValuesView
andtyping.ItemsView
. The way to resolve that would be essentially duplicate every method fromtyping.{Keys, Values, Items}View
into those classes (but with pos-only args instead of pos-or-kw args). I don't really have the stomach to do that. These should probably just be allowlisted.weakref.ProxyType
,dbm.dum._Database
,lib2to3.pytree.Leaf
: I don't really know anything about these classes.enum.EnumMeta.__prepare__
: this will be resolved by AddEnumMeta.__prepare__
typeshed#7243super
has some really weird dunders.property.__set_name__
: this is a false positive -- it doesn't exist in real life, just needs to be allowlisted.http.cookies
has some really weird__str__
methods.functools.partial.__vectorcalloffset__
: no idea what this does or is for.platform.uname_result
is a mess in CPython.pstats
hits: these relate to a mypy bug indataclasses
__eq__
method generation (Mypy incorrectly infers that parameters are positional-only for__eq__
methods autogenerated with@dataclass
#12186).collections.Counter.__missing__
: this always raises an exception, but per Why iscollections.ChainMap.__missing__
defined in the stub? typeshed#7188, we could maybe add it to the stub.__bool__
overrides stubtest now complains about: we could add these to the stub, though they don't seem particularly useful, since they don't alter the default behaviour ofbool(x)
at all. (But I don't think__bool__
should be added to the list of ignored dunders: it was useful for this patch to flag the missing__bool__
method fixed in AddEnumMeta.__bool__
typeshed#7206, as that is an override that changes behaviour from the default.)uuid.UUID.__setattr__
: this always raises an exception, I think it should just be allowlisted.Test Plan
I've altered the existing tests so they continue to pass, and added two new test cases.
cc. @hauntsaninja: here is the promised follow-up PR!