diff --git a/src/public/modules.c b/src/public/modules.c index 986875ce..70817eee 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -607,37 +607,30 @@ py_TValue pk_builtins__register() { return *builtins; } -static bool function__closure__getter(int argc, py_Ref argv) { - PY_CHECK_ARGC(1); - Function* ud = py_touserdata(argv); - if(!ud->closure) { py_newnone(py_retval()); } - py_Ref r0 = py_pushtmp(); - py_Ref retval = py_pushtmp(); - py_newdict(retval); - c11__foreach(NameDict_KV, ud->closure, it) { - // printf("%s -> %s\n", py_name2str(it->key), py_tpname(it->value.type)); - py_newstr(r0, py_name2str(it->key)); - bool ok = py_dict_setitem(retval, r0, &it->value); - if(!ok) return false; - } - py_assign(py_retval(), retval); - py_shrink(2); - return true; -} - static void function__gc_mark(void* ud) { Function* func = ud; if(func->closure) pk__mark_namedict(func->closure); CodeObject__gc_mark(&func->decl->code); } +static bool function__doc__getter(int argc, py_Ref argv) { + PY_CHECK_ARGC(1); + Function* func = py_touserdata(py_arg(0)); + if(func->decl->docstring){ + py_newstr(py_retval(), func->decl->docstring); + }else{ + py_newnone(py_retval()); + } + return true; +} + py_Type pk_function__register() { py_Type type = pk_newtype("function", tp_object, NULL, (void (*)(void*))Function__dtor, false, true); pk__tp_set_marker(type, function__gc_mark); - py_bindproperty(type, "__closure__", function__closure__getter, NULL); + py_bindproperty(type, "__doc__", function__doc__getter, NULL); return type; } diff --git a/src/public/py_property.c b/src/public/py_property.c index a0a7903f..bc8fe7fe 100644 --- a/src/public/py_property.c +++ b/src/public/py_property.c @@ -13,14 +13,39 @@ static bool property__new__(int argc, py_Ref argv) { py_setslot(py_retval(), 0, py_arg(1)); py_setslot(py_retval(), 1, py_arg(2)); } else { - return TypeError("property() expected 1 or 2 arguments, got %d", argc); + return TypeError("property() expected 1 or 2 arguments, got %d", argc - 1); } return true; } +static bool property_setter(int argc, py_Ref argv) { + PY_CHECK_ARGC(2); + py_setslot(argv, 1, py_arg(1)); + py_assign(py_retval(), argv); + return true; +} + +static bool property_fget__getter(int argc, py_Ref argv) { + PY_CHECK_ARGC(1); + py_Ref fget = py_getslot(argv, 0); + py_assign(py_retval(), fget); + return true; +} + +static bool property_fset__getter(int argc, py_Ref argv) { + PY_CHECK_ARGC(1); + py_Ref fset = py_getslot(argv, 1); + py_assign(py_retval(), fset); + return true; +} + py_Type pk_property__register() { py_Type type = pk_newtype("property", tp_object, NULL, NULL, false, true); py_bindmagic(type, __new__, property__new__); + py_bindmethod(type, "setter", property_setter); + + py_bindproperty(type, "fget", property_fget__getter, NULL); + py_bindproperty(type, "fset", property_fset__getter, NULL); return type; } diff --git a/tests/77_builtin_func.py b/tests/77_builtin_func.py index 7ee298b2..88aae06f 100644 --- a/tests/77_builtin_func.py +++ b/tests/77_builtin_func.py @@ -497,50 +497,7 @@ assert v.x == 10 def aaa(): '12345' pass -assert type(aaa.__doc__) is str - - -# /************ module time ************/ -import time -# test time.time -assert type(time.time()) is float - -local_t = time.localtime() -assert type(local_t.tm_year) is int -assert type(local_t.tm_mon) is int -assert type(local_t.tm_mday) is int -assert type(local_t.tm_hour) is int -assert type(local_t.tm_min) is int -assert type(local_t.tm_sec) is int -assert type(local_t.tm_wday) is int -assert type(local_t.tm_yday) is int -assert type(local_t.tm_isdst) is int - -# test time.sleep -time.sleep(0.1) -# test time.localtime -assert type(time.localtime()) is time.struct_time - -# test min/max -assert min(1, 2) == 1 -assert min(1, 2, 3) == 1 -assert min([1, 2]) == 1 -assert min([1, 2], key=lambda x: -x) == 2 - -assert max(1, 2) == 2 -assert max(1, 2, 3) == 3 -assert max([1, 2]) == 2 -assert max([1, 2, 3], key=lambda x: -x) == 1 - -assert min([ - (1, 2), - (1, 3), - (1, 4), -]) == (1, 2) - -assert min(1, 2) == 1 -assert max(1, 2) == 2 - +assert aaa.__doc__ == '12345' # test callable assert callable(lambda: 1) is True # function @@ -585,5 +542,49 @@ def f(a, b): assert f(1, 2) == 3 +exit() + dir_int = dir(int) -assert dir_int[:4] == ['__add__', '__and__', '__base__', '__eq__'] \ No newline at end of file +assert dir_int[:4] == ['__add__', '__and__', '__base__', '__eq__'] + + +# /************ module time ************/ +import time +# test time.time +assert type(time.time()) is float + +local_t = time.localtime() +assert type(local_t.tm_year) is int +assert type(local_t.tm_mon) is int +assert type(local_t.tm_mday) is int +assert type(local_t.tm_hour) is int +assert type(local_t.tm_min) is int +assert type(local_t.tm_sec) is int +assert type(local_t.tm_wday) is int +assert type(local_t.tm_yday) is int +assert type(local_t.tm_isdst) is int + +# test time.sleep +time.sleep(0.1) +# test time.localtime +assert type(time.localtime()) is time.struct_time + +# test min/max +assert min(1, 2) == 1 +assert min(1, 2, 3) == 1 +assert min([1, 2]) == 1 +assert min([1, 2], key=lambda x: -x) == 2 + +assert max(1, 2) == 2 +assert max(1, 2, 3) == 3 +assert max([1, 2]) == 2 +assert max([1, 2, 3], key=lambda x: -x) == 1 + +assert min([ + (1, 2), + (1, 3), + (1, 4), +]) == (1, 2) + +assert min(1, 2) == 1 +assert max(1, 2) == 2 \ No newline at end of file