blueloveTH 2 лет назад
Родитель
Сommit
6edb50b516
3 измененных файлов с 18 добавлено и 2 удалено
  1. 8 1
      docs/modules/pickle.md
  2. 7 1
      python/pickle.py
  3. 3 0
      tests/81_pickle.py

+ 8 - 1
docs/modules/pickle.md

@@ -21,5 +21,12 @@ The following types can be pickled:
 - [x] strings, bytes;
 - [x] tuples, lists, sets, and dictionaries containing only picklable objects;
 - [ ] functions (built-in and user-defined) accessible from the top level of a module (using def, not lambda);
-- [ ] classes accessible from the top level of a module;
+- [x] classes accessible from the top level of a module;
 - [x] instances of such classes
+
+The following magic methods are available:
+
+- [x] `__getnewargs__`
+- [ ] `__getstate__`
+- [ ] `__setstate__`
+- [ ] `__reduce__`

+ 7 - 1
python/pickle.py

@@ -29,7 +29,9 @@ class _Pickler:
     def wrap(self, o):
         if type(o) in _BASIC_TYPES:
             return o
-        
+        if type(o) is type:
+            return ["type", o.__name__]
+
         index = self.raw_memo.get(id(o), None)
         if index is not None:
             return [index]
@@ -47,6 +49,7 @@ class _Pickler:
             ret.append("bytes")
             ret.append([o[j] for j in range(len(o))])
             return [index]
+
         if type(o) is list:
             ret.append("list")
             ret.append([self.wrap(i) for i in o])
@@ -97,6 +100,9 @@ class _Unpickler:
             return o
         assert type(o) is list
 
+        if o[0] == "type":
+            return _find_class(o[1])
+
         # reference
         if type(o[0]) is int:
             assert index is None    # index should be None

+ 3 - 0
tests/81_pickle.py

@@ -60,4 +60,7 @@ assert c == d
 from collections import deque
 
 a = deque([1, 2, 3])
+test(a)
+
+a = [int, float, Foo]
 test(a)