typing.Protocol
implementation means that isinstance([], collections.abc.Mapping)
can sometimes evaluate to True
#105280
Labels
3.12
only security fixes
3.13
bugs and security fixes
stdlib
Python modules in the Lib dir
topic-typing
type-bug
An unexpected behavior, bug, or error
(In very specific circumstances)
Bug report
Due to some changes that have been made to the implementation of
typing.Protocol
in Python 3.12, whether or notisinstance([], collections.abc.Mapping)
evaluates toTrue
orFalse
now depends on precisely when and if garbage collection happens.Minimal repro:
Why does this happen?! It's because
Foo
is an illegal class, soTypeError
is raised during class initialisation here:cpython/Lib/typing.py
Lines 1905 to 1912 in ce558e6
TypeError
being raised here means thatFoo
never has__protocol_attrs__
set on it. But, the error is raised after class construction, meaning that if garbage collection happens at the wrong time, a reference toFoo
is still retained incollections.abc.Mapping.__subclasses__()
. This then creates problems in theisinstance()
check, because of some behaviour in theabc
module where it iterates through all of the subclasses ofcollections.abc.Mapping
in order to determine whether an object is an instance ofcollections.abc.Mapping
.The fix is to raise
TypeError
before the class has actually been created, rather than during class initialisation.Why does this matter?
This might seem like an absurdly specific bug report, but it would be good to see it fixed. It was causing bizarre test failures in the
typing_extensions
backport. The issue was that we did this in one test method:...And that final
P
class wasn't being cleaned up by the garbage collector immediately after that test having been run. That then caused an unrelated test elsewhere to fail due to the fact thatisinstance([], collections.abc.Mapping)
was evaluating toTrue
, and it was very hard to figure out why.Linked PRs
isinstance([], collections.abc.Mapping)
always evaluates toFalse
#105281isinstance([], collections.abc.Mapping)
always evaluates toFalse
(GH-105281) #105318The text was updated successfully, but these errors were encountered: