mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
fb83748e02
commit
b13581037d
@ -270,11 +270,8 @@ type.__repr__ = lambda self: "<class '" + self.__name__ + "'>"
|
|||||||
def help(obj):
|
def help(obj):
|
||||||
if hasattr(obj, '__func__'):
|
if hasattr(obj, '__func__'):
|
||||||
obj = obj.__func__
|
obj = obj.__func__
|
||||||
if hasattr(obj, '__doc__'):
|
print(obj.__signature__)
|
||||||
print(obj.__doc__)
|
print(obj.__doc__)
|
||||||
else:
|
|
||||||
print("No docstring found")
|
|
||||||
|
|
||||||
|
|
||||||
del __f
|
del __f
|
||||||
|
|
||||||
|
12
src/c.pyi
12
src/c.pyi
@ -65,12 +65,24 @@ class void_p:
|
|||||||
def set_base_offset(self, offset: str) -> None: ...
|
def set_base_offset(self, offset: str) -> None: ...
|
||||||
|
|
||||||
class struct:
|
class struct:
|
||||||
|
@overload
|
||||||
|
def __init__(self, size: int): ...
|
||||||
|
@overload
|
||||||
|
def __init__(self, p: 'void_p', size: int): ...
|
||||||
|
@overload
|
||||||
|
def __init__(self, s: str): ...
|
||||||
|
@overload
|
||||||
|
def __init__(self, b: bytes): ...
|
||||||
|
|
||||||
def addr(self) -> 'void_p': ...
|
def addr(self) -> 'void_p': ...
|
||||||
def copy(self) -> 'struct': ...
|
def copy(self) -> 'struct': ...
|
||||||
def size(self) -> int: ...
|
def size(self) -> int: ...
|
||||||
def __eq__(self, other: 'struct') -> bool: ...
|
def __eq__(self, other: 'struct') -> bool: ...
|
||||||
def __ne__(self, other: 'struct') -> bool: ...
|
def __ne__(self, other: 'struct') -> bool: ...
|
||||||
|
|
||||||
|
def to_string(self) -> str: ...
|
||||||
|
def to_bytes(self) -> bytes: ...
|
||||||
|
|
||||||
def read_char(self, offset=0) -> int: ...
|
def read_char(self, offset=0) -> int: ...
|
||||||
def read_uchar(self, offset=0) -> int: ...
|
def read_uchar(self, offset=0) -> int: ...
|
||||||
def read_short(self, offset=0) -> int: ...
|
def read_short(self, offset=0) -> int: ...
|
||||||
|
@ -11,7 +11,6 @@ inline PyObject* VM::_run_top_frame(){
|
|||||||
DEF_SNAME(set);
|
DEF_SNAME(set);
|
||||||
DEF_SNAME(__enter__);
|
DEF_SNAME(__enter__);
|
||||||
DEF_SNAME(__exit__);
|
DEF_SNAME(__exit__);
|
||||||
DEF_SNAME(__doc__);
|
|
||||||
|
|
||||||
FrameId frame = top_frame();
|
FrameId frame = top_frame();
|
||||||
const int base_id = frame.index;
|
const int base_id = frame.index;
|
||||||
@ -674,9 +673,6 @@ __NEXT_STEP:;
|
|||||||
TARGET(RE_RAISE) _raise(); DISPATCH();
|
TARGET(RE_RAISE) _raise(); DISPATCH();
|
||||||
TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH();
|
TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
TARGET(SETUP_DOCSTRING)
|
|
||||||
TOP()->attr().set(__doc__, co_consts[byte.arg]);
|
|
||||||
DISPATCH();
|
|
||||||
TARGET(FORMAT_STRING) {
|
TARGET(FORMAT_STRING) {
|
||||||
_0 = POPX();
|
_0 = POPX();
|
||||||
const Str& spec = CAST(Str&, co_consts[byte.arg]);
|
const Str& spec = CAST(Str&, co_consts[byte.arg]);
|
||||||
|
57
src/cffi.h
57
src/cffi.h
@ -191,7 +191,7 @@ struct C99Struct{
|
|||||||
char* p;
|
char* p;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
void _init(int new_size){
|
C99Struct(int new_size){
|
||||||
this->size = new_size;
|
this->size = new_size;
|
||||||
if(size <= INLINE_SIZE){
|
if(size <= INLINE_SIZE){
|
||||||
p = _inlined;
|
p = _inlined;
|
||||||
@ -201,27 +201,46 @@ struct C99Struct{
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
C99Struct(const T& data){
|
C99Struct(const T& data): C99Struct(sizeof(T)){
|
||||||
static_assert(std::is_pod_v<T>);
|
static_assert(std::is_pod_v<T>);
|
||||||
static_assert(!std::is_pointer_v<T>);
|
static_assert(!std::is_pointer_v<T>);
|
||||||
_init(sizeof(T));
|
|
||||||
memcpy(p, &data, this->size);
|
memcpy(p, &data, this->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
C99Struct() { p = _inlined; }
|
C99Struct(void* p, int size): C99Struct(size){
|
||||||
C99Struct(void* p, int size){
|
if(p != nullptr) memcpy(this->p, p, size);
|
||||||
_init(size);
|
|
||||||
if(p!=nullptr) memcpy(this->p, p, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C99Struct(const C99Struct& other): C99Struct(other.p, other.size){}
|
||||||
|
|
||||||
~C99Struct(){ if(p!=_inlined) free(p); }
|
~C99Struct(){ if(p!=_inlined) free(p); }
|
||||||
|
|
||||||
C99Struct(const C99Struct& other){
|
|
||||||
_init(other.size);
|
|
||||||
memcpy(p, other.p, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
vm->bind_default_constructor<C99Struct>(type);
|
vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
|
||||||
|
if(args.size() == 1+1){
|
||||||
|
if(is_int(args[1])){
|
||||||
|
int size = _CAST(int, args[1]);
|
||||||
|
return VAR_T(C99Struct, size);
|
||||||
|
}
|
||||||
|
if(is_non_tagged_type(args[1], vm->tp_str)){
|
||||||
|
const Str& s = _CAST(Str&, args[1]);
|
||||||
|
return VAR_T(C99Struct, (void*)s.data, s.size);
|
||||||
|
}
|
||||||
|
if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
||||||
|
const Bytes& b = _CAST(Bytes&, args[1]);
|
||||||
|
return VAR_T(C99Struct, (void*)b.data(), b.size());
|
||||||
|
}
|
||||||
|
vm->TypeError("expected int, str or bytes");
|
||||||
|
return vm->None;
|
||||||
|
}
|
||||||
|
if(args.size() == 1+2){
|
||||||
|
void* p = CAST(void*, args[1]);
|
||||||
|
int size = CAST(int, args[2]);
|
||||||
|
return VAR_T(C99Struct, p, size);
|
||||||
|
}
|
||||||
|
vm->TypeError("expected 1 or 2 arguments");
|
||||||
|
return vm->None;
|
||||||
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||||
@ -238,6 +257,18 @@ struct C99Struct{
|
|||||||
return VAR_T(C99Struct, self);
|
return VAR_T(C99Struct, self);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vm->bind_method<0>(type, "to_string", [](VM* vm, ArgsView args){
|
||||||
|
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||||
|
return VAR(Str(self.p, self.size));
|
||||||
|
});
|
||||||
|
|
||||||
|
vm->bind_method<0>(type, "to_bytes", [](VM* vm, ArgsView args){
|
||||||
|
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||||
|
std::vector<char> buffer(self.size);
|
||||||
|
memcpy(buffer.data(), self.p, self.size);
|
||||||
|
return VAR(Bytes(std::move(buffer)));
|
||||||
|
});
|
||||||
|
|
||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
||||||
C99Struct& self = _CAST(C99Struct&, lhs);
|
C99Struct& self = _CAST(C99Struct&, lhs);
|
||||||
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
||||||
|
@ -972,9 +972,9 @@ __SUBSCR_END:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void compile_function(const std::vector<Expr_>& decorators={}){
|
void compile_function(const std::vector<Expr_>& decorators={}){
|
||||||
Str decl_name;
|
const char* _start = curr().start;
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
decl_name = prev().str();
|
Str decl_name = prev().str();
|
||||||
FuncDecl_ decl = push_f_context(decl_name);
|
FuncDecl_ decl = push_f_context(decl_name);
|
||||||
consume(TK("("));
|
consume(TK("("));
|
||||||
if (!match(TK(")"))) {
|
if (!match(TK(")"))) {
|
||||||
@ -982,6 +982,8 @@ __SUBSCR_END:
|
|||||||
consume(TK(")"));
|
consume(TK(")"));
|
||||||
}
|
}
|
||||||
if(match(TK("->"))) consume_type_hints();
|
if(match(TK("->"))) consume_type_hints();
|
||||||
|
const char* _end = curr().start;
|
||||||
|
decl->signature = Str(_start, _end-_start);
|
||||||
compile_block_body();
|
compile_block_body();
|
||||||
pop_context();
|
pop_context();
|
||||||
|
|
||||||
@ -994,10 +996,11 @@ __SUBSCR_END:
|
|||||||
docstring = c;
|
docstring = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
|
|
||||||
if(docstring != nullptr){
|
if(docstring != nullptr){
|
||||||
ctx()->emit(OP_SETUP_DOCSTRING, ctx()->add_const(docstring), prev().line);
|
decl->docstring = PK_OBJ_GET(Str, docstring);
|
||||||
}
|
}
|
||||||
|
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
|
||||||
|
|
||||||
// add decorators
|
// add decorators
|
||||||
for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
|
for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
|
||||||
(*it)->emit(ctx());
|
(*it)->emit(ctx());
|
||||||
|
18
src/main.cpp
18
src/main.cpp
@ -7,11 +7,25 @@
|
|||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
pkpy::VM* vm = pkpy_new_vm();
|
pkpy::VM* vm = pkpy_new_vm();
|
||||||
pkpy::PyObject* input_f = vm->bind_builtin_func<0>("input", [](pkpy::VM* vm, pkpy::ArgsView args){
|
vm->bind_builtin_func<0>("input", [](pkpy::VM* vm, pkpy::ArgsView args){
|
||||||
// pkpy::getline() has bugs for PIPE input on Windows
|
// pkpy::getline() has bugs for PIPE input on Windows
|
||||||
return VAR(pkpy::getline());
|
return VAR(pkpy::getline());
|
||||||
});
|
});
|
||||||
vm->_modules["sys"]->attr("stdin")->attr().set("readline", input_f);
|
|
||||||
|
// vm->bind(vm->builtins, "test_sum(a: int, b: int, *args, x=5)",
|
||||||
|
// "Test function for summing up numbers.",
|
||||||
|
// [](pkpy::VM* vm, pkpy::ArgsView args){
|
||||||
|
// PK_ASSERT(args.size() == 4);
|
||||||
|
// int sum = 0;
|
||||||
|
// sum += pkpy::CAST(int, args[0]);
|
||||||
|
// sum += pkpy::CAST(int, args[1]);
|
||||||
|
// pkpy::Tuple& t = pkpy::CAST(pkpy::Tuple&, args[2]);
|
||||||
|
// for(pkpy::PyObject* ob: t){
|
||||||
|
// sum += pkpy::CAST(int, ob);
|
||||||
|
// }
|
||||||
|
// sum *= pkpy::CAST(int, args[3]);
|
||||||
|
// return VAR(sum);
|
||||||
|
// });
|
||||||
if(argc == 1){
|
if(argc == 1){
|
||||||
pkpy::REPL* repl = pkpy_new_repl(vm);
|
pkpy::REPL* repl = pkpy_new_repl(vm);
|
||||||
bool need_more_lines = false;
|
bool need_more_lines = false;
|
||||||
|
@ -30,6 +30,9 @@ struct FuncDecl {
|
|||||||
int starred_arg = -1; // index in co->varnames, -1 if no *arg
|
int starred_arg = -1; // index in co->varnames, -1 if no *arg
|
||||||
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
|
||||||
|
Str docstring; // docstring of this function
|
||||||
void _gc_mark() const;
|
void _gc_mark() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,7 +46,6 @@ struct NativeFunc {
|
|||||||
|
|
||||||
// new style decl-based call
|
// new style decl-based call
|
||||||
FuncDecl_ decl;
|
FuncDecl_ decl;
|
||||||
const char* docstring;
|
|
||||||
|
|
||||||
using UserData = char[32];
|
using UserData = char[32];
|
||||||
UserData _userdata;
|
UserData _userdata;
|
||||||
@ -75,11 +77,10 @@ struct NativeFunc {
|
|||||||
_has_userdata = false;
|
_has_userdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeFunc(NativeFuncC f, FuncDecl_ decl, const char* docstring){
|
NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
||||||
this->f = f;
|
this->f = f;
|
||||||
this->argc = -1;
|
this->argc = -1;
|
||||||
this->decl = decl;
|
this->decl = decl;
|
||||||
this->docstring = docstring;
|
|
||||||
_has_userdata = false;
|
_has_userdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,6 @@ OPCODE(RAISE)
|
|||||||
OPCODE(RE_RAISE)
|
OPCODE(RE_RAISE)
|
||||||
OPCODE(POP_EXCEPTION)
|
OPCODE(POP_EXCEPTION)
|
||||||
/**************************/
|
/**************************/
|
||||||
OPCODE(SETUP_DOCSTRING)
|
|
||||||
OPCODE(FORMAT_STRING)
|
OPCODE(FORMAT_STRING)
|
||||||
/**************************/
|
/**************************/
|
||||||
OPCODE(INC_FAST)
|
OPCODE(INC_FAST)
|
||||||
|
@ -559,16 +559,6 @@ inline void init_builtins(VM* _vm) {
|
|||||||
return VAR(ss.str());
|
return VAR(ss.str());
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<0>("str", "to_c_str", [](VM* vm, ArgsView args){
|
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
|
||||||
return VAR(self.c_str_dup());
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bind_func<1>("str", "from_c_str", [](VM* vm, ArgsView args){
|
|
||||||
char* p = CAST(char*, args[0]);
|
|
||||||
return VAR(Str(p));
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bind_method<0>("str", "lower", [](VM* vm, ArgsView args) {
|
_vm->bind_method<0>("str", "lower", [](VM* vm, ArgsView args) {
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
return VAR(self.lower());
|
return VAR(self.lower());
|
||||||
@ -907,21 +897,6 @@ inline void init_builtins(VM* _vm) {
|
|||||||
return VAR(Str(self.str()));
|
return VAR(Str(self.str()));
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<0>("bytes", "to_char_array", [](VM* vm, ArgsView args) {
|
|
||||||
const Bytes& self = _CAST(Bytes&, args[0]);
|
|
||||||
void* buffer = malloc(self.size());
|
|
||||||
memcpy(buffer, self.data(), self.size());
|
|
||||||
return VAR_T(VoidP, buffer);
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bind_func<2>("bytes", "from_char_array", [](VM* vm, ArgsView args) {
|
|
||||||
const VoidP& data = _CAST(VoidP&, args[0]);
|
|
||||||
int size = CAST(int, args[1]);
|
|
||||||
std::vector<char> buffer(size);
|
|
||||||
memcpy(buffer.data(), data.ptr, size);
|
|
||||||
return VAR(Bytes(std::move(buffer)));
|
|
||||||
});
|
|
||||||
|
|
||||||
_vm->bind__eq__(_vm->tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) {
|
_vm->bind__eq__(_vm->tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) {
|
||||||
if(!is_non_tagged_type(rhs, vm->tp_bytes)) return vm->NotImplemented;
|
if(!is_non_tagged_type(rhs, vm->tp_bytes)) return vm->NotImplemented;
|
||||||
return VAR(_CAST(Bytes&, lhs) == _CAST(Bytes&, rhs));
|
return VAR(_CAST(Bytes&, lhs) == _CAST(Bytes&, rhs));
|
||||||
@ -1175,6 +1150,28 @@ inline void init_builtins(VM* _vm) {
|
|||||||
vm->TypeError("property() takes at most 2 arguments");
|
vm->TypeError("property() takes at most 2 arguments");
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_vm->_t(_vm->tp_function)->attr().set("__doc__", _vm->property([](VM* vm, ArgsView args) {
|
||||||
|
Function& func = _CAST(Function&, args[0]);
|
||||||
|
return VAR(func.decl->docstring);
|
||||||
|
}));
|
||||||
|
|
||||||
|
_vm->_t(_vm->tp_native_func)->attr().set("__doc__", _vm->property([](VM* vm, ArgsView args) {
|
||||||
|
NativeFunc& func = _CAST(NativeFunc&, args[0]);
|
||||||
|
if(func.decl != nullptr) return VAR(func.decl->docstring);
|
||||||
|
return VAR("");
|
||||||
|
}));
|
||||||
|
|
||||||
|
_vm->_t(_vm->tp_function)->attr().set("__signature__", _vm->property([](VM* vm, ArgsView args) {
|
||||||
|
Function& func = _CAST(Function&, args[0]);
|
||||||
|
return VAR(func.decl->signature);
|
||||||
|
}));
|
||||||
|
|
||||||
|
_vm->_t(_vm->tp_native_func)->attr().set("__signature__", _vm->property([](VM* vm, ArgsView args) {
|
||||||
|
NativeFunc& func = _CAST(NativeFunc&, args[0]);
|
||||||
|
if(func.decl != nullptr) return VAR(func.decl->signature);
|
||||||
|
return VAR("unknown(*args, **kwargs)");
|
||||||
|
}));
|
||||||
|
|
||||||
RangeIter::register_class(_vm, _vm->builtins);
|
RangeIter::register_class(_vm, _vm->builtins);
|
||||||
ArrayIter::register_class(_vm, _vm->builtins);
|
ArrayIter::register_class(_vm, _vm->builtins);
|
||||||
@ -1288,10 +1285,8 @@ inline void add_module_sys(VM* vm){
|
|||||||
|
|
||||||
PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
||||||
PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
||||||
PyObject* stdin_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
|
|
||||||
vm->setattr(mod, "stdout", stdout_);
|
vm->setattr(mod, "stdout", stdout_);
|
||||||
vm->setattr(mod, "stderr", stderr_);
|
vm->setattr(mod, "stderr", stderr_);
|
||||||
vm->setattr(mod, "stdin", stdin_);
|
|
||||||
|
|
||||||
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
|
vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
|
||||||
vm->_stdout(vm, CAST(Str&, args[0]));
|
vm->_stdout(vm, CAST(Str&, args[0]));
|
||||||
|
11
src/str.h
11
src/str.h
@ -228,6 +228,17 @@ struct Str{
|
|||||||
return Str(copy);
|
return Str(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Str strip() const {
|
||||||
|
std::string copy(data, size);
|
||||||
|
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) {
|
||||||
|
return c != ' ' && c != '\t' && c != '\r' && c != '\n';
|
||||||
|
}));
|
||||||
|
copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](char c) {
|
||||||
|
return c != ' ' && c != '\t' && c != '\r' && c != '\n';
|
||||||
|
}).base(), copy.end());
|
||||||
|
return Str(copy);
|
||||||
|
}
|
||||||
|
|
||||||
Str lower() const{
|
Str lower() const{
|
||||||
std::string copy(data, size);
|
std::string copy(data, size);
|
||||||
std::transform(copy.begin(), copy.end(), copy.begin(), [](unsigned char c){ return std::tolower(c); });
|
std::transform(copy.begin(), copy.end(), copy.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||||
|
6
src/vm.h
6
src/vm.h
@ -1561,7 +1561,11 @@ inline PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring,
|
|||||||
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];
|
||||||
PyObject* f_obj = VAR(NativeFunc(fn, decl, docstring));
|
decl->signature = Str(sig);
|
||||||
|
if(docstring != nullptr){
|
||||||
|
decl->docstring = Str(docstring).strip();
|
||||||
|
}
|
||||||
|
PyObject* f_obj = VAR(NativeFunc(fn, decl));
|
||||||
obj->attr().set(decl->code->name, f_obj);
|
obj->attr().set(decl->code->name, f_obj);
|
||||||
return f_obj;
|
return f_obj;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user