blueloveTH 1 неделя назад
Родитель
Сommit
128fc43667
3 измененных файлов с 15 добавлено и 38 удалено
  1. 3 0
      docs/modules/pickle.md
  2. 0 30
      src/modules/pickle.c
  3. 12 8
      tests/904_pickle.py

+ 3 - 0
docs/modules/pickle.md

@@ -24,6 +24,9 @@ The following types can be pickled:
 - [x] classes accessible from the top level of a module;
 - [x] instances of such classes
 
+`array2d` instances cannot be pickled. Calling `pickle.dumps()` on an `array2d`
+raises `TypeError`. Previously pickled `array2d` data is no longer supported.
+
 Cyclic and shared references are preserved: `list`, `dict` and instances of
 python classes are memoized before their contents are written, so an object
 graph containing reference cycles round-trips correctly and object identity

+ 0 - 30
src/modules/pickle.c

@@ -5,7 +5,6 @@
 #include "pocketpy/common/utils.h"
 #include "pocketpy/common/sstream.h"
 #include "pocketpy/interpreter/vm.h"
-#include "pocketpy/interpreter/array2d.h"
 #include <stdint.h>
 
 typedef enum {
@@ -28,7 +27,6 @@ typedef enum {
     PKL_VEC2, PKL_VEC3,
     PKL_VEC2I, PKL_VEC3I,
     PKL_TYPE,
-    PKL_ARRAY2D,
     PKL_IMPORT_PATH,
     PKL_GETATTR,
     PKL_TVALUE,
@@ -396,22 +394,6 @@ static bool pkl__write_object(PickleObject* buf, py_TValue* obj) {
             pkl__emit_cstr(buf, name->data);
             return true;
         }
-        case tp_array2d: {
-            if(pkl__try_memo(buf, obj->_obj)) return true;
-            c11_array2d* arr = py_touserdata(obj);
-            for(int i = 0; i < arr->header.numel; i++) {
-                if(arr->data[i].is_ptr)
-                    return TypeError(
-                        "'array2d' object is not picklable because it contains heap-allocated objects");
-                buf->used_types[arr->data[i].type] = true;
-            }
-            pkl__emit_op(buf, PKL_ARRAY2D);
-            pkl__emit_int(buf, arr->header.n_cols);
-            pkl__emit_int(buf, arr->header.n_rows);
-            PickleObject__write_bytes(buf, arr->data, arr->header.numel * sizeof(py_TValue));
-            pkl__store_memo(buf, obj->_obj);
-            return true;
-        }
         default: {
             if(!obj->is_ptr) {
                 pkl__emit_op(buf, PKL_TVALUE);
@@ -732,18 +714,6 @@ bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_
                 py_push(py_tpobject(type));
                 break;
             }
-            case PKL_ARRAY2D: {
-                int n_cols = pkl__read_int(&p);
-                int n_rows = pkl__read_int(&p);
-                c11_array2d* arr = c11_newarray2d(py_pushtmp(), n_cols, n_rows);
-                int total_size = arr->header.numel * sizeof(py_TValue);
-                memcpy(arr->data, p, total_size);
-                for(int i = 0; i < arr->header.numel; i++) {
-                    arr->data[i].type = pkl__fix_type(arr->data[i].type, type_mapping);
-                }
-                p += total_size;
-                break;
-            }
             case PKL_IMPORT_PATH: {
                 const char* path = pkl__read_cstr(&p);
                 int res = py_import(path);

+ 12 - 8
tests/904_pickle.py

@@ -1,5 +1,12 @@
 import pickle as pkl
 
+def assert_not_picklable(data):
+    try:
+        pkl.dumps(data)
+        assert False, 'array2d must not be picklable'
+    except TypeError as e:
+        assert str(e) == "'array2d' object is not picklable"
+
 def test(data): # type: ignore
     print('-'*50)
     b = pkl.dumps(data)
@@ -37,13 +44,10 @@ a = array2d[int | bool | vec2i].fromlist([
     [1, 2, vec2i.LEFT],
     [4, True, 6]
 ])
-a_encoded = pkl.dumps(a)
-print(a_encoded)
-a_decoded = pkl.loads(a_encoded)
-assert isinstance(a_decoded, array2d)
-assert a_decoded.width == 3 and a_decoded.height == 2
-assert (a == a_decoded).all()
-print(a_decoded)
+assert_not_picklable(a)
+assert_not_picklable([a])
+assert_not_picklable({'array': a})
+assert_not_picklable(array2d.fromlist([['hello', []]]))
 
 test([1, 2, 3])                 # PKL_LIST
 test((1, 2, 3))                 # PKL_TUPLE
@@ -99,7 +103,7 @@ print(pkl.dumps(decoded))
 a = array2d[TVal].fromlist([
     [TVal(1), TVal(2)],
     [TVal(3), 1]])
-test(a)
+assert_not_picklable(a)
 
 # test __reduce__