Skip to content

Use realpath in PackageDescriptor.__hash__ (#478) - #752

Open
paneendrakumar0 wants to merge 1 commit into
colcon:masterfrom
paneendrakumar0:fix-descriptor-hash-478
Open

paneendrakumar0 wants to merge 1 commit into
colcon:masterfrom
paneendrakumar0:fix-descriptor-hash-478

Conversation

@paneendrakumar0

@paneendrakumar0 paneendrakumar0 commented Oct 30, 2026 •

Copy link
Copy Markdown

Fixes #478.

Problem

Both the name and type attributes of PackageDescriptor are mutable and may be modified after instantiation (for example, during package identification or augmentation). Because __hash__ previously computed hash((self.type, self.name)), mutating either attribute changes the instance's hash value while it resides in a set or dict, corrupting the hash table buckets and causing subsequent membership checks or removal operations to fail:

desc = PackageDescriptor('foo')
descs = {desc}
desc.name = 'bar'
assert desc in descs  # failed

Solution

  • Compute __hash__ using os.path.realpath(str(self.path)). The package path is set upon construction and does not change during the descriptor's lifetime.
  • This satisfies Python's hash contract: two descriptors that compare equal (__eq__ verifies (self.type, self.name) == (other.type, other.name) and realpath(self) == realpath(other)) will always yield identical hashes.
  • Two descriptors sharing the same path but having different types/names produce identical hashes (hash collision), which Python sets and dicts handle through equality probing.
  • Added test coverage in test_magic_methods verifying that mutations to name or type preserve hash value and set membership, and that descriptors pointing to the same realpath compare equal and hash identically.

Both 'name' and 'type' attributes of PackageDescriptor are mutable and can be modified during package identification or augmentation. Computing __hash__ from mutable attributes causes the hash value to change after an instance has been added to a set or dict, resulting in hash table corruption and membership check failures.

Compute __hash__ using os.path.realpath(str(self.path)), which is immutable over the lifetime of the descriptor and consistent with the realpath equality check in __eq__.

Signed-off-by: paneendrakumar0 <paneendra100@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PackageDescriptor.__hash__ uses mutable values

1 participant