From ea4673ed0757e9bfe8774e60cfae3313e9927b5f Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Fri, 30 Jul 2021 16:49:24 +0300 Subject: [PATCH] bpo-44747: Refactor usage of sys._getframe at typing module (#27387) Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> --- Lib/typing.py | 28 +++++-------------- .../2021-07-27-12-06-19.bpo-44747.epUzZz.rst | 2 ++ 2 files changed, 9 insertions(+), 21 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-07-27-12-06-19.bpo-44747.epUzZz.rst diff --git a/Lib/typing.py b/Lib/typing.py index 2826525efff..702bb647269 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -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 index 00000000000..e63d77f76de --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-07-27-12-06-19.bpo-44747.epUzZz.rst @@ -0,0 +1,2 @@ +Refactor usage of ``sys._getframe`` in ``typing`` module. Patch provided by +Yurii Karabas.