Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
Open
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
The update to the invalidation counter is not thread-safe and can lose updates in some Python implementations:
Failures seen on:
- Python 3.14t
- Python 3.9
- pypy3.10
- pypy3.11
But not on Python 3.10-3.14 with GIL due to limited GIL switch opportunities.
Lines 54 to 70 in 05e89c3
| defregister(cls, subclass): | |
| """Register a virtual subclass of an ABC. | |
| Returns the subclass, to allow usage as a class decorator. | |
| """ | |
| ifnotisinstance(subclass, type): | |
| raiseTypeError("Can only register classes") | |
| ifissubclass(subclass, cls): | |
| returnsubclass# Already a subclass | |
| # Subtle: test for cycles *after* testing for "already a subclass"; | |
| # this means we allow X.register(X) and interpret it as a no-op. | |
| ifissubclass(cls, subclass): | |
| # This would create a cycle, which is bad for the algorithm below | |
| raiseRuntimeError("Refusing to create an inheritance cycle") | |
| cls._abc_registry.add(subclass) | |
| ABCMeta._abc_invalidation_counter+=1# Invalidate negative cache | |
| returnsubclass |
For example, consider the following repro, adapted from test_abc.test_registration_basics:
import_py_abcasabc# Use Python implementation of ABCs!!importthreadingimportosimportsyssys.setswitchinterval(1e-6) N=5defrun(b): b.wait() classA(metaclass=abc.ABCMeta): passA.register(int) ifnotisinstance(42, A): print("Oops!") os._exit(1) defmain(): for_inrange(10000): threads= [] b=threading.Barrier(N) for_inrange(N): t=threading.Thread(target=run, args=(b,)) threads.append(t) t.start() fortinthreads: t.join() if__name__=="__main__": main()Linked PRs
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error