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
Trying to type-check generic types of a bound enum.Enum (with a custom metaclass) only catches type errors when the actual code fails to run; but doesn't detect the issues when the code runs.
To Reproduce
The code in this gist properly detects the type error while calling Carrier(Foo, Bar.item1):
Traceback (most recent call last):
File "/home/manu/src/tmp/enums.py", line 14, in <module>
class Foo(enum.Enum, MyEnum):
File "/usr/lib/python3.10/enum.py", line 173, in __prepare__
member_type, first_enum = metacls._get_mixins_(cls, bases)
File "/usr/lib/python3.10/enum.py", line 619, in _get_mixins_
raise TypeError("new enumerations should be created as "
TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`
In order for the code to run we have to swap the positions of enum.Enum and MyEnum in both Foo and Bar (see the second gist); but then mypy fails to catch the type-error.
Your Environment
Mypy version used: master and 0.931
Mypy command-line flags: none
Mypy configuration options from mypy.ini (and other config files): none
Python version used: 3.9
Operating system and version: Linux pavla 5.15.12-1-MANJARO #1 SMP PREEMPT Wed Dec 29 18:08:07 UTC 2021 x86_64 GNU/Linux
I don't think the sample above (or the one in your gist) should generate a type error. There's a valid solution for TypeVar M for both Carrier calls at the bottom of the sample. In the first of the two calls, the M is Foo. In the second M is Foo | Bar or object.
If you want the second call to Carrier to produce an error, you would need to define M as a constrained TypeVar rather than a bound TypeVar.
That's probably correct. My first intuition was to look for something like Instance[T] (for some T bounded to a meta-class). This is the (pseudo) code I was asking about in the gitter thread:
Yeah, there's no such thing as Instance in the type system today. (It's generally not needed because you can specify Type[M] to specify that you're talking about the instantiable class rather than an instance of that class.) And as you probably know, bound works only parent/child class relationships, not with metaclasses.
Does my suggestion to use a constrained TypeVar meet your needs?
Bug Report
Trying to type-check generic types of a bound
enum.Enum
(with a custom metaclass) only catches type errors when the actual code fails to run; but doesn't detect the issues when the code runs.To Reproduce
The code in this gist properly detects the type error while calling
Carrier(Foo, Bar.item1)
:However that code fails to run with
In order for the code to run we have to swap the positions of
enum.Enum
andMyEnum
in bothFoo
andBar
(see the second gist); but then mypy fails to catch the type-error.Your Environment
mypy.ini
(and other config files): noneLinux pavla 5.15.12-1-MANJARO #1 SMP PREEMPT Wed Dec 29 18:08:07 UTC 2021 x86_64 GNU/Linux
Previous discussion in gitter: https://gitter.im/python/typing?at=61dab43cf5a3947800f73b71
The text was updated successfully, but these errors were encountered: