Explorar o código

refactor `__doc__` and rm `__signature__`

blueloveTH hai 1 ano
pai
achega
0ec01abdeb
Modificáronse 6 ficheiros con 14 adicións e 58 borrados
  1. 1 2
      include/pocketpy/codeobject.h
  2. 1 2
      include/pocketpy/obj.h
  3. 2 8
      src/compiler.cpp
  4. 7 24
      src/pocketpy.cpp
  5. 2 6
      src/vm.cpp
  6. 1 16
      tests/99_builtin_func.py

+ 1 - 2
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;
 

+ 1 - 2
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 {

+ 2 - 8
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);

+ 7 - 24
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

+ 2 - 6
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<NativeFunc>(tp_native_func, fget, 1, false);
     PyObject* _1 = vm->None;
     if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(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;
 }

+ 1 - 16
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