refactor __doc__ and rm __signature__

This commit is contained in:
blueloveTH 2024-04-16 23:06:43 +08:00
parent 9de8fee0a0
commit 0ec01abdeb
6 changed files with 14 additions and 58 deletions

View File

@ -112,8 +112,7 @@ struct FuncDecl {
int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
bool nested = false; // whether this function is nested bool nested = false; // whether this function is nested
Str signature; // signature of this function const char* docstring; // docstring of this function (weak ref)
Str docstring; // docstring of this function
FuncType type = FuncType::UNSET; FuncType type = FuncType::UNSET;

View File

@ -40,8 +40,7 @@ struct ClassMethod{
struct Property{ struct Property{
PyObject* getter; PyObject* getter;
PyObject* setter; PyObject* setter;
Str signature; Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {}
Property(PyObject* getter, PyObject* setter, Str signature) : getter(getter), setter(setter), signature(signature) {}
}; };
struct Range { struct Range {

View File

@ -1133,7 +1133,6 @@ __EAT_DOTS_END:
} }
void Compiler::compile_function(const Expr_vector& decorators){ void Compiler::compile_function(const Expr_vector& decorators){
const char* _start = curr().start;
consume(TK("@id")); consume(TK("@id"));
Str decl_name = prev().str(); Str decl_name = prev().str();
FuncDecl_ decl = push_f_context(decl_name); FuncDecl_ decl = push_f_context(decl_name);
@ -1143,23 +1142,18 @@ __EAT_DOTS_END:
consume(TK(")")); consume(TK(")"));
} }
if(match(TK("->"))) consume_type_hints(); if(match(TK("->"))) consume_type_hints();
const char* _end = curr().start;
if(_start && _end) decl->signature = Str(_start, _end-_start);
compile_block_body(); compile_block_body();
pop_context(); 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){ 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]; PyObject* c = decl->code->consts[decl->code->codes[0].arg];
if(is_type(c, vm->tp_str)){ if(is_type(c, vm->tp_str)){
decl->code->codes[0].op = OP_NO_OP; decl->code->codes[0].op = OP_NO_OP;
decl->code->codes[1].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); ctx()->emit_(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
_add_decorators(decorators); _add_decorators(decorators);

View File

@ -1455,42 +1455,25 @@ void init_builtins(VM* _vm) {
// tp_property // tp_property
_vm->bind_constructor<-1>(_vm->_t(VM::tp_property), [](VM* vm, ArgsView args) { _vm->bind_constructor<-1>(_vm->_t(VM::tp_property), [](VM* vm, ArgsView args) {
if(args.size() == 1+1){ 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){ }else if(args.size() == 1+2){
return VAR(Property(args[1], args[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 3 arguments"); vm->TypeError("property() takes at most 2 arguments");
return vm->None; 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) { _vm->bind_property(_vm->_t(VM::tp_function), "__doc__", [](VM* vm, ArgsView args) {
Function& func = _CAST(Function&, args[0]); Function& func = _CAST(Function&, args[0]);
if(!func.decl->docstring) return vm->None;
return VAR(func.decl->docstring); return VAR(func.decl->docstring);
}); });
_vm->bind_property(_vm->_t(VM::tp_native_func), "__doc__", [](VM* vm, ArgsView args) { _vm->bind_property(_vm->_t(VM::tp_native_func), "__doc__", [](VM* vm, ArgsView args) {
NativeFunc& func = _CAST(NativeFunc&, args[0]); NativeFunc& func = _CAST(NativeFunc&, args[0]);
if(func.decl != nullptr) return VAR(func.decl->docstring); if(func.decl == nullptr) return vm->None;
return VAR(""); if(!func.decl->docstring) return vm->None;
}); return VAR(func.decl->docstring);
_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("");
}); });
// tp_exception // tp_exception

View File

@ -1186,10 +1186,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
throw std::runtime_error("expected 1 function declaration"); throw std::runtime_error("expected 1 function declaration");
} }
FuncDecl_ decl = co->func_decls[0]; FuncDecl_ decl = co->func_decls[0];
decl->signature = Str(sig); decl->docstring = docstring;
if(docstring != nullptr){
decl->docstring = Str(docstring).strip();
}
PyObject* f_obj = VAR(NativeFunc(fn, decl)); PyObject* f_obj = VAR(NativeFunc(fn, decl));
PK_OBJ_GET(NativeFunc, f_obj).set_userdata(userdata); 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* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, false);
PyObject* _1 = vm->None; PyObject* _1 = vm->None;
if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false); if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
Str signature = name;
int pos = name.index(":"); int pos = name.index(":");
if(pos > 0) name = name.substr(0, pos).strip(); 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); obj->attr().set(name, prop);
return prop; return prop;
} }

View File

@ -335,7 +335,6 @@ assert type(s) is slice
assert s.start == 1 assert s.start == 1
assert s.stop == 2 assert s.stop == 2
assert s.step == 3 assert s.step == 3
assert slice.__dict__['start'].__signature__ == 'start'
# 未完全测试准确性----------------------------------------------- # 未完全测试准确性-----------------------------------------------
# test slice.__repr__ # test slice.__repr__
@ -489,16 +488,8 @@ class A():
self._name = val self._name = val
assert A().value == 2 assert A().value == 2
assert A.__dict__['value'].__signature__ == ''
A.name = property(A.get_name, A.set_name, "name: str") A.name = property(A.get_name, A.set_name)
assert A.__dict__['name'].__signature__ == 'name: str'
try:
property(A.get_name, A.set_name, 1)
print('未能拦截错误, 在测试 property')
exit(1)
except:
pass
class Vector2: class Vector2:
def __init__(self) -> None: def __init__(self) -> None:
@ -524,12 +515,6 @@ def aaa():
assert type(aaa.__doc__) is str assert type(aaa.__doc__) is str
# function.__signature__
def aaa():
pass
assert type(aaa.__signature__) is str
# /************ module time ************/ # /************ module time ************/
import time import time
# test time.time # test time.time