Skip to content

Commit 386e66a

Browse files
committed
Minor optimizations and test for #150
1 parent 445e823 commit 386e66a

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

src/graphql/language/ast.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,18 @@ def __eq__(self, other: Any) -> bool:
255255
)
256256

257257
def __hash__(self) -> int:
258-
if getattr(self, "_hash", None) is None:
259-
self._hash = hash(tuple(getattr(self, key) for key in self.keys))
260-
return self._hash
261-
262-
def __setattr__(self, key, value):
263-
object.__setattr__(self, "_hash", None)
258+
"""Get a cached hash value for the node."""
259+
# Caching the hash values improves the performance of AST validators
260+
hashed = getattr(self, "_hash", None)
261+
if hashed is None:
262+
hashed = hash(tuple(getattr(self, key) for key in self.keys))
263+
self._hash = hashed
264+
return hashed
265+
266+
def __setattr__(self, key: str, value: Any) -> None:
267+
# reset cashed hash value if attributes are changed
268+
if hasattr(self, "_hash") and key in self.keys:
269+
del self._hash
264270
super().__setattr__(key, value)
265271

266272
def __copy__(self) -> "Node":

tests/language/test_ast.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,27 @@ def can_hash():
180180
assert node3 != node
181181
assert hash(node3) != hash(node)
182182

183+
def caches_are_hashed():
184+
node = SampleTestNode(alpha=1)
185+
assert not hasattr(node, "_hash")
186+
hash1 = hash(node)
187+
assert hasattr(node, "_hash")
188+
assert hash1 == getattr(node, "_hash")
189+
node.alpha = 2
190+
assert not hasattr(node, "_hash")
191+
hash2 = hash(node)
192+
assert hash2 != hash1
193+
assert hasattr(node, "_hash")
194+
assert hash2 == getattr(node, "_hash")
195+
183196
def can_create_weak_reference():
184197
node = SampleTestNode(alpha=1, beta=2)
185198
ref = weakref.ref(node)
186199
assert ref() is node
187200

188201
def can_create_custom_attribute():
189202
node = SampleTestNode(alpha=1, beta=2)
190-
node.gamma = 3 # type: ignore
203+
node.gamma = 3
191204
assert node.gamma == 3 # type: ignore
192205

193206
def can_create_shallow_copy():

0 commit comments

Comments
 (0)