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
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;

View File

@ -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 {

View File

@ -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);

View File

@ -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

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");
}
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;
}

View File

@ -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