You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Keep mypy from thinking Git has arbitrary class attributes
The existence of __getattr__ or __getattribute__ on a class causes
static type checkers like mypy to stop inferring that reads of
unrecognized instance attributes are static type errors. When the
class is a metaclass, this causes static type checkers to stop
inferring that reads of unrecognized class attributes, on classes
that use (i.e., that have as their type) the metaclass, are static
type errors.
The Git class itself defines __getattr__ and __getattribute__, but
Git objects' instance attributes really are dynamically synthesized
(in __getattr__). However, class attributes of Git are not dynamic,
even though _GitMeta defines __getattribute__. Therefore, something
special is needed so mypy infers nothing about Git class attributes
from the existence of _GitMeta.__getattribute__.
This takes the same approach as taken to the analogous problem with
__getattr__ at module level, defining __getattribute__ with a
different name first and then assigning that to __getattribute__
under an `if not TYPE_CHECKING:`. (Allowing static type checkers to
see the original definition allows them to find some kinds of type
errors in the body of the method, which is why the method isn't
just defined in the `if not TYPE_CHECKING`.)
Although it may not currently be necessary to hide __setattr__ too,
the same is done with it in _GitMeta as well. The reason is that
the intent may otherwise be subtly amgiguous to human readers and
maybe future tools: when __setattr__ exists, the effect of setting
a class attribute that did not previously exist is in principle
unclear, and might not make the attribute readble. (I am unsure if
this is the right choice; either approach seems reasonable.)
0 commit comments