Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3242,7 +3242,6 @@ def __init__(
super().__init__(line, column)
self.value = value
self.fallback = fallback
self._hash = -1 # Cached hash value

# NOTE: Enum types are always truthy by default, but this can be changed
# in subclasses, so we need to get the truthyness from the Enum
Expand Down Expand Up @@ -3272,13 +3271,11 @@ def accept(self, visitor: TypeVisitor[T]) -> T:
return visitor.visit_literal_type(self)

def __hash__(self) -> int:
if self._hash == -1:
self._hash = hash((self.value, self.fallback))
return self._hash
return hash(self.value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this part actually safe? This will make Literal["foo"] and Literal[b"foo"] have same hash (I don't remember why, but we always store the literal bytes value as a string).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also Literal[0] vs Literal[False], both 0 and False hash to zero IIRC

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine for hashes to collide and doesn't affect correctness. You just don't want too many values to collide because then some of your constant time operations become linear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only correctness requirement is that values that compare equal have the same hash


def __eq__(self, other: object) -> bool:
if isinstance(other, LiteralType):
return self.fallback == other.fallback and self.value == other.value
return self.value == other.value and self.fallback == other.fallback
else:
return NotImplemented

Expand Down