diff --git a/include/pocketpy/codeobject.h b/include/pocketpy/codeobject.h index ac26e973..1117adcd 100644 --- a/include/pocketpy/codeobject.h +++ b/include/pocketpy/codeobject.h @@ -112,8 +112,7 @@ struct FuncDecl { int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg bool nested = false; // whether this function is nested - Str signature; // signature of this function - Str docstring; // docstring of this function + const char* docstring; // docstring of this function (weak ref) FuncType type = FuncType::UNSET; diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index 8391fa2b..e53015f4 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -40,8 +40,7 @@ struct ClassMethod{ struct Property{ PyObject* getter; PyObject* setter; - Str signature; - Property(PyObject* getter, PyObject* setter, Str signature) : getter(getter), setter(setter), signature(signature) {} + Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {} }; struct Range { diff --git a/src/compiler.cpp b/src/compiler.cpp index 3b085e05..9cd5e5d8 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -1133,7 +1133,6 @@ __EAT_DOTS_END: } void Compiler::compile_function(const Expr_vector& decorators){ - const char* _start = curr().start; consume(TK("@id")); Str decl_name = prev().str(); FuncDecl_ decl = push_f_context(decl_name); @@ -1143,23 +1142,18 @@ __EAT_DOTS_END: consume(TK(")")); } if(match(TK("->"))) consume_type_hints(); - const char* _end = curr().start; - if(_start && _end) decl->signature = Str(_start, _end-_start); compile_block_body(); pop_context(); - PyObject* docstring = nullptr; + decl->docstring = nullptr; if(decl->code->codes.size()>=2 && decl->code->codes[0].op == OP_LOAD_CONST && decl->code->codes[1].op == OP_POP_TOP){ PyObject* c = decl->code->consts[decl->code->codes[0].arg]; if(is_type(c, vm->tp_str)){ decl->code->codes[0].op = OP_NO_OP; decl->code->codes[1].op = OP_NO_OP; - docstring = c; + decl->docstring = PK_OBJ_GET(Str, c).c_str(); } } - if(docstring != nullptr){ - decl->docstring = PK_OBJ_GET(Str, docstring); - } ctx()->emit_(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line); _add_decorators(decorators); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index a5c367f2..a198d59f 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1455,42 +1455,25 @@ void init_builtins(VM* _vm) { // tp_property _vm->bind_constructor<-1>(_vm->_t(VM::tp_property), [](VM* vm, ArgsView args) { if(args.size() == 1+1){ - return VAR(Property(args[1], vm->None, "")); + 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]))); + return VAR(Property(args[1], args[2])); } - vm->TypeError("property() takes at most 3 arguments"); + vm->TypeError("property() takes at most 2 arguments"); return vm->None; }); - - // properties - _vm->bind_property(_vm->_t(VM::tp_property), "__signature__", [](VM* vm, ArgsView args){ - Property& self = _CAST(Property&, args[0]); - return VAR(self.signature); - }); _vm->bind_property(_vm->_t(VM::tp_function), "__doc__", [](VM* vm, ArgsView args) { Function& func = _CAST(Function&, args[0]); + if(!func.decl->docstring) return vm->None; return VAR(func.decl->docstring); }); _vm->bind_property(_vm->_t(VM::tp_native_func), "__doc__", [](VM* vm, ArgsView args) { NativeFunc& func = _CAST(NativeFunc&, args[0]); - if(func.decl != nullptr) return VAR(func.decl->docstring); - return VAR(""); - }); - - _vm->bind_property(_vm->_t(VM::tp_function), "__signature__", [](VM* vm, ArgsView args) { - Function& func = _CAST(Function&, args[0]); - return VAR(func.decl->signature); - }); - - _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(""); + if(func.decl == nullptr) return vm->None; + if(!func.decl->docstring) return vm->None; + return VAR(func.decl->docstring); }); // tp_exception diff --git a/src/vm.cpp b/src/vm.cpp index 6bb2875d..94dde907 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1186,10 +1186,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native throw std::runtime_error("expected 1 function declaration"); } FuncDecl_ decl = co->func_decls[0]; - decl->signature = Str(sig); - if(docstring != nullptr){ - decl->docstring = Str(docstring).strip(); - } + decl->docstring = docstring; PyObject* f_obj = VAR(NativeFunc(fn, decl)); PK_OBJ_GET(NativeFunc, f_obj).set_userdata(userdata); @@ -1211,10 +1208,9 @@ 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 signature = name; int pos = name.index(":"); if(pos > 0) name = name.substr(0, pos).strip(); - PyObject* prop = VAR(Property(_0, _1, signature)); + PyObject* prop = VAR(Property(_0, _1)); obj->attr().set(name, prop); return prop; } diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index afe89381..084830a3 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -335,7 +335,6 @@ assert type(s) is slice assert s.start == 1 assert s.stop == 2 assert s.step == 3 -assert slice.__dict__['start'].__signature__ == 'start' # 未完全测试准确性----------------------------------------------- # test slice.__repr__ @@ -489,16 +488,8 @@ class A(): self._name = val 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') - exit(1) -except: - pass +A.name = property(A.get_name, A.set_name) class Vector2: def __init__(self) -> None: @@ -524,12 +515,6 @@ def aaa(): assert type(aaa.__doc__) is str -# function.__signature__ -def aaa(): - pass -assert type(aaa.__signature__) is str - - # /************ module time ************/ import time # test time.time