cpython: 3b974b61e74d (original) (raw)
--- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2239,14 +2239,7 @@ class Parameter: id(self), self) def hash(self):
hash_tuple = (self.name, int(self.kind))[](#l1.7)
if self._annotation is not _empty:[](#l1.9)
hash_tuple += (self._annotation,)[](#l1.10)
if self._default is not _empty:[](#l1.11)
hash_tuple += (self._default,)[](#l1.12)
return hash(hash_tuple)[](#l1.14)
return hash((self.name, self.kind, self.annotation, self.default))[](#l1.15)
def eq(self, other): return (issubclass(other.class, Parameter) and @@ -2541,41 +2534,23 @@ class Signature: return type(self)(parameters, return_annotation=return_annotation)
- def _hash_basis(self):
params = tuple(param for param in self.parameters.values()[](#l1.24)
if param.kind != _KEYWORD_ONLY)[](#l1.25)
kwo_params = {param.name: param for param in self.parameters.values()[](#l1.27)
if param.kind == _KEYWORD_ONLY}[](#l1.28)
return params, kwo_params, self.return_annotation[](#l1.30)
hash_tuple = tuple(self.parameters.values())[](#l1.33)
if self._return_annotation is not _empty:[](#l1.34)
hash_tuple += (self._return_annotation,)[](#l1.35)
return hash(hash_tuple)[](#l1.36)
params, kwo_params, return_annotation = self._hash_basis()[](#l1.37)
kwo_params = frozenset(kwo_params.values())[](#l1.38)
return hash((params, kwo_params, return_annotation))[](#l1.39)
if (not issubclass(type(other), Signature) or[](#l1.42)
self.return_annotation != other.return_annotation or[](#l1.43)
len(self.parameters) != len(other.parameters)):[](#l1.44)
return False[](#l1.45)
other_positions = {param: idx[](#l1.47)
for idx, param in enumerate(other.parameters.keys())}[](#l1.48)
for idx, (param_name, param) in enumerate(self.parameters.items()):[](#l1.50)
if param.kind == _KEYWORD_ONLY:[](#l1.51)
try:[](#l1.52)
other_param = other.parameters[param_name][](#l1.53)
except KeyError:[](#l1.54)
return False[](#l1.55)
else:[](#l1.56)
if param != other_param:[](#l1.57)
return False[](#l1.58)
else:[](#l1.59)
try:[](#l1.60)
other_idx = other_positions[param_name][](#l1.61)
except KeyError:[](#l1.62)
return False[](#l1.63)
else:[](#l1.64)
if (idx != other_idx or[](#l1.65)
param != other.parameters[param_name]):[](#l1.66)
return False[](#l1.67)
return True[](#l1.69)
return (isinstance(other, Signature) and[](#l1.70)
self._hash_basis() == other._hash_basis())[](#l1.71)
def ne(self, other): return not self.eq(other)
--- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -2535,43 +2535,67 @@ class TestSignatureObject(unittest.TestC def bar(a, *, b:int) -> float: pass self.assertEqual(inspect.signature(foo), inspect.signature(bar))
self.assertEqual([](#l2.7)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.8)
def bar(a, *, b:int) -> int: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.12)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.13)
def bar(a, *, b:int): pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.17)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.18)
def bar(a, *, b:int=42) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.22)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.23)
def bar(a, *, c) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.27)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.28)
def bar(a, b:int) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.32)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.33) def spam(b:int, a) -> float: pass[](#l2.34) self.assertNotEqual(inspect.signature(spam), inspect.signature(bar))[](#l2.35)
self.assertNotEqual([](#l2.36)
hash(inspect.signature(spam)), hash(inspect.signature(bar)))[](#l2.37)
def foo(, a, b, c): pass def bar(, c, b, a): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar))
self.assertEqual([](#l2.42)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.43)
def foo(, a=1, b, c): pass def bar(, c, b, a=1): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar))
self.assertEqual([](#l2.48)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.49)
def foo(pos, *, a=1, b, c): pass def bar(pos, *, c, b, a=1): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar))
self.assertEqual([](#l2.54)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.55)
def foo(pos, *, a, b, c): pass def bar(pos, *, c, b, a=1): pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar))
self.assertNotEqual([](#l2.60)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.61)
def foo(pos, *args, a=42, b, c, **kwargs:int): pass def bar(pos, *args, c, b, a=42, **kwargs:int): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar))
self.assertEqual([](#l2.66)
hash(inspect.signature(foo)), hash(inspect.signature(bar)))[](#l2.67)
def test_signature_hashable(self): S = inspect.Signature
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -814,6 +814,7 @@ Library keyword-only.