Skip to content

Commit d498625

Browse files
bpo-33652: Improve pickle support in the typing module. (GH-7123)
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 <[email protected]>
1 parent e69657d commit d498625

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

Lib/typing.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import collections.abc
2525
import contextlib
2626
import functools
27+
import operator
2728
import re as stdlib_re # Avoid confusion with the re we export.
2829
import sys
2930
import types
@@ -486,10 +487,6 @@ def __repr__(self):
486487
return f'ForwardRef({self.__forward_arg__!r})'
487488

488489

489-
def _find_name(mod, name):
490-
return getattr(sys.modules[mod], name)
491-
492-
493490
class TypeVar(_Final, _Immutable, _root=True):
494491
"""Type variable.
495492
@@ -535,7 +532,7 @@ def longest(x: A, y: A) -> A:
535532
"""
536533

537534
__slots__ = ('__name__', '__bound__', '__constraints__',
538-
'__covariant__', '__contravariant__', '_def_mod')
535+
'__covariant__', '__contravariant__')
539536

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

559558
def __getstate__(self):
560559
return {'name': self.__name__,
@@ -580,7 +579,7 @@ def __repr__(self):
580579
return prefix + self.__name__
581580

582581
def __reduce__(self):
583-
return (_find_name, (self._def_mod, self.__name__))
582+
return self.__name__
584583

585584

586585
# Special typing constructs Union, Optional, Generic, Callable and Tuple
@@ -741,7 +740,19 @@ def __subclasscheck__(self, cls):
741740
def __reduce__(self):
742741
if self._special:
743742
return self._name
744-
return super().__reduce__()
743+
744+
if self._name:
745+
origin = globals()[self._name]
746+
else:
747+
origin = self.__origin__
748+
if (origin is Callable and
749+
not (len(self.__args__) == 2 and self.__args__[0] is Ellipsis)):
750+
args = list(self.__args__[:-1]), self.__args__[-1]
751+
else:
752+
args = tuple(self.__args__)
753+
if len(args) == 1 and not isinstance(args[0], tuple):
754+
args, = args
755+
return operator.getitem, (origin, args)
745756

746757

747758
class _VariadicGenericAlias(_GenericAlias, _root=True):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Pickles of type variables and subscripted generics are now future-proof and
2+
compatible with older Python versions.

0 commit comments

Comments
 (0)