Wie kann ich MyPy dazu bringen, mit Subklasser von Enumtype/Enummeta korrekt umzugehen?
Posted: 13 Feb 2025, 23:16
Haftungsausschluss: Beziehen Normalerweise, was zu tun ist): < /p>
In der ersten Bestellung sagen Sie "fein". Wenn ich die CLS fallen lasse: Typ [_e] portionstyp-Hindern, MyPy wird verwirrter: < /p>
hat wirklich einige Fehler:
[*] Warum wird Enumtype .__ getItem __ als beide zurückgegeben. Dies scheint ein seltsamer interner Konflikt mit MyPy zu sein. Typevar wird konsequent von MyPy bewertet, aber auch, damit der Anruf bei Super () .__ getItem __ [oder zu enumtype .__ getItem __ ] ist korrekt? < Br /> < /ol>
Code: Select all
import sys
from enum import Enum, IntEnum
from typing import Any, Type, TypeVar, Union, Callable, cast, TYPE_CHECKING
if sys.version_info >= (3, 11):
from enum import EnumType
else:
from enum import EnumMeta as EnumType
_E = TypeVar("_E", bound=Enum)
class MultipleEnumAccessMeta(EnumType):
"""
Enum Metaclass to provide a way to access multiple values all at once.
"""
def __getitem__(cls: Type[_E], key: Union[str, tuple[str, ...]]) -> Union[_E, list[_E]]:
getitem = cast(Callable[[Type[_E], str], _E], EnumType.__getitem__) # Ensure correct typing for __getitem__
if isinstance(key, tuple):
return [getitem(cls, name) for name in key] # Return list for tuple keys
return getitem(cls, key) # Return single value for single key
if TYPE_CHECKING:
reveal_type(EnumType.__getitem__) # Base method signature
reveal_type(MultipleEnumAccessMeta.__getitem__) # Overridden method signature
# Test Enum with metaclass
class Names(IntEnum, metaclass=MultipleEnumAccessMeta):
Alice = 0
Bob = 1
Charlie = 2
# Test cases
assert Names["Alice"] == Names.Alice
assert Names["Alice", "Bob"] == [Names.Alice, Names.Bob]
< /code>
Dies ergibt jedoch die folgenden Typen -Beschwerden < /p>
test.py:17: error: Self argument missing for a non-static method (or an invalid type for self) [misc]
test.py:17: error: Return type "list[Never]" of "__getitem__" incompatible with return type "Never" in supertype "EnumMeta" [override]
test.py:25: note: Revealed type is "def [_EnumMemberT] (type[_EnumMemberT`3], builtins.str) -> _EnumMemberT`3"
test.py:26: note: Revealed type is "def [_E Union[_E`4, builtins.list[_E`4]]"
test.py:36: error: Enum index should be a string (actual index type "tuple[str, str]") [misc]
test.py:36: error: Non-overlapping equality check (left operand type: "Names", right operand type: "list[Names]") [comparison-overlap]
Code: Select all
test.py:17: error: Return type "Union[_E, list[_E]]" of "__getitem__" incompatible with return type "Never" in supertype "EnumMeta" [override]
test.py:21: error: Argument 1 has incompatible type "MultipleEnumAccessMeta"; expected "type[_E]" [arg-type]
test.py:22: error: Argument 1 has incompatible type "MultipleEnumAccessMeta"; expected "type[_E]" [arg-type]
test.py:25: note: Revealed type is "def [_EnumMemberT] (type[_EnumMemberT`3], builtins.str) -> _EnumMemberT`3"
test.py:26: note: Revealed type is "def [_E Union[_E`4, builtins.list[_E`4]]"
test.py:36: error: Enum index should be a string (actual index type "tuple[str, str]") [misc]
test.py:36: error: Non-overlapping equality check (left operand type: "Names", right operand type: "list[Names]") [comparison-overlap]
< /code>
Ich habe Fragen. Wahrscheinlich ist dies teilweise auf die Metaklasse zurückzuführen, die sehr schwierig ist, und ich tue mein Bestes, um hier vorsichtig zu sein, aber ich bin anscheinend entweder nicht vorsichtig genug oder MyPy
[*] Warum wird Enumtype .__ getItem __ als beide zurückgegeben. Dies scheint ein seltsamer interner Konflikt mit MyPy zu sein. Typevar wird konsequent von MyPy bewertet, aber auch, damit der Anruf bei Super () .__ getItem __ [oder zu enumtype .__ getItem __ ] ist korrekt? < Br /> < /ol>