diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index bbe89617..74fcf0c7 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -31,8 +31,8 @@ struct BoundMethod { struct Property{ PyObject* getter; PyObject* setter; - Str type_hint; - Property(PyObject* getter, PyObject* setter, Str type_hint) : getter(getter), setter(setter), type_hint(type_hint) {} + Str signature; + Property(PyObject* getter, PyObject* setter, Str signature) : getter(getter), setter(setter), signature(signature) {} }; struct Range { diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 32616742..3999e7df 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1231,17 +1231,18 @@ void init_builtins(VM* _vm) { return VAR(Property(args[1], vm->None, "")); }else if(args.size() == 1+2){ return VAR(Property(args[1], args[2], "")); + }else if(args.size() == 1+3){ + return VAR(Property(args[1], args[2], CAST(Str, args[3]))); } - vm->TypeError("property() takes at most 2 arguments"); + vm->TypeError("property() takes at most 3 arguments"); return vm->None; }); - _vm->bind_property(_vm->_t(_vm->tp_property), "type_hint: str", [](VM* vm, ArgsView args){ + _vm->bind_property(_vm->_t(_vm->tp_property), "__signature__", [](VM* vm, ArgsView args){ Property& self = _CAST(Property&, args[0]); - return VAR(self.type_hint); + return VAR(self.signature); }); - _vm->bind_property(_vm->_t(_vm->tp_function), "__doc__", [](VM* vm, ArgsView args) { Function& func = _CAST(Function&, args[0]); return VAR(func.decl->docstring); @@ -1261,7 +1262,7 @@ void init_builtins(VM* _vm) { _vm->bind_property(_vm->_t(_vm->tp_native_func), "__signature__", [](VM* vm, ArgsView args) { NativeFunc& func = _CAST(NativeFunc&, args[0]); if(func.decl != nullptr) return VAR(func.decl->signature); - return VAR("unknown(*args, **kwargs)"); + return VAR(""); }); RangeIter::register_class(_vm, _vm->builtins); diff --git a/src/vm.cpp b/src/vm.cpp index 9bbd2f67..fe3b6b80 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -977,13 +977,10 @@ PyObject* VM::bind_property(PyObject* obj, Str name, NativeFuncC fget, NativeFun PyObject* _0 = heap.gcnew(tp_native_func, fget, 1, false); PyObject* _1 = vm->None; if(fset != nullptr) _1 = heap.gcnew(tp_native_func, fset, 2, false); - Str type_hint; + Str signature = name; int pos = name.index(":"); - if(pos > 0){ - type_hint = name.substr(pos + 1).strip(); - name = name.substr(0, pos).strip(); - } - PyObject* prop = VAR(Property(_0, _1, type_hint)); + if(pos > 0) name = name.substr(0, pos).strip(); + PyObject* prop = VAR(Property(_0, _1, signature)); obj->attr().set(name, prop); return prop; } diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index 3b80ff2d..c559c64c 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -747,10 +747,12 @@ assert type(slice(0.1, 0.2, 0.3)) is slice # 116: 1535: bind_property(_t(tp_slice), "step", [](VM* vm, ArgsView args){ # #####: 1536: return CAST(Slice&, args[0]).step; # -: 1537: }); -# test slice.start: -assert type(slice(0.1, 0.2, 0.3)) is slice -# test slice.stop: -# test slice.step: +s = slice(1, 2, 3) +assert type(s) is slice +assert s.start == 1 +assert s.stop == 2 +assert s.step == 3 +assert slice.__dict__['start'].__signature__ == 'start' # 未完全测试准确性----------------------------------------------- # 116: 957: _vm->bind__repr__(_vm->tp_slice, [](VM* vm, PyObject* obj) { @@ -984,6 +986,10 @@ class A(): def __init__(self): self._name = '123' + @property + def value(self): + return 2 + def get_name(self): ''' doc string 1 @@ -996,7 +1002,11 @@ class A(): ''' self._name = val -A.name = property(A.get_name, A.set_name) +assert A().value == 2 +assert A.__dict__['value'].__signature__ == '' + +A.name = property(A.get_name, A.set_name, "name: str") +assert A.__dict__['name'].__signature__ == 'name: str' try: property(A.get_name, A.set_name, 1) print('未能拦截错误, 在测试 property') @@ -1008,8 +1018,8 @@ except: import timeit def aaa(): - for i in range(1000): - for j in range(1000): + for i in range(100): + for j in range(100): pass assert type(timeit.timeit(aaa, 2)) is float @@ -1064,7 +1074,7 @@ assert type(time.time()) is float # #####: 1275: return vm->None; # #####: 1276: }); # test time.sleep -time.sleep(0.5) +time.sleep(0.1) # 未完全测试准确性----------------------------------------------- # 116: 1278: vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) {