mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +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{
|
||||
PyObject* obj;
|
||||
Type base;
|
||||
PyObject* mod;
|
||||
Str name;
|
||||
bool subclass_enabled;
|
||||
|
||||
|
@ -2,15 +2,13 @@ import json
|
||||
import builtins
|
||||
|
||||
_BASIC_TYPES = [int, float, str, bool, type(None)]
|
||||
_MOD_T_SEP = "@"
|
||||
|
||||
def _find_class(path: str):
|
||||
if "." not in path:
|
||||
g = globals()
|
||||
if path in g:
|
||||
return g[path]
|
||||
if _MOD_T_SEP not in path:
|
||||
return builtins.__dict__[path]
|
||||
modname, name = path.split(".")
|
||||
return __import__(modname).__dict__[name]
|
||||
modpath, name = path.split(_MOD_T_SEP)
|
||||
return __import__(modpath).__dict__[name]
|
||||
|
||||
def _find__new__(cls):
|
||||
while cls is not None:
|
||||
@ -26,11 +24,19 @@ class _Pickler:
|
||||
self.raw_memo = {} # id -> int
|
||||
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):
|
||||
if type(o) in _BASIC_TYPES:
|
||||
return o
|
||||
if type(o) is type:
|
||||
return ["type", o.__name__]
|
||||
return ["type", self._type_id(o)]
|
||||
|
||||
index = self.raw_memo.get(id(o), 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()])
|
||||
return [index]
|
||||
|
||||
_0 = o.__class__.__name__
|
||||
_0 = self._type_id(type(o))
|
||||
|
||||
if hasattr(o, "__getnewargs__"):
|
||||
_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])];
|
||||
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){
|
||||
return CAST(BoundMethod&, args[0]).self;
|
||||
});
|
||||
|
@ -131,7 +131,8 @@ namespace pkpy{
|
||||
PyTypeInfo info{
|
||||
obj,
|
||||
base,
|
||||
(mod!=nullptr && mod!=builtins) ? Str(OBJ_NAME(mod)+"."+name.sv()): name.sv(),
|
||||
mod,
|
||||
name.sv(),
|
||||
subclass_enabled,
|
||||
};
|
||||
if(mod != nullptr) mod->attr().set(name, obj);
|
||||
@ -636,8 +637,8 @@ void VM::_log_s_data(const char* title) {
|
||||
#endif
|
||||
|
||||
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(1)), 0, "type", false});
|
||||
_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, nullptr, "type", false});
|
||||
tp_object = 0; tp_type = 1;
|
||||
|
||||
tp_int = _new_type_object("int");
|
||||
|
@ -1,7 +1,9 @@
|
||||
from pickle import dumps, loads, _wrap, _unwrap
|
||||
|
||||
def test(x):
|
||||
ok = x == loads(dumps(x))
|
||||
y = dumps(x)
|
||||
# print(y.decode())
|
||||
ok = x == loads(y)
|
||||
if not ok:
|
||||
_0 = _wrap(x)
|
||||
_1 = _unwrap(_0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user