homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Typing: Specialized subclasses of generics cannot be unpickled
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: alexandre.vassalotti, gvanrossum, maatt, pitrou, python-dev, serhiy.storchaka
Priority: normal Keywords:

Created on 2015年10月25日 03:09 by maatt, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Messages (7)
msg253421 - (view) Author: Matt Chaput (maatt) Date: 2015年10月25日 03:09
If I try to pickle and unpickle an object of a class that has specialized a generic superclass, when I try to unpickle I get this error:
TypeError: descriptor '__dict__' for 'A' objects doesn't apply to 'B' object
Test case:
from typing import Generic, TypeVar
import pickle
T = TypeVar("T")
class A(Generic[T]):
 def __init__(self, x: T):
 self.x = x
class B(A[str]):
 def __init__(self, x: str):
 self.x = x
b = B("hello")
z = pickle.dumps(b)
print(z)
_ = pickle.loads(z)
msg253514 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015年10月27日 04:00
FWIW the pickle produced looks like this, decoded with pickletools.dis():
 0: \x80 PROTO 3
 2: c GLOBAL '__main__ B'
 14: q BINPUT 0
 16: ) EMPTY_TUPLE
 17: \x81 NEWOBJ
 18: q BINPUT 1
 20: } EMPTY_DICT
 21: q BINPUT 2
 23: X BINUNICODE 'x'
 29: q BINPUT 3
 31: X BINUNICODE 'hello'
 41: q BINPUT 4
 43: s SETITEM
 44: b BUILD
 45: . STOP
msg253515 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015年10月27日 04:14
The issue seems to be the line
 inst_dict = inst.__dict__
in _Unpickler.load_build(). (I found this out by forcing sys.modules['_pickle'] = None, so the pure-Python pickle.py code gets used.)
This leads to a simpler repro: 
# Use the same class definitions for A and B
b = B("hello")
print(b.__dict__) # Same error message as before
That is, specialized subclasses of generics don't have a working __dict__ attribute! Interestingly, A("hello").__dict__ works.
I have to ponder this more.
msg254877 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015年11月19日 03:12
Update: I have not forgotten this, but it's a tough case and I haven't made much progress. I don't think I'll make the deadline for 3.5.1.
msg254878 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015年11月19日 05:01
Actually, I just found an embarrassingly simple fix:
diff --git a/src/typing.py b/src/typing.py
index d900036..49c4a06 100644
--- a/src/typing.py
+++ b/src/typing.py
@@ -981,7 +981,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
 "Cannot substitute %s for %s in %s" %
 (_type_repr(new), _type_repr(old), self))
 
- return self.__class__(self.__name__, self.__bases__,
+ return self.__class__(self.__name__, (self,) + self.__bases__,
 dict(self.__dict__),
 parameters=params,
 origin=self,
I'll go check this in now, together with a test.
msg254879 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015年11月19日 05:14
New changeset 1d37f7dbbb37 by Guido van Rossum in branch '3.5':
Issue #25472: In B[<type>], insert B in front of __bases__, to make the __dict__ descriptor work.
https://hg.python.org/cpython/rev/1d37f7dbbb37
New changeset 63c261185fc7 by Guido van Rossum in branch 'default':
Issue #25472: In B[<type>], insert B in front of __bases__, to make the __dict__ descriptor work. (Merge 3.5->3.6)
https://hg.python.org/cpython/rev/63c261185fc7 
msg254880 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2015年11月19日 05:20
Thanks for the report! Made it before the 3.5.1 (rc1) deadline.
History
Date User Action Args
2022年04月11日 14:58:23adminsetgithub: 69658
2015年11月19日 05:20:46gvanrossumsetstatus: open -> closed
resolution: fixed
messages: + msg254880
2015年11月19日 05:14:08python-devsetnosy: + python-dev
messages: + msg254879
2015年11月19日 05:01:57gvanrossumsetmessages: + msg254878
2015年11月19日 03:12:03gvanrossumsetassignee: gvanrossum
messages: + msg254877
2015年10月27日 04:14:02gvanrossumsetmessages: + msg253515
2015年10月27日 04:00:30gvanrossumsetmessages: + msg253514
2015年10月25日 05:08:42serhiy.storchakasetnosy: + gvanrossum, pitrou, alexandre.vassalotti, serhiy.storchaka

type: behavior
components: + Library (Lib)
versions: + Python 3.6
2015年10月25日 03:09:33maattcreate

AltStyle によって変換されたページ (->オリジナル) /