-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Support for singleton types in unions with Enum #7693
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4751,7 +4751,8 @@ def is_singleton_type(typ: Type) -> bool: | |
'is_singleton_type(t)' returns True if and only if the expression 'a is b' is | ||
always true. | ||
|
||
Currently, this returns True when given NoneTypes and enum LiteralTypes. | ||
Currently, this returns True when given NoneTypes, enum LiteralTypes and | ||
enum types with a single value. | ||
|
||
Note that other kinds of LiteralTypes cannot count as singleton types. For | ||
example, suppose we do 'a = 100000 + 1' and 'b = 100001'. It is not guaranteed | ||
|
@@ -4761,7 +4762,8 @@ def is_singleton_type(typ: Type) -> bool: | |
typ = get_proper_type(typ) | ||
# TODO: Also make this return True if the type is a bool LiteralType. | ||
# Also make this return True if the type corresponds to ... (ellipsis) or NotImplemented? | ||
return isinstance(typ, NoneType) or (isinstance(typ, LiteralType) and typ.is_enum_literal()) | ||
return (isinstance(typ, NoneType) or (isinstance(typ, LiteralType) and typ.is_enum_literal()) | ||
or (isinstance(typ, Instance) and typ.type.is_enum and len(typ.type.names) == 1)) | ||
|
||
|
||
def try_expanding_enum_to_union(typ: Type, target_fullname: str) -> ProperType: | ||
|
@@ -4808,17 +4810,20 @@ class Status(Enum): | |
|
||
|
||
def coerce_to_literal(typ: Type) -> ProperType: | ||
"""Recursively converts any Instances that have a last_known_value into the | ||
corresponding LiteralType. | ||
"""Recursively converts any Instances that have a last_known_value or are | ||
instances of enum types with a single value into the corresponding LiteralType. | ||
""" | ||
typ = get_proper_type(typ) | ||
if isinstance(typ, UnionType): | ||
new_items = [coerce_to_literal(item) for item in typ.items] | ||
return make_simplified_union(new_items) | ||
elif isinstance(typ, Instance) and typ.last_known_value: | ||
return typ.last_known_value | ||
else: | ||
return typ | ||
elif isinstance(typ, Instance): | ||
if typ.last_known_value: | ||
return typ.last_known_value | ||
elif typ.type.is_enum and len(typ.type.names) == 1: | ||
key, = typ.type.names | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the I'd try refactoring out the "get all enum values" check on lines ~4794 to ~4798 of this file into a separate helper function and call it here instead of using |
||
return LiteralType(value=key, fallback=typ) | ||
return typ | ||
|
||
|
||
def has_bool_item(typ: ProperType) -> bool: | ||
|
Uh oh!
There was an error while loading. Please reload this page.
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.
See other comment about
typ.type.names
-- the same fix should be done here.