Skip to content

Fix __hash__/__eq__ inconsistency in HConfigChild (#185)#236

Merged
jtdub merged 2 commits intonextfrom
issue-185-fix-hash-eq-inconsistency-next
Mar 23, 2026
Merged

Fix __hash__/__eq__ inconsistency in HConfigChild (#185)#236
jtdub merged 2 commits intonextfrom
issue-185-fix-hash-eq-inconsistency-next

Conversation

@jtdub
Copy link
Contributor

@jtdub jtdub commented Mar 23, 2026

Summary

  • Aligns __hash__ with __eq__ in HConfigChild by removing new_in_config and order_weight (intentionally excluded from __eq__) and adding tags (which __eq__ checks but __hash__ previously omitted)
  • Adds five tests covering each dimension of the inconsistency and its practical impact on set deduplication and dict key lookup

Fixes #185.

Test plan

  • test_child_hash_eq_consistency_new_in_config — equal children with differing new_in_config now have equal hashes
  • test_child_hash_eq_consistency_order_weight — equal children with differing order_weight now have equal hashes
  • test_child_hash_eq_consistency_tags — unequal children (differing tags) now have different hashes
  • test_child_set_deduplication_with_new_in_config — equal children collapse to one entry in a set
  • test_child_dict_key_lookup_with_order_weight — equal children resolve to the same dict key

🤖 Generated with Claude Code

__hash__ included new_in_config and order_weight but __eq__ intentionally
excluded them, violating the Python invariant that a == b implies hash(a) == hash(b).
__eq__ also checked tags but __hash__ did not include them.

Align __hash__ to use the same fields as __eq__: text, tags, and children.

Add five tests covering each dimension of the inconsistency and its practical
impact on set deduplication and dict key lookup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jtdub jtdub force-pushed the issue-185-fix-hash-eq-inconsistency-next branch from 98b22c1 to fbcf558 Compare March 23, 2026 16:23
- test_benchmarks.py: replace append loops with extend (PERF401), add
  @staticmethod to methods that don't use self (PLR6301), suppress
  intentional print calls with noqa: T201
- test_child.py: suppress pylint too-many-lines (C0302)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jtdub jtdub merged commit 6fd5b2e into next Mar 23, 2026
5 checks passed
@jtdub jtdub deleted the issue-185-fix-hash-eq-inconsistency-next branch March 23, 2026 16:32
jtdub added a commit that referenced this pull request Mar 26, 2026
* Fix __hash__/__eq__ inconsistency in HConfigChild (#185)

__hash__ included new_in_config and order_weight but __eq__ intentionally
excluded them, violating the Python invariant that a == b implies hash(a) == hash(b).
__eq__ also checked tags but __hash__ did not include them.

Align __hash__ to use the same fields as __eq__: text, tags, and children.

Add five tests covering each dimension of the inconsistency and its practical
impact on set deduplication and dict key lookup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix pre-existing lint errors in next branch

- test_benchmarks.py: replace append loops with extend (PERF401), add
  @staticmethod to methods that don't use self (PLR6301), suppress
  intentional print calls with noqa: T201
- test_child.py: suppress pylint too-many-lines (C0302)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
jtdub added a commit that referenced this pull request Mar 26, 2026
* Fix __hash__/__eq__ inconsistency in HConfigChild (#185)

__hash__ included new_in_config and order_weight but __eq__ intentionally
excluded them, violating the Python invariant that a == b implies hash(a) == hash(b).
__eq__ also checked tags but __hash__ did not include them.

Align __hash__ to use the same fields as __eq__: text, tags, and children.

Add five tests covering each dimension of the inconsistency and its practical
impact on set deduplication and dict key lookup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix pre-existing lint errors in next branch

- test_benchmarks.py: replace append loops with extend (PERF401), add
  @staticmethod to methods that don't use self (PLR6301), suppress
  intentional print calls with noqa: T201
- test_child.py: suppress pylint too-many-lines (C0302)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
jtdub added a commit that referenced this pull request Mar 26, 2026
* Add CODEOWNERS file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Literal type constraint for cisco_style_text() style parameter (#189) (#240)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Drop v2 migration utilities, rename to load_driver_rules/load_tag_rules, and reorganize tests (#221)

Remove v2-to-v3 platform mapping functions and constants. Rename
load_hconfig_v2_options to load_driver_rules and load_hconfig_v2_tags
to load_tag_rules, preserving dict-based driver extension for Nautobot
Golden Config compatibility.

Reorganize test suite into unit/, integration/, and benchmarks/
directories mirroring the source code structure. Split the 2079-line
test_hier_config.py into focused files by module (test_root.py,
test_child.py, test_children.py). Separate driver remediation scenario
tests into integration/ and unit tests into unit/platforms/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix load_tag_rules: use _collect_match_rules and correct return type

Replace inline match-rule collection with existing _collect_match_rules
helper for consistency. Simplify return type from
tuple[TagRule] | tuple[TagRule, ...] to tuple[TagRule, ...].

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update gha to test against the next branch

* Fix __hash__/__eq__ inconsistency in HConfigChild (#185) (#236)

* Fix __hash__/__eq__ inconsistency in HConfigChild (#185)

__hash__ included new_in_config and order_weight but __eq__ intentionally
excluded them, violating the Python invariant that a == b implies hash(a) == hash(b).
__eq__ also checked tags but __hash__ did not include them.

Align __hash__ to use the same fields as __eq__: text, tags, and children.

Add five tests covering each dimension of the inconsistency and its practical
impact on set deduplication and dict key lookup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix pre-existing lint errors in next branch

- test_benchmarks.py: replace append loops with extend (PERF401), add
  @staticmethod to methods that don't use self (PLR6301), suppress
  intentional print calls with noqa: T201
- test_child.py: suppress pylint too-many-lines (C0302)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* Move Huawei VRP tests to integration test directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Rename inconsistent public APIs (#216)

- tags_add()/tags_remove() → add_tags()/remove_tags()
- cisco_style_text() → indented_text()
- dump_simple() → to_lines()
- config_to_get_to() → remediation()
- depth() method → depth property
- Rename private helpers _config_to_get_to/_left/_right accordingly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add custom exception hierarchy (#219) (#239)

Add HierConfigError as the base exception with DriverNotFoundError,
InvalidConfigError, IncompatibleDriverError, and reparent
DuplicateChildError under it. Replace generic ValueError/TypeError
raises in constructors and workflows with specific exception types.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Literal type constraint for indented_text() style parameter (#189) (#241)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.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.

1 participant