python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.45k stars 2.82k forks source link

False positive error when subclassing `List` type #15040

Open thepabloaguilar opened 1 year ago

thepabloaguilar commented 1 year ago

Bug Report

This bug is experienced in classes lib

To Reproduce

from typing import List

class ListOfStrMeta(type):
    def __instancecheck__(cls, other) -> bool:
        return (
            isinstance(other, list) and
            bool(other) and
            all(isinstance(list_item, str) for list_item in other)
        )

class ListOfStr(List[str], metaclass=ListOfStrMeta):
    ...

Expected Behavior

No errors should appear

Actual Behavior

Error from the code above:

poetry run mypy ex.py
ex.py:13: error: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases  [misc]
Found 1 error in 1 file (checked 1 source file)

Your Environment

disable_error_code = empty-body

allow_redefinition = false check_untyped_defs = true disallow_any_explicit = true

disallow_any_generics = true

disallow_untyped_calls = true ignore_errors = false ignore_missing_imports = true implicit_reexport = false local_partial_types = true strict_optional = true strict_equality = true no_implicit_optional = true warn_no_return = true warn_unused_ignores = true warn_redundant_casts = true warn_unused_configs = true warn_unreachable = true


- Python version used: 3.10.10

cc @sobolevn 
ikonst commented 1 year ago

This is probably due to #6042: https://github.com/python/mypy/blob/0f09be472cad7aa06ca4af9dd73aca6b87450d84/mypy/semanal.py#L2363-L2372 Can take a look @ilevkivskyi?

Since list derives from a handful of protocols (e.g. Sequence), its metaclass is ABCMeta.

Changing

-class ListOfStrMeta(typing):
+class ListOfStrMeta(ABCMeta):

eliminates the error, though it's probably wrong since type(list) is type.

sobolevn commented 1 year ago

Yes, this is due to the fact that typeshed has Sequence in the base classes of list. While runtime does not have it.