Skip to content

Commit b30b29e

Browse files
disable local-class hashing
1 parent a722191 commit b30b29e

2 files changed

Lines changed: 5 additions & 47 deletions

File tree

pytools/persistent_dict.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,11 @@ def update_for_type(self, key_hash: Hash, key: type) -> None:
251251
resolved = getattr(resolved, attr) # pyright: ignore[reportAny]
252252
if resolved is key:
253253
# Globally accessible: hash based on name
254-
self.rec(key_hash,
255-
f"{key.__module__}.{key.__qualname__}".encode()
256-
)
254+
self.rec(key_hash, f"{key.__module__}.{key.__qualname__}")
257255
else:
258-
# Name collision or local class; fall back
259-
self.rec(key_hash, f"{key.__module__}.{key.__qualname__}_{id(key)}")
256+
raise ValueError(f"Cannot hash function-local class '{key}'")
260257
except (KeyError, AttributeError):
261-
# Can't resolve the class name, must be local
262-
self.rec(key_hash, f"{key.__module__}.{key.__qualname__}_{id(key)}")
258+
raise ValueError(f"Cannot hash function-local class '{key}'") from None
263259

264260
update_for_ABCMeta = update_for_type
265261

pytools/test/test_persistent_dict.py

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,6 @@ def test_ABC_hashing() -> None: # noqa: N802
503503
class MyABC(ABC): # noqa: B024
504504
pass
505505

506-
assert keyb(MyABC) != keyb(ABC)
507-
508506
with pytest.raises(TypeError):
509507
keyb(MyABC())
510508

@@ -515,62 +513,29 @@ class MyABC2(MyABC):
515513
def update_persistent_hash(self, key_hash, key_builder):
516514
key_builder.rec(key_hash, 42)
517515

518-
assert keyb(MyABC2) != keyb(MyABC)
519516
assert keyb(MyABC2())
520517

521518
class MyABC3(metaclass=ABCMeta): # noqa: B024
522519
def update_persistent_hash(self, key_hash, key_builder):
523520
key_builder.rec(key_hash, 42)
524521

525-
assert keyb(MyABC3) != keyb(MyABC) != keyb(MyABC3())
522+
assert keyb(MyABC3())
526523

527524

528525
class WithoutUpdateMethodGlobal:
529526
pass
530527

531528

532-
class CollidingNameClass:
533-
pass
534-
535-
536529
def test_class_hashing() -> None:
537530
keyb = KeyBuilder()
538531

539-
class WithoutUpdateMethod:
540-
pass
541-
542-
assert keyb(WithoutUpdateMethod) == keyb(WithoutUpdateMethod)
543532
assert keyb(WithoutUpdateMethodGlobal) == keyb(WithoutUpdateMethodGlobal)
544-
545-
# This doesn't work with the function-local class "WithoutUpdateMethod", because
546-
# local classes are instantiated at each function call, and thus their hash
547-
# includes the id() of the class:
548-
# assert keyb(WithoutUpdateMethod) == "N/A"
549533
assert keyb(WithoutUpdateMethodGlobal) == "49c4673089d30507"
550534

551-
with pytest.raises(TypeError):
552-
# does not have update_persistent_hash() = > will raise
553-
keyb(WithoutUpdateMethod())
554-
555535
with pytest.raises(TypeError):
556536
# does not have update_persistent_hash() = > will raise
557537
keyb(WithoutUpdateMethodGlobal())
558538

559-
# {{{ test for name collisions between top-level and function-local classes
560-
561-
def make_colliding_name_class():
562-
class CollidingNameClass:
563-
pass
564-
565-
return CollidingNameClass
566-
567-
top_level_cls = CollidingNameClass
568-
shadowed_cls = make_colliding_name_class()
569-
570-
assert keyb(top_level_cls) != keyb(shadowed_cls)
571-
572-
# }}}
573-
574539
class WithUpdateMethod:
575540
def update_persistent_hash(self, key_hash, key_builder):
576541
# Only called for instances of this class, not for the class itself
@@ -583,11 +548,8 @@ class TagClass(Tag):
583548
class TagClass2(Tag):
584549
pass
585550

586-
assert keyb(WithUpdateMethod) != keyb(WithUpdateMethod())
587-
assert keyb(TagClass) != keyb(TagClass())
588-
assert keyb(TagClass2) != keyb(TagClass2())
551+
assert keyb(WithUpdateMethod()) == keyb(WithUpdateMethod())
589552

590-
assert keyb(TagClass) != keyb(TagClass2)
591553
assert keyb(TagClass()) != keyb(TagClass2())
592554

593555
assert keyb(TagClass()) == "7b3e4e66503438f6"

0 commit comments

Comments
 (0)