| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…t_thread_module_has_signatures
…44DYc.rst Co-authored-by: AN Long <aisk@users.noreply.github.com>
There was a problem hiding this comment.
LGTM. It makes sense to remove the Python implementation and declare threading.RLock as a class.
Sorry, something went wrong.
| @@ -0,0 +1 @@ | |||
| Make :class:`threading.RLock` a real class instead of a factory function. | |||
There was a problem hiding this comment.
Please mention also that the Python implementation has been removed.
Sorry, something went wrong.
| @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') | ||
| class CRLockTests(lock_tests.RLockTests): | ||
| locktype = staticmethod(threading._CRLock) | ||
| class RLockTests(lock_tests.RLockTests): |
There was a problem hiding this comment.
According to PEP 8, there should be two blank lines between classes. Other parts of this file may not follow PEP 8, but since we touched this part, let's update it (and keep the rest as it is).
| class RLockTests(lock_tests.RLockTests): | |
| class RLockTests(lock_tests.RLockTests): |
Sorry, something went wrong.
|
_thread.Lock is not a basetype, however _thread.RLock is a basetype. Given that previously this was a factory function and not intended for inheritance I think we should make _thread.RLock non-basetype. |
Sorry, something went wrong.
| return _PyRLock() | ||
| return _CRLock() | ||
|
|
||
| class _RLock: |
There was a problem hiding this comment.
For backwards compatibility with people using threading._RLock for their types, could we keep _RLock = RLock? It doesn't cost us much and won't be an issue but at least it won't be cause breakage downstream where people assume _RLock to be a class.
Same with keeping _CRLock and _PyRLock just for backward compatibility.
I know that we don't need to do it, but it's preferrable that we don't remove symbols like that sitting for the past decades.
Sorry, something went wrong.
There was a problem hiding this comment.
A code search on PyPI top 15,000 projects for threading._RLock found 6 matching projects:
PYPI-2026-01-07/astroid-4.0.3.tar.gz: astroid-4.0.3/tests/brain/test_multiprocessing.py: rlock_name = "threading._RLock" PYPI-2026-01-07/django_sendgrid_v5-1.3.1.tar.gz: django_sendgrid_v5-1.3.1/sendgrid_backend/mail.py: self._lock = None # type: Optional[threading._RLock] PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/gevent/threading.py: # Previously it was a factory function around threading._RLock PYPI-2026-01-07/prefect-3.6.9.tar.gz: prefect-3.6.9/src/prefect/_internal/concurrency/cancellation.py: self._lock = threading._RLock() # type: ignore # yes, we want the private version PYPI-2026-01-07/prefect_client-3.6.9.tar.gz: prefect_client-3.6.9/src/prefect/_internal/concurrency/cancellation.py: self._lock = threading._RLock() # type: ignore # yes, we want the private version PYPI-2026-01-07/pylint-4.0.4.tar.gz: pylint-4.0.4/pylint/checkers/refactoring/refactoring_checker.py: "threading._RLock.acquire",
I also found 7 projects embedding a copy of typeshed annotations (multiprocessing/managers.pyi) which also refers to threading._RLock. Example:
PYPI-2026-01-07/mypy-1.19.1.tar.gz: mypy-1.19.1/mypy/typeshed/stdlib/multiprocessing/managers.pyi: def Condition(self, lock: threading.Lock | threading._RLock | None = None) -> threading.Condition: ...
A code search on PyPI top 15,000 projects for threading._(CRLock|PyRLock) found 2 matching projects: eventlet and gevent.
PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/eventlet/patcher.py: threading.RLock = threading._PyRLock PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/eventlet/patcher.py: new = threading._PyRLock() PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/tests/isolated/patcher_existing_locks_preexisting.py: python_lock = threading._PyRLock PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/tests/isolated/patcher_existing_logging_module_lock.py: assert not isinstance(logging._lock, threading._PyRLock) PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/tests/isolated/patcher_existing_logging_module_lock.py: assert not isinstance(handler.lock, threading._PyRLock) PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/tests/isolated/patcher_existing_logging_module_lock.py: assert isinstance(logging._lock, threading._PyRLock) PYPI-2026-01-07/eventlet-0.40.4.tar.gz: eventlet-0.40.4/tests/isolated/patcher_existing_logging_module_lock.py: assert isinstance(handler.lock, threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/gevent/threading.py: # threading._CRLock, which is imported from _thread.RLock and as such PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.10/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.10/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.10/test_threading.py: locktype = staticmethod(threading._CRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.11/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.11/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.11/test_threading.py: locktype = staticmethod(threading._CRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.12/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.12/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.12/test_threading.py: locktype = staticmethod(threading._CRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.13/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.13/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.13/test_threading.py: locktype = staticmethod(threading._CRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.14/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.14/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.14/test_threading.py: locktype = staticmethod(threading._CRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.9/test_threading.py: locktype = staticmethod(threading._PyRLock) PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.9/test_threading.py: @unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C') PYPI-2026-01-07/gevent-25.9.1.tar.gz: gevent-25.9.1/src/greentest/3.9/test_threading.py: locktype = staticmethod(threading._CRLock)
Sorry, something went wrong.
There was a problem hiding this comment.
Would it be possible to deprecate threading._RLock if we decide to keep it?
For _CRLock and _PyRLock, I don't think that we need to keep them. Impacted projects (eventlet, gevent) should be updated anyway for this change.
Sorry, something went wrong.
There was a problem hiding this comment.
So, I think we need to contact those projects or make the change louder. This typically requires something in the What's New page. However, there might be other private projects that could be broken. I really don't want to remove this class like that. However, making the attribute raise a deprecation warning could be better. Yes, it will pollute outputs but people know that the implementation will really be different (that is, it will be using the C implementation).
Sorry, something went wrong.
| __enter__ = acquire | ||
|
|
||
| def release(self): | ||
| """Release a lock, decrementing the recursion level. |
There was a problem hiding this comment.
Can you quickly check that the docstrings match the C docstrings as well please?
Sorry, something went wrong.
Oh, it's a good idea to remove the Py_TPFLAGS_BASETYPE flag. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
gh-141460 make RLock a class instead of a factory function
📚 Documentation preview 📚: https://cpython-previews--142977.org.readthedocs.build/