]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44747: Refactor usage of sys._getframe at typing module (#27387)
authorYurii Karabas <1998uriyyo@gmail.com>
Fri, 30 Jul 2021 13:49:24 +0000 (16:49 +0300)
committerGitHub <noreply@github.com>
Fri, 30 Jul 2021 13:49:24 +0000 (15:49 +0200)
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Lib/typing.py
Misc/NEWS.d/next/Library/2021-07-27-12-06-19.bpo-44747.epUzZz.rst [new file with mode: 0644]

index 2826525efff7aaf4b51e7a7fe787a30ef7c1d5ca..702bb647269d0be3c3f753f4a6a4f8747f98ffcf 100644 (file)
@@ -798,10 +798,7 @@ class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True):
             raise TypeError("A single constraint is not allowed")
         msg = "TypeVar(name, constraint, ...): constraints must be types."
         self.__constraints__ = tuple(_type_check(t, msg) for t in constraints)
-        try:
-            def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')  # for pickling
-        except (AttributeError, ValueError):
-            def_mod = None
+        def_mod = _caller()
         if def_mod != 'typing':
             self.__module__ = def_mod
 
@@ -904,10 +901,7 @@ class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True):
     def __init__(self, name, *, bound=None, covariant=False, contravariant=False):
         self.__name__ = name
         super().__init__(bound, covariant, contravariant)
-        try:
-            def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
-        except (AttributeError, ValueError):
-            def_mod = None
+        def_mod = _caller()
         if def_mod != 'typing':
             self.__module__ = def_mod
 
@@ -1400,10 +1394,7 @@ def _allow_reckless_class_checks(depth=3):
     The abc and functools modules indiscriminately call isinstance() and
     issubclass() on the whole MRO of a user class, which may contain protocols.
     """
-    try:
-        return sys._getframe(depth).f_globals['__name__'] in ['abc', 'functools']
-    except (AttributeError, ValueError):  # For platforms without _getframe().
-        return True
+    return _caller(depth) in {'abc', 'functools', None}
 
 
 _PROTO_ALLOWLIST = {
@@ -2238,11 +2229,7 @@ def NamedTuple(typename, fields=None, /, **kwargs):
     elif kwargs:
         raise TypeError("Either list of fields or keywords"
                         " can be provided to NamedTuple, not both")
-    try:
-        module = sys._getframe(1).f_globals.get('__name__', '__main__')
-    except (AttributeError, ValueError):
-        module = None
-    return _make_nmtuple(typename, fields, module=module)
+    return _make_nmtuple(typename, fields, module=_caller())
 
 _NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {})
 
@@ -2357,11 +2344,10 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
                         " but not both")
 
     ns = {'__annotations__': dict(fields)}
-    try:
+    module = _caller()
+    if module is not None:
         # Setting correct module is necessary to make typed dict classes pickleable.
-        ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
-    except (AttributeError, ValueError):
-        pass
+        ns['__module__'] = module
 
     return _TypedDictMeta(typename, (), ns, total=total)
 
diff --git a/Misc/NEWS.d/next/Library/2021-07-27-12-06-19.bpo-44747.epUzZz.rst b/Misc/NEWS.d/next/Library/2021-07-27-12-06-19.bpo-44747.epUzZz.rst
new file mode 100644 (file)
index 0000000..e63d77f
--- /dev/null
@@ -0,0 +1,2 @@
+Refactor usage of ``sys._getframe`` in ``typing`` module. Patch provided by
+Yurii Karabas.