mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
add __module__
for types and fix pickle bugs
This commit is contained in:
parent
7a7ded5735
commit
aaa6d60404
@ -51,6 +51,7 @@ typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
|
|||||||
struct PyTypeInfo{
|
struct PyTypeInfo{
|
||||||
PyObject* obj;
|
PyObject* obj;
|
||||||
Type base;
|
Type base;
|
||||||
|
PyObject* mod;
|
||||||
Str name;
|
Str name;
|
||||||
bool subclass_enabled;
|
bool subclass_enabled;
|
||||||
|
|
||||||
|
@ -2,15 +2,13 @@ import json
|
|||||||
import builtins
|
import builtins
|
||||||
|
|
||||||
_BASIC_TYPES = [int, float, str, bool, type(None)]
|
_BASIC_TYPES = [int, float, str, bool, type(None)]
|
||||||
|
_MOD_T_SEP = "@"
|
||||||
|
|
||||||
def _find_class(path: str):
|
def _find_class(path: str):
|
||||||
if "." not in path:
|
if _MOD_T_SEP not in path:
|
||||||
g = globals()
|
|
||||||
if path in g:
|
|
||||||
return g[path]
|
|
||||||
return builtins.__dict__[path]
|
return builtins.__dict__[path]
|
||||||
modname, name = path.split(".")
|
modpath, name = path.split(_MOD_T_SEP)
|
||||||
return __import__(modname).__dict__[name]
|
return __import__(modpath).__dict__[name]
|
||||||
|
|
||||||
def _find__new__(cls):
|
def _find__new__(cls):
|
||||||
while cls is not None:
|
while cls is not None:
|
||||||
@ -26,11 +24,19 @@ class _Pickler:
|
|||||||
self.raw_memo = {} # id -> int
|
self.raw_memo = {} # id -> int
|
||||||
self.memo = [] # int -> object
|
self.memo = [] # int -> object
|
||||||
|
|
||||||
|
def _type_id(self, o: type):
|
||||||
|
assert type(o) is type
|
||||||
|
name = o.__name__
|
||||||
|
mod = o.__module__
|
||||||
|
if mod is not None:
|
||||||
|
name = mod.__path__ + _MOD_T_SEP + name
|
||||||
|
return name
|
||||||
|
|
||||||
def wrap(self, o):
|
def wrap(self, o):
|
||||||
if type(o) in _BASIC_TYPES:
|
if type(o) in _BASIC_TYPES:
|
||||||
return o
|
return o
|
||||||
if type(o) is type:
|
if type(o) is type:
|
||||||
return ["type", o.__name__]
|
return ["type", self._type_id(o)]
|
||||||
|
|
||||||
index = self.raw_memo.get(id(o), None)
|
index = self.raw_memo.get(id(o), None)
|
||||||
if index is not None:
|
if index is not None:
|
||||||
@ -59,7 +65,7 @@ class _Pickler:
|
|||||||
ret.append([[self.wrap(k), self.wrap(v)] for k,v in o.items()])
|
ret.append([[self.wrap(k), self.wrap(v)] for k,v in o.items()])
|
||||||
return [index]
|
return [index]
|
||||||
|
|
||||||
_0 = o.__class__.__name__
|
_0 = self._type_id(type(o))
|
||||||
|
|
||||||
if hasattr(o, "__getnewargs__"):
|
if hasattr(o, "__getnewargs__"):
|
||||||
_1 = o.__getnewargs__() # an iterable
|
_1 = o.__getnewargs__() # an iterable
|
||||||
|
@ -1540,6 +1540,11 @@ void VM::post_init(){
|
|||||||
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
||||||
return VAR(info.name);
|
return VAR(info.name);
|
||||||
});
|
});
|
||||||
|
bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){
|
||||||
|
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
|
||||||
|
if(info.mod == nullptr) return vm->None;
|
||||||
|
return info.mod;
|
||||||
|
});
|
||||||
bind_property(_t(tp_bound_method), "__self__", [](VM* vm, ArgsView args){
|
bind_property(_t(tp_bound_method), "__self__", [](VM* vm, ArgsView args){
|
||||||
return CAST(BoundMethod&, args[0]).self;
|
return CAST(BoundMethod&, args[0]).self;
|
||||||
});
|
});
|
||||||
|
@ -131,7 +131,8 @@ namespace pkpy{
|
|||||||
PyTypeInfo info{
|
PyTypeInfo info{
|
||||||
obj,
|
obj,
|
||||||
base,
|
base,
|
||||||
(mod!=nullptr && mod!=builtins) ? Str(OBJ_NAME(mod)+"."+name.sv()): name.sv(),
|
mod,
|
||||||
|
name.sv(),
|
||||||
subclass_enabled,
|
subclass_enabled,
|
||||||
};
|
};
|
||||||
if(mod != nullptr) mod->attr().set(name, obj);
|
if(mod != nullptr) mod->attr().set(name, obj);
|
||||||
@ -636,8 +637,8 @@ void VM::_log_s_data(const char* title) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void VM::init_builtin_types(){
|
void VM::init_builtin_types(){
|
||||||
_all_types.push_back({heap._new<Type>(Type(1), Type(0)), -1, "object", true});
|
_all_types.push_back({heap._new<Type>(Type(1), Type(0)), -1, nullptr, "object", true});
|
||||||
_all_types.push_back({heap._new<Type>(Type(1), Type(1)), 0, "type", false});
|
_all_types.push_back({heap._new<Type>(Type(1), Type(1)), 0, nullptr, "type", false});
|
||||||
tp_object = 0; tp_type = 1;
|
tp_object = 0; tp_type = 1;
|
||||||
|
|
||||||
tp_int = _new_type_object("int");
|
tp_int = _new_type_object("int");
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
from pickle import dumps, loads, _wrap, _unwrap
|
from pickle import dumps, loads, _wrap, _unwrap
|
||||||
|
|
||||||
def test(x):
|
def test(x):
|
||||||
ok = x == loads(dumps(x))
|
y = dumps(x)
|
||||||
|
# print(y.decode())
|
||||||
|
ok = x == loads(y)
|
||||||
if not ok:
|
if not ok:
|
||||||
_0 = _wrap(x)
|
_0 = _wrap(x)
|
||||||
_1 = _unwrap(_0)
|
_1 = _unwrap(_0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user