-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] handle more enum.auto()
cases
#20541
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
base: main
Are you sure you want to change the base?
Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
7208cf6
to
87548a3
Compare
184c132
to
eb5cf24
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
} else if Type::ClassLiteral(class) | ||
.is_subtype_of(db, KnownClass::Str.to_subclass_of(db)) | ||
{ | ||
KnownClass::Str.to_instance(db) | ||
} else if Type::ClassLiteral(class) | ||
.is_subtype_of(db, KnownClass::Bytes.to_subclass_of(db)) | ||
{ | ||
KnownClass::Bytes.to_instance(db) | ||
} else if Type::ClassLiteral(class) | ||
.is_subtype_of(db, KnownClass::Float.to_subclass_of(db)) | ||
{ | ||
KnownClass::Float.to_instance(db) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I'm not sure we should be adding more special cases here. An enum class that uses bytes
as a mixin isn't conceptually any different from an enum that uses tuple
or list
or dict
as a mixin, or a custom dataclass or custom NamedTuple
as a mixin. Why should we treat bytes
and float
specially here?
Rather than adding more special cases, I think we should have a generalised fallback logic that iterates through the MRO of the enum class to check whether it has a custom mixin that isn't str
or int
. (Those two make sense to special-case, I think, because of the presence of StrEnum
and IntEnum
in the stdlib. You can determine whether an element in the MRO is a "custom mixin" class by checking if it isn't object
and isn't a subclass of enum.Enum
-- if both those conditions hold, I think we can treat it as a mixin class.) If the enum class has a custom mixin and auto()
is used to define the value of an enum member, we should probably infer the .value
of that enum member as just being Any
, which would still be more accurate than what we have on main
(even if it isn't very precise!). It seems pretty hard to predict whether the .value
property is going to give you an instance of the mixin or an integer:
>>> class Foo: ...
>>> import enum
>>> class FooEnum(Foo, enum.Enum):
... X = enum.auto()
...
>>> FooEnum.X.value
1
>>> class BEnum(bytes, enum.Enum):
... X = enum.auto()
...
>>> BEnum.X.value
b'\x00'
>>> class TEnum(tuple, enum.Enum):
... X = enum.auto()
...
>>> TEnum.X.value
(1,)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes a lot more sense - thanks - didn't feel great about the explicit special cases after going down that road...
eb5cf24
to
fc0bd30
Compare
Summary
see astral-sh/ty#1241
.value
on single member enumsstr
,bytes
,float
asEnum
mixinstuple
as anEnum
mixini'm not sure this is the best implementation for
auto
for these mixin types - at runtime it looks like the counter gets coerced somehow into the mixin type (ieauto() -> (1,)
fortuple
mixins). could probably handle this in a more generic way but this seems like a decent step for nowTest Plan
new mdtests