Skip to content

Conversation

@johnslavik
Copy link
Member

@johnslavik johnslavik commented Jan 14, 2026

Cells are mutable and, in regular comparison, they are equal when their contents are equal (or if both are empty).

Two different cells should not be considered equal by value in forward references, though.
If there are two separate cells, they either (1) target different variables or (2) belong to different scopes, so two separate forward references storing two separate cells are conceptually unequal even if these cells happen to be equal at a given point in time. Mutability, essentially.

I'm still working on tests.

@leycec

This comment was marked as resolved.

@johnslavik
Copy link
Member Author

johnslavik commented Jan 15, 2026

Thank you for your interest in this! I encourage you to open a new issue if you think like the performance of ForwardRef.__hash__ can and should be improved. I'm afraid it is out of scope of this surgical PR -- I will not be addressing anything outside the topic of cell comparison.


Regarding why I solved it this way -- I just went with what the original intent was but with a corrected assumption about the hashability of cells.

An alternative approach to hashing a sorted tuple of names -> cell ids is to simply return an identity of __cell__. It can make sense because assuming cell dicts change additively -- so if a forwardref has the same hash because of the same forward arg and the same cell dict, then even if the cell dict changed over time, it possibly only added new keys, so evaluating the ref wouldn't produce different results. I also assume two different dict objects with same cell ids to be rather rare.

cc @JelleZijlstra

and self.__forward_is_class__ == other.__forward_is_class__
and self.__cell__ == other.__cell__
# Two separate cells are always considered unequal in forward refs.
and self.__cell__ is other.__cell__
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't match the __hash__ since there we has the dictionary contents. So two different dicts with the same contents would hash equal, but not compare equal.

@JelleZijlstra
Copy link
Member

If the performance of some part of the typing stack is a problem for you, please open a concise issue with concrete examples of what you would like to change. (Digressions on the beauty of the wilds of Canada are not necessary.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs backport to 3.14 bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants