gh-151769: Make IPv6Address ordering scope_id-aware#151772
Open
Builder106 wants to merge 1 commit into
Open
Conversation
IPv6Address.__eq__ and __hash__ fold in the interface scope_id, but IPv6Address inherited the scope-blind _BaseAddress.__lt__. Under @functools.total_ordering, which derives > from < and ==, that made ordering inconsistent for addresses differing only by scope: both a > b and b > a could be true, so antisymmetry broke and sorted(), min() and max() were non-deterministic. Add a scope-aware IPv6Address.__lt__ that tie-breaks on scope_id only when the integer address is equal, so unscoped sorts before scoped. Overriding only __lt__ routes all four total_ordering comparisons through the scope-aware path, which also fixes scoped IPv6Interface and IPv6Network ordering since they delegate to address comparison. _BaseAddress.__lt__ is untouched, so IPv4 is unaffected.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
IPv6Address.__eq__and__hash__fold in the interfacescope_id, butIPv6Addressinherited the scope-blind_BaseAddress.__lt__. Under@functools.total_ordering— which derives>from<and==— that made ordering inconsistent for addresses differing only by scope: botha > bandb > acould be true, so antisymmetry broke andsorted()/min()/max()were non-deterministic for scoped addresses.This adds a scope-aware
IPv6Address.__lt__that tie-breaks onscope_idonly when the integer address is equal (unscoped sorts before scoped; scope ids compare lexicographically). Because the derived operators dispatch throughtype(self).__lt__, overriding only__lt__routes all four comparisons through the scope-aware path — which also repairs scopedIPv6InterfaceandIPv6Networkordering, since they delegate to address comparison._BaseAddress.__lt__is left untouched, soIPv4Addressis unaffected.Verified on a
3.16.0a0build and on stock3.14.6: without the fix, antisymmetry fails and the three scoped permutations of one address yield 6 distinct sort orders; with it, ordering is total and deterministic. The newtestScopedAddressComparisoncovers trichotomy, antisymmetry, and stablesorted()/min()/max()for scopedIPv6Address,IPv6Interface, andIPv6Network, with an IPv4 ordering guard.