stubtest: error if a dunder method is missing from a stub#12203
Merged
hauntsaninja merged 13 commits intopython:masterfrom Feb 19, 2022
Merged
stubtest: error if a dunder method is missing from a stub#12203hauntsaninja merged 13 commits intopython:masterfrom
hauntsaninja merged 13 commits intopython:masterfrom
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.
AlexWaygood
commented
Feb 17, 2022
Comment on lines
246
to
291
| 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__ | ||
| }) |
Member
Author
There was a problem hiding this comment.
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.
Collaborator
hauntsaninja
left a comment
There was a problem hiding this comment.
This is great, thanks for doing this!
Contributor
|
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
Member
Author
|
Thanks! :D |
hauntsaninja
added a commit
that referenced
this pull request
Feb 20, 2022
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 was referenced Feb 22, 2022
hauntsaninja
pushed a commit
to hauntsaninja/mypy
that referenced
this pull request
Mar 5, 2022
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 was referenced Mar 5, 2022
hauntsaninja
added a commit
that referenced
this pull request
Mar 5, 2022
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 <>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
Details
array,tracemallocandunittest.mocktypeshed#7248ipaddressdunders typeshed#7244__(deep)copy__methods typeshed#7242types: Add several missing__(qual)name__attributes typeshed#7216builtinstypeshed#7214itertools.repeat.__length_hint__method typeshed#7212traceback.FrameSummarytypeshed#7210traceback.FrameSummarytypeshed#7210collections: Add missing reflected BinOp methods typeshed#7207EnumMeta.__bool__typeshed#7206__isabstractmethods__attributes inabcandfunctoolstypeshed#7205dataclassesandfunctoolstypeshed#7203With these typeshed fixes merged, here are the new errors stubtest reports from checking typeshed, with this patch applied:
Details
Notes on the new errors reported
typingandcollections.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_valuesanddict_itemshaving positional-only differences withtyping.KeysView,typing.ValuesViewandtyping.ItemsView. The way to resolve that would be essentially duplicate every method fromtyping.{Keys, Values, Items}Viewinto 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#7243superhas 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.cookieshas some really weird__str__methods.functools.partial.__vectorcalloffset__: no idea what this does or is for.platform.uname_resultis a mess in CPython.pstatshits: 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!