Skip to content

Commit

Permalink
bpo-33652: Improve pickle support in the typing module. (GH-7123)
Browse files Browse the repository at this point in the history
Pickles of type variables and subscripted generics are now future-proof
and compatible with older Python versions.
(cherry picked from commit 09f3221)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
miss-islington and serhiy-storchaka committed May 26, 2018
1 parent e69657d commit d498625
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
27 changes: 19 additions & 8 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import collections.abc
import contextlib
import functools
import operator
import re as stdlib_re # Avoid confusion with the re we export.
import sys
import types
Expand Down Expand Up @@ -486,10 +487,6 @@ def __repr__(self):
return f'ForwardRef({self.__forward_arg__!r})'


def _find_name(mod, name):
return getattr(sys.modules[mod], name)


class TypeVar(_Final, _Immutable, _root=True):
"""Type variable.
Expand Down Expand Up @@ -535,7 +532,7 @@ def longest(x: A, y: A) -> A:
"""

__slots__ = ('__name__', '__bound__', '__constraints__',
'__covariant__', '__contravariant__', '_def_mod')
'__covariant__', '__contravariant__')

def __init__(self, name, *constraints, bound=None,
covariant=False, contravariant=False):
Expand All @@ -554,7 +551,9 @@ def __init__(self, name, *constraints, bound=None,
self.__bound__ = _type_check(bound, "Bound must be a type.")
else:
self.__bound__ = None
self._def_mod = sys._getframe(1).f_globals['__name__'] # for pickling
def_mod = sys._getframe(1).f_globals['__name__'] # for pickling
if def_mod != 'typing':
self.__module__ = def_mod

def __getstate__(self):
return {'name': self.__name__,
Expand All @@ -580,7 +579,7 @@ def __repr__(self):
return prefix + self.__name__

def __reduce__(self):
return (_find_name, (self._def_mod, self.__name__))
return self.__name__


# Special typing constructs Union, Optional, Generic, Callable and Tuple
Expand Down Expand Up @@ -741,7 +740,19 @@ def __subclasscheck__(self, cls):
def __reduce__(self):
if self._special:
return self._name
return super().__reduce__()

if self._name:
origin = globals()[self._name]
else:
origin = self.__origin__
if (origin is Callable and
not (len(self.__args__) == 2 and self.__args__[0] is Ellipsis)):
args = list(self.__args__[:-1]), self.__args__[-1]
else:
args = tuple(self.__args__)
if len(args) == 1 and not isinstance(args[0], tuple):
args, = args
return operator.getitem, (origin, args)


class _VariadicGenericAlias(_GenericAlias, _root=True):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Pickles of type variables and subscripted generics are now future-proof and
compatible with older Python versions.

0 comments on commit d498625

Please sign in to comment.