Skip to content

stubtest: Fix TypeType subtyping problem #13367

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

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

sobolevn
Copy link
Member

@sobolevn sobolevn commented Aug 9, 2022

Now this passes:

# STUB
class Meta(type): ...
class Y(metaclass=Meta): ...
class Z:
    foo: type[Y]

# RUNTIME:
class Meta(type): ...
class Y(metaclass=Meta): ...
class Z:
    foo = Y

Closes #13316

@sobolevn
Copy link
Member Author

sobolevn commented Aug 9, 2022

I will also add type/instance mismatch tests in a moment 🤔

@AlexWaygood
Copy link
Member

I will also add type/instance mismatch tests in a moment 🤔

Would be good to test ABCMeta specifically, as well, given how much it's special-cased by mypy!

@sobolevn
Copy link
Member Author

sobolevn commented Aug 9, 2022

@AlexWaygood any specific case that you have in mind?

@AlexWaygood
Copy link
Member

@AlexWaygood any specific case that you have in mind?

The ones you added look good!

@AlexWaygood
Copy link
Member

AlexWaygood commented Aug 9, 2022

It seems like this would be very disruptive for typeshed:

New hits from running typeshed's `stubtest_stdlib.py`, with this PR checked out, relative to mypy master
diff --git a/old_hits.txt b/new_hits.txt
index 419ea740..3e52a198 100644
--- a/old_hits.txt
+++ b/new_hits.txt
@@ -1,11 +1,372 @@
+error: argparse.ArgumentParser.__init__ is inconsistent, runtime argument "formatter_class" has a default value of type Type[argparse.HelpFormatter], which is incompatible with stub argument type argparse._FormatterClass
+Stub: at line 131 in file stdlib\argparse.pyi
+def (self: argparse.ArgumentParser, prog: Union[builtins.str, None] =, usage: Union[builtins.str, None] =, description: Union[builtins.str, None] =, epilog: Union[builtins.str, None] =, parents: typing.Sequence[argparse.ArgumentParser] =, formatter_class: argparse._FormatterClass =, prefix_chars: builtins.str =, fromfile_prefix_chars: Union[builtins.str, None] =, argument_default: Any =, conflict_handler: builtins.str =, add_help: builtins.bool =, allow_abbrev: builtins.bool =, exit_on_error: builtins.bool =)
+Runtime: at line 1694 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\argparse.py
+def (self, prog=None, usage=None, description=None, epilog=None, parents=[], formatter_class=<class 'argparse.HelpFormatter'>, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True)
+
+error: asyncio.DefaultEventLoopPolicy._loop_factory variable differs from runtime type Type[asyncio.windows_events.ProactorEventLoop]
+Stub: at line 62 in file stdlib\asyncio\__init__.pyi
+Type[asyncio.windows_events._WindowsSelectorEventLoop]
+Runtime: at line 309 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\asyncio\windows_events.py
+<class 'asyncio.windows_events.ProactorEventLoop'>
+
+error: asyncio.windows_events.DefaultEventLoopPolicy._loop_factory variable differs from runtime type Type[asyncio.windows_events.ProactorEventLoop]
+Stub: at line 62 in file stdlib\asyncio\windows_events.pyi
+Type[asyncio.windows_events._WindowsSelectorEventLoop]
+Runtime: at line 309 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\asyncio\windows_events.py
+<class 'asyncio.windows_events.ProactorEventLoop'>
+
+error: ctypes.CDLL._func_restype_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 21 in file stdlib\ctypes\__init__.pyi
+ctypes._CData
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.LPBOOL._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.LPBYTE._type_ variable differs from runtime type Type[ctypes.c_byte]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 228 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_byte'>
+
+error: ctypes.wintypes.LPCOLORREF._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.LPDWORD._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.LPFILETIME._type_ variable differs from runtime type Type[ctypes.wintypes.FILETIME]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 128 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.FILETIME'>
+
+error: ctypes.wintypes.LPHANDLE._type_ variable differs from runtime type Type[ctypes.c_void_p]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 244 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_void_p'>
+
+error: ctypes.wintypes.LPHKL._type_ variable differs from runtime type Type[ctypes.c_void_p]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 244 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_void_p'>
+
+error: ctypes.wintypes.LPINT._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.LPLONG._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.LPMSG._type_ variable differs from runtime type Type[ctypes.wintypes.MSG]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 133 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.MSG'>
+
+error: ctypes.wintypes.LPPOINT._type_ variable differs from runtime type Type[ctypes.wintypes.POINT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 115 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.POINT'>
+
+error: ctypes.wintypes.LPRECT._type_ variable differs from runtime type Type[ctypes.wintypes.RECT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 97 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.RECT'>
+
+error: ctypes.wintypes.LPRECTL._type_ variable differs from runtime type Type[ctypes.wintypes.RECT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 97 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.RECT'>
+
+error: ctypes.wintypes.LPSC_HANDLE._type_ variable differs from runtime type Type[ctypes.c_void_p]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 244 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_void_p'>
+
+error: ctypes.wintypes.LPSIZE._type_ variable differs from runtime type Type[ctypes.wintypes.SIZE]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 120 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.SIZE'>
+
+error: ctypes.wintypes.LPSIZEL._type_ variable differs from runtime type Type[ctypes.wintypes.SIZE]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 120 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.SIZE'>
+
+error: ctypes.wintypes.LPUINT._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.LPWIN32_FIND_DATAA._type_ variable differs from runtime type Type[ctypes.wintypes.WIN32_FIND_DATAA]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 143 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.WIN32_FIND_DATAA'>
+
+error: ctypes.wintypes.LPWIN32_FIND_DATAW._type_ variable differs from runtime type Type[ctypes.wintypes.WIN32_FIND_DATAW]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 155 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.WIN32_FIND_DATAW'>
+
+error: ctypes.wintypes.LPWORD._type_ variable differs from runtime type Type[ctypes.c_ushort]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 167 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ushort'>
+
+error: ctypes.wintypes.PBOOL._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.PBOOLEAN._type_ variable differs from runtime type Type[ctypes.c_byte]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 228 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_byte'>
+
+error: ctypes.wintypes.PBYTE._type_ variable differs from runtime type Type[ctypes.c_byte]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 228 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_byte'>
+
+error: ctypes.wintypes.PCHAR._type_ variable differs from runtime type Type[ctypes.c_char]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 233 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_char'>
+
+error: ctypes.wintypes.PDWORD._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.PFILETIME._type_ variable differs from runtime type Type[ctypes.wintypes.FILETIME]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 128 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.FILETIME'>
+
+error: ctypes.wintypes.PFLOAT._type_ variable differs from runtime type Type[ctypes.c_float]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 192 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_float'>
+
+error: ctypes.wintypes.PHANDLE._type_ variable differs from runtime type Type[ctypes.c_void_p]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 244 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_void_p'>
+
+error: ctypes.wintypes.PHKEY._type_ variable differs from runtime type Type[ctypes.c_void_p]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 244 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_void_p'>
+
+error: ctypes.wintypes.PINT._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.PLARGE_INTEGER._type_ variable differs from runtime type Type[ctypes.c_longlong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 210 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_longlong'>
+
+error: ctypes.wintypes.PLCID._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.PLONG._type_ variable differs from runtime type Type[ctypes.c_long]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 171 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_long'>
+
+error: ctypes.wintypes.PMSG._type_ variable differs from runtime type Type[ctypes.wintypes.MSG]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 133 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.MSG'>
+
+error: ctypes.wintypes.PPOINT._type_ variable differs from runtime type Type[ctypes.wintypes.POINT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 115 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.POINT'>
+
+error: ctypes.wintypes.PPOINTL._type_ variable differs from runtime type Type[ctypes.wintypes.POINT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 115 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.POINT'>
+
+error: ctypes.wintypes.PRECT._type_ variable differs from runtime type Type[ctypes.wintypes.RECT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 97 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.RECT'>
+
+error: ctypes.wintypes.PRECTL._type_ variable differs from runtime type Type[ctypes.wintypes.RECT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 97 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.RECT'>
+
+error: ctypes.wintypes.PSHORT._type_ variable differs from runtime type Type[ctypes.c_short]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 163 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_short'>
+
+error: ctypes.wintypes.PSIZE._type_ variable differs from runtime type Type[ctypes.wintypes.SIZE]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 120 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.SIZE'>
+
+error: ctypes.wintypes.PSIZEL._type_ variable differs from runtime type Type[ctypes.wintypes.SIZE]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 120 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.SIZE'>
+
+error: ctypes.wintypes.PSMALL_RECT._type_ variable differs from runtime type Type[ctypes.wintypes._SMALL_RECT]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 104 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes._SMALL_RECT'>
+
+error: ctypes.wintypes.PUINT._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.PULARGE_INTEGER._type_ variable differs from runtime type Type[ctypes.c_ulonglong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 214 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulonglong'>
+
+error: ctypes.wintypes.PULONG._type_ variable differs from runtime type Type[ctypes.c_ulong]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 175 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ulong'>
+
+error: ctypes.wintypes.PUSHORT._type_ variable differs from runtime type Type[ctypes.c_ushort]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 167 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ushort'>
+
+error: ctypes.wintypes.PWCHAR._type_ variable differs from runtime type Type[ctypes.c_wchar]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 259 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_wchar'>
+
+error: ctypes.wintypes.PWIN32_FIND_DATAA._type_ variable differs from runtime type Type[ctypes.wintypes.WIN32_FIND_DATAA]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 143 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.WIN32_FIND_DATAA'>
+
+error: ctypes.wintypes.PWIN32_FIND_DATAW._type_ variable differs from runtime type Type[ctypes.wintypes.WIN32_FIND_DATAW]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 155 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
+<class 'ctypes.wintypes.WIN32_FIND_DATAW'>
+
+error: ctypes.wintypes.PWORD._type_ variable differs from runtime type Type[ctypes.c_ushort]
+Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
+Type[_CT`1]
+Runtime: at line 167 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\__init__.py
+<class 'ctypes.c_ushort'>
+
+error: dataclasses.asdict is inconsistent, runtime argument "dict_factory" has a default value of type Type[builtins.dict[Any, Any]], which is incompatible with stub argument type def (builtins.list[Tuple[builtins.str, Any]]) -> _T`-1. This is often caused by overloads failing to account for explicitly passing in the default value.
+Stub: at line 46 in file stdlib\dataclasses.pyi
+Overload(def (obj: Any) -> builtins.dict[builtins.str, Any], def [_T] (obj: Any, *, dict_factory: def (builtins.list[Tuple[builtins.str, Any]]) -> _T`-1) -> _T`-1)
+Inferred signature: def (obj: Any, *, dict_factory: def (builtins.list[Tuple[builtins.str, Any]]) -> _T`-1 = ...)
+Runtime: at line 1218 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\dataclasses.py
+def (obj, *, dict_factory=<class 'dict'>)
+
+error: dataclasses.astuple is inconsistent, runtime argument "tuple_factory" has a default value of type Type[builtins.tuple[Any, ...]], which is incompatible with stub argument type def (builtins.list[Any]) -> _T`-1. This is often caused by overloads failing to account for explicitly passing in the default value.
+Stub: at line 50 in file stdlib\dataclasses.pyi
+Overload(def (obj: Any) -> builtins.tuple[Any, ...], def [_T] (obj: Any, *, tuple_factory: def (builtins.list[Any]) -> _T`-1) -> _T`-1)
+Inferred signature: def (obj: Any, *, tuple_factory: def (builtins.list[Any]) -> _T`-1 = ...)
+Runtime: at line 1283 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\dataclasses.py
+def (obj, *, tuple_factory=<class 'tuple'>)
+
+error: dbm.error variable differs from runtime type Tuple[Tuple[Type[dbm._error], Type[builtins.OSError]], Type[builtins.OSError]]
+Stub: at line 92 in file stdlib\dbm\__init__.pyi
+Tuple[Type[dbm._error], Type[builtins.OSError]]
+Runtime:
+(<class 'dbm.error'>, <class 'OSError'>)
+
+error: email.headerregistry.HeaderRegistry.__init__ is inconsistent, runtime argument "default_class" has a default value of type Type[email.headerregistry.UnstructuredHeader], which is incompatible with stub argument type Type[email.headerregistry.BaseHeader]
+Stub: at line 145 in file stdlib\email\headerregistry.pyi
+def (self: email.headerregistry.HeaderRegistry, base_class: Type[email.headerregistry.BaseHeader] =, default_class: Type[email.headerregistry.BaseHeader] =, use_default_map: builtins.bool =)
+Runtime: at line 566 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\email\headerregistry.py
+def (self, base_class=<class 'email.headerregistry.BaseHeader'>, default_class=<class 'email.headerregistry.UnstructuredHeader'>, use_default_map=True)
+
 error: locale names exported from the stub do not correspond to the names exported at runtime. This is probably due to an inaccurate `__all__` in the stub or things being missing from the stub.
 Stub: in file stdlib\locale.pyi
 Names exported in the stub but not at runtime: ['LC_MESSAGES']
 Runtime:
 Names exported at runtime but not in the stub: []
 
+error: wsgiref.simple_server.make_server is inconsistent, runtime argument "server_class" has a default value of type Type[wsgiref.simple_server.WSGIServer], which is incompatible with stub argument type Type[_S`-1]. This is often caused by overloads failing to account for explicitly passing in the default value.
+Stub: at line 34 in file stdlib\wsgiref\simple_server.pyi
+Overload(def (host: builtins.str, port: builtins.int, app: def (builtins.dict[builtins.str, Any], _typeshed.wsgi.StartResponse) -> typing.Iterable[builtins.bytes], *, handler_class: Type[wsgiref.simple_server.WSGIRequestHandler] =) -> wsgiref.simple_server.WSGIServer, def [_S <: wsgiref.simple_server.WSGIServer] (host: builtins.str, port: builtins.int, app: def (builtins.dict[builtins.str, Any], _typeshed.wsgi.StartResponse) -> typing.Iterable[builtins.bytes], server_class: Type[_S`-1], handler_class: Type[wsgiref.simple_server.WSGIRequestHandler] =) -> _S`-1)
+Inferred signature: def (host: builtins.str, port: builtins.int, app: def (builtins.dict[builtins.str, Any], _typeshed.wsgi.StartResponse) -> typing.Iterable[builtins.bytes], server_class: Type[_S`-1] = ..., handler_class: Type[wsgiref.simple_server.WSGIRequestHandler] = ...)
+Runtime: at line 150 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\wsgiref\simple_server.py
+def (host, port, app, server_class=<class 'wsgiref.simple_server.WSGIServer'>, handler_class=<class 'wsgiref.simple_server.WSGIRequestHandler'>)
+
 note: unused allowlist entry sqlite3.dbapi2.Binary.__contains__
 note: unused allowlist entry sqlite3.Binary.__contains__
+note: unused allowlist entry http.client.HTTPConnection.response_class
+note: unused allowlist entry inspect.Parameter.empty
+note: unused allowlist entry inspect.Signature.empty
+note: unused allowlist entry multiprocessing.reduction.AbstractReducer.ForkingPickler
 note: unused allowlist entry enum.Enum.name
 note: unused allowlist entry enum.Enum.value
 note: unused allowlist entry enum.Flag.name
@@ -18,6 +379,7 @@ note: unused allowlist entry dbm.dumb.error.characters_written
 note: unused allowlist entry os.error.characters_written
 note: unused allowlist entry select.error.characters_written
 note: unused allowlist entry socket.error.characters_written
+note: unused allowlist entry _collections_abc.Callable
 note: unused allowlist entry importlib.metadata._meta.SimplePath.__div__
 note: unused allowlist entry importlib.abc.Traversable.__init__
 note: unused allowlist entry importlib.metadata.PackageMetadata.__init__
@@ -30,6 +392,7 @@ note: unused allowlist entry typing.SupportsFloat.__init__
 note: unused allowlist entry typing.SupportsIndex.__init__
 note: unused allowlist entry typing.SupportsInt.__init__
 note: unused allowlist entry typing.SupportsRound.__init__
+note: unused allowlist entry multiprocessing.reduction.AbstractReducer.DupHandle
 note: unused allowlist entry builtins.WindowsError.characters_written
 note: unused allowlist entry winreg.error.characters_written
-Found 29 errors (checked 481 modules)
+Found 94 errors (checked 481 modules)

If these are all true positives, we should fix them over at typeshed before merging this PR.

@AlexWaygood
Copy link
Member

AlexWaygood commented Aug 9, 2022

Another test that it might be useful to add:

diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py
index d6b7affb7..3a5bef614 100644
--- a/mypy/test/teststubtest.py
+++ b/mypy/test/teststubtest.py
@@ -885,6 +885,33 @@ class StubtestUnit(unittest.TestCase):
             error="B2.a",
         )

+    @collect_cases
+    def test_generic_classvar(self) -> Iterator[Case]:
+        yield Case(
+            stub="""
+            from typing import Generic, TypeVar
+            _T = TypeVar("_T")
+            class Meta(type): ...
+            class Foo(Generic[_T], metaclass=Meta): ...
+            """,
+            runtime="""
+            class Meta(type): ...
+            class Foo(metaclass=Meta): ...
+            """,
+            error=None,
+        )
+        yield Case(
+            stub="""
+            class A:
+                x: type[Foo[int]]
+            """,
+            runtime="""
+            class A:
+                x = Foo
+            """,
+            error=None,
+        )
+
     @collect_cases
     def test_type_alias(self) -> Iterator[Case]:
         yield Case(

Comment on lines 1389 to +1391
else:
if isinstance(runtime, type):
return mypy.types.TypeType(fallback)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
else:
if isinstance(runtime, type):
return mypy.types.TypeType(fallback)
elif isinstance(runtime, type):
return mypy.types.TypeType(fallback)
else:

Copy link
Member Author

Choose a reason for hiding this comment

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

I decided to use nested if because all other elif cases work with literal values. I didn't want to created mixed concepts here.

And since we only work with fallback under else - I kept it that way.

Copy link
Member

@AlexWaygood AlexWaygood Aug 9, 2022

Choose a reason for hiding this comment

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

I see -- maybe we should move this block to just below the if isinstance(runtime, tuple) block on lines 1373-1378, in that case? That seems like a more logical place for it to be, and it would mean we could have it as an isolated block of code instead of next to all the literal-value stuff.

Co-authored-by: Alex Waygood <[email protected]>
@sobolevn
Copy link
Member Author

sobolevn commented Aug 9, 2022

I am thinking about possible solutions 🤔
Typeshed output has many false-positives.
I will first concentrate on reproducing them with tests, then fixing problems.
By the way, thank you for the extra test sample!

else:
runtime_type = type(runtime) # Or an instance

stub = get_stub(runtime_type.__module__)
Copy link
Member

Choose a reason for hiding this comment

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

It might be worth being a bit more defensive here as well. What if it's a class that doesn't have a __module__ attribute, or that has a __module__ attribute set to something that isn't a str? (The problem predates this PR, but we may as well fix it while we're here.)

@sobolevn
Copy link
Member Author

My thoughts:

  1. Type vs Protocol
error: argparse.ArgumentParser.__init__ is inconsistent, runtime argument "formatter_class" has a default value of type Type[argparse.HelpFormatter], which is incompatible with stub argument type argparse._FormatterClass
Stub: at line 131 in file stdlib\argparse.pyi

This happens because _FormatterClass is a protocol:

Looks like right now TypeType has problems matching a protocol 🤔

  1. There are multiple errors where TypeVar is used, like:
error: ctypes.wintypes.PWIN32_FIND_DATAW._type_ variable differs from runtime type Type[ctypes.wintypes.WIN32_FIND_DATAW]
Stub: at line 162 in file stdlib\ctypes\wintypes.pyi
Type[_CT`1]
Runtime: at line 155 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\ctypes\wintypes.py
<class 'ctypes.wintypes.WIN32_FIND_DATAW'>
  1. There are cases that look real, for example:
error: email.headerregistry.HeaderRegistry.__init__ is inconsistent, runtime argument "default_class" has a default value of type Type[email.headerregistry.UnstructuredHeader], which is incompatible with stub argument type Type[email.headerregistry.BaseHeader]
Stub: at line 145 in file stdlib\email\headerregistry.pyi
def (self: email.headerregistry.HeaderRegistry, base_class: Type[email.headerregistry.BaseHeader] =, default_class: Type[email.headerregistry.BaseHeader] =, use_default_map: builtins.bool =)
Runtime: at line 566 in file C:\Users\alexw\AppData\Local\Programs\Python\Python310\lib\email\headerregistry.py
def (self, base_class=<class 'email.headerregistry.BaseHeader'>, default_class=<class 'email.headerregistry.UnstructuredHeader'>, use_default_map=True)

Note that UnstructuredHeader is not a subclass of BaseHeader.

One more:

error: dbm.error variable differs from runtime type Tuple[Tuple[Type[dbm._error], Type[builtins.OSError]], Type[builtins.OSError]]
Stub: at line 92 in file stdlib\dbm\__init__.pyi
Tuple[Type[dbm._error], Type[builtins.OSError]]
Runtime:
+(<class 'dbm.error'>, <class 'OSError'>)

The problem here is:

Notice _error and error class names (because name erorr is later re-defined), I think that this is a good allowlist candidate.

I will collect all real errors and send a PR to typeshed. There are too many cases to process them fastly!

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.

stubtest: False-positive errors for type[T] attributes with non-type metaclasses
2 participants