From 4735de50b568468e355517a3133799d1136a9be2 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 30 Jun 2025 15:18:22 +0900 Subject: [PATCH 1/4] gh-136047 Allow typing._allow_reckless_class_checks to check `_py_abc` When `abc.py` fails to import `_abc` and instead imports `_py_abc.ABCMeta`, `_py_abc.ABCMeta.__module__` is set to `abc` to allow `typing._allow_reckless_class_checks` to work with it. Unfortunately, when `typing._caller` falls back to using `sys._getframe`, its `globals()` contains the real module name instead of the module name of the frame's function. This patch allows checking for `_py_abc` in that scenario. --- Lib/typing.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index ed1dd4fc6413a5..1b6a8898e17540 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1843,11 +1843,15 @@ def _no_init_or_replace_init(self, *args, **kwargs): cls.__init__(self, *args, **kwargs) +_RECKLESS_CLASS_CHECK_ALLOWED = {'abc', 'functools', None} +_SYS_HAS_GETFRAMEMODULENAME = hasattr(sys, '_getframemodulename') +if not _SYS_HAS_GETFRAMEMODULENAME: + _RECKLESS_CLASS_CHECK_ALLOWED.add('_py_abc') + + def _caller(depth=1, default='__main__'): - try: + if _SYS_HAS_GETFRAMEMODULENAME: return sys._getframemodulename(depth + 1) or default - except AttributeError: # For platforms without _getframemodulename() - pass try: return sys._getframe(depth + 1).f_globals.get('__name__', default) except (AttributeError, ValueError): # For platforms without _getframe() @@ -1860,7 +1864,7 @@ def _allow_reckless_class_checks(depth=2): The abc and functools modules indiscriminately call isinstance() and issubclass() on the whole MRO of a user class, which may contain protocols. """ - return _caller(depth) in {'abc', 'functools', None} + return _caller(depth) in _RECKLESS_CLASS_CHECK_ALLOWED _PROTO_ALLOWLIST = { From 8e216945250997d880acb98b7d1eb82a0ab21e0d Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 30 Jun 2025 23:43:29 +0900 Subject: [PATCH 2/4] Revert "gh-136047 Allow typing._allow_reckless_class_checks to check `_py_abc`" This reverts commit 4735de50b568468e355517a3133799d1136a9be2. --- Lib/typing.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 1b6a8898e17540..ed1dd4fc6413a5 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1843,15 +1843,11 @@ def _no_init_or_replace_init(self, *args, **kwargs): cls.__init__(self, *args, **kwargs) -_RECKLESS_CLASS_CHECK_ALLOWED = {'abc', 'functools', None} -_SYS_HAS_GETFRAMEMODULENAME = hasattr(sys, '_getframemodulename') -if not _SYS_HAS_GETFRAMEMODULENAME: - _RECKLESS_CLASS_CHECK_ALLOWED.add('_py_abc') - - def _caller(depth=1, default='__main__'): - if _SYS_HAS_GETFRAMEMODULENAME: + try: return sys._getframemodulename(depth + 1) or default + except AttributeError: # For platforms without _getframemodulename() + pass try: return sys._getframe(depth + 1).f_globals.get('__name__', default) except (AttributeError, ValueError): # For platforms without _getframe() @@ -1864,7 +1860,7 @@ def _allow_reckless_class_checks(depth=2): The abc and functools modules indiscriminately call isinstance() and issubclass() on the whole MRO of a user class, which may contain protocols. """ - return _caller(depth) in _RECKLESS_CLASS_CHECK_ALLOWED + return _caller(depth) in {'abc', 'functools', None} _PROTO_ALLOWLIST = { From 519898d00fdf28ae9d510a93fe117f0f2996ab43 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 30 Jun 2025 23:45:29 +0900 Subject: [PATCH 3/4] Simply add _py_abc --- Lib/typing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/typing.py b/Lib/typing.py index ed1dd4fc6413a5..e8a61e64833602 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1860,7 +1860,9 @@ def _allow_reckless_class_checks(depth=2): The abc and functools modules indiscriminately call isinstance() and issubclass() on the whole MRO of a user class, which may contain protocols. """ - return _caller(depth) in {'abc', 'functools', None} + # gh-136047: When `_abc` module is not available, `_py_abc` is required to + # allow `_py_abc.ABCMeta` fallback. + return _caller(depth) in {'abc', '_py_abc', 'functools', None} _PROTO_ALLOWLIST = { From 934705b9f45f32166a9824c75ea7a8c5adcce420 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 5 Jul 2025 06:59:49 -0700 Subject: [PATCH 4/4] blurb --- .../next/Library/2025-07-05-06-59-46.gh-issue-136047.qWvycf.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-07-05-06-59-46.gh-issue-136047.qWvycf.rst diff --git a/Misc/NEWS.d/next/Library/2025-07-05-06-59-46.gh-issue-136047.qWvycf.rst b/Misc/NEWS.d/next/Library/2025-07-05-06-59-46.gh-issue-136047.qWvycf.rst new file mode 100644 index 00000000000000..1a381860914bc3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-05-06-59-46.gh-issue-136047.qWvycf.rst @@ -0,0 +1,2 @@ +Fix issues with :mod:`typing` when the C implementation of :mod:`abc` is not +available.