@@ -1471,7 +1471,7 @@ def accept(self, visitor: TypeVisitor[T]) -> T:
14711471
14721472 def __hash__ (self ) -> int :
14731473 if self ._hash == - 1 :
1474- self ._hash = hash ((self .type , self .args , self .last_known_value , self . extra_attrs ))
1474+ self ._hash = hash ((self .type , self .args , self .last_known_value ))
14751475 return self ._hash
14761476
14771477 def __eq__ (self , other : object ) -> bool :
@@ -2895,6 +2895,7 @@ class UnionType(ProperType):
28952895
28962896 __slots__ = (
28972897 "items" ,
2898+ "_frozen_items" ,
28982899 "is_evaluated" ,
28992900 "uses_pep604_syntax" ,
29002901 "original_str_expr" ,
@@ -2914,6 +2915,7 @@ def __init__(
29142915 # We must keep this false to avoid crashes during semantic analysis.
29152916 # TODO: maybe switch this to True during type-checking pass?
29162917 self .items = flatten_nested_unions (items , handle_type_alias_type = False )
2918+ self ._frozen_items = frozenset (self .items )
29172919 # is_evaluated should be set to false for type comments and string literals
29182920 self .is_evaluated = is_evaluated
29192921 # uses_pep604_syntax is True if Union uses OR syntax (X | Y)
@@ -2931,14 +2933,14 @@ def can_be_false_default(self) -> bool:
29312933 return any (item .can_be_false for item in self .items )
29322934
29332935 def __hash__ (self ) -> int :
2934- return hash (frozenset ( self .items ) )
2936+ return hash (self ._frozen_items )
29352937
29362938 def __eq__ (self , other : object ) -> bool :
29372939 if not isinstance (other , UnionType ):
29382940 return NotImplemented
29392941 if self is other :
29402942 return True
2941- return frozenset ( self .items ) == frozenset ( other .items )
2943+ return self ._frozen_items == other ._frozen_items
29422944
29432945 @overload
29442946 @staticmethod
0 commit comments