At cassandra/connection.py:313-315 on master, the right-hand tuple is built from self._server_name rather than other._server_name:
@total_ordering
class SniEndPoint(EndPoint):
...
def __lt__(self, other):
return ((self.address, self.port, self._server_name) <
(other.address, other.port, self._server_name))
__eq__ and __hash__ just above it both use other._server_name, so this looks like a copy-paste slip rather than an intended asymmetry.
Consequence. Two SNI endpoints that share a proxy address and port but differ by server name compare as neither less nor greater: the third element of both tuples is the same object, so the comparison falls through to equality on the first two. a < b and b < a are both False for endpoints __eq__ considers different. SniEndPoint carries @total_ordering, so the derived >, <= and >= inherit the same result, and sorted() over a list of such endpoints is not well defined — the order depends on where Timsort happens to place each item.
This is the normal shape for an SNI deployment: one proxy address and port, many server names.
Repro
from cassandra.connection import SniEndPoint
a = SniEndPoint("proxy.example", "node-a", 9042)
b = SniEndPoint("proxy.example", "node-b", 9042)
assert a != b
print(a < b, b < a, a >= b, b >= a) # False False True True
Fix. other._server_name in the right-hand tuple.
Not introduced by any open PR; it dates to 9b145cf9 (Add SNIEndPoint support). Noticed while reviewing #789, which adds _default_tls_session_cache_key to the same class but does not touch this method.
At
cassandra/connection.py:313-315on master, the right-hand tuple is built fromself._server_namerather thanother._server_name:__eq__and__hash__just above it both useother._server_name, so this looks like a copy-paste slip rather than an intended asymmetry.Consequence. Two SNI endpoints that share a proxy address and port but differ by server name compare as neither less nor greater: the third element of both tuples is the same object, so the comparison falls through to equality on the first two.
a < bandb < aare both False for endpoints__eq__considers different.SniEndPointcarries@total_ordering, so the derived>,<=and>=inherit the same result, andsorted()over a list of such endpoints is not well defined — the order depends on where Timsort happens to place each item.This is the normal shape for an SNI deployment: one proxy address and port, many server names.
Repro
Fix.
other._server_namein the right-hand tuple.Not introduced by any open PR; it dates to
9b145cf9(Add SNIEndPoint support). Noticed while reviewing #789, which adds_default_tls_session_cache_keyto the same class but does not touch this method.