Skip to content

Commit 459da8a

Browse files
committed
support '__getattribute__()'
support `__getattr__()` disable proxy for PIKA_NANO_ENABLE fix typo support `__setattr__()` proxy for cmodule is ok
1 parent 52995e6 commit 459da8a

File tree

9 files changed

+353
-44
lines changed

9 files changed

+353
-44
lines changed

port/linux/.vscode/launch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"program": "${workspaceFolder}/build/test/pikascript_test",
1212
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
1313
"args": [
14-
// "--gtest_filter=stddata.list_pop_"
14+
// "--gtest_filter=vm.getattribute"
1515
],
1616
"stopAtEntry": false,
1717
"cwd": "${workspaceFolder}",

port/linux/.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"agile_modbus.h": "c",
6666
"_modbus__modbusrtu.h": "c",
6767
"_modbus__modbustcp.h": "c",
68-
"pikastddata_string.h": "c"
68+
"pikastddata_string.h": "c",
69+
"gtesttask_proxytest.h": "c"
6970
}
7071
}

port/linux/package/pikascript/GTestTask.pyi

+5
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ class Task(PikaStdTask.Task):
1414
def test(a: int, b: object): ...
1515
def test_dict() -> dict: ...
1616
def test64(a: int64, b: int64) -> int64: ...
17+
18+
19+
class ProxyTest:
20+
def __getattribute__(self, __name: str) -> any: ...
21+
def __setattr__(self, __name: str, __value: any): ...

port/linux/package/pikascript/pikascript-lib/GTestTask/GTestTask.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "GTestTask.h"
2+
#include "GTestTask_ProxyTest.h"
23
#include "GTestTask_Task.h"
34
#include "PikaStdData_Dict.h"
45

@@ -38,6 +39,17 @@ PikaObj* GTestTask_test_dict(PikaObj* self) {
3839
return dict;
3940
}
4041

41-
int64_t GTestTask_test64(PikaObj *self, int64_t a, int64_t b){
42+
int64_t GTestTask_test64(PikaObj* self, int64_t a, int64_t b) {
4243
return a * b;
4344
}
45+
46+
Arg* GTestTask_ProxyTest___getattribute__(PikaObj* self, char* __name) {
47+
return arg_newStr(__name);
48+
}
49+
50+
void GTestTask_ProxyTest___setattr__(PikaObj* self,
51+
char* __name,
52+
Arg* __value) {
53+
__platform_printf("GTestTask_ProxyTest___setattr__: %s, %s\r\n", __name,
54+
arg_getStr(__value));
55+
}

port/linux/test/VM-test.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -1781,4 +1781,104 @@ TEST(vm, call_dict_err) {
17811781
obj_deinit(pikaMain);
17821782
EXPECT_EQ(pikaMemNow(), 0);
17831783
}
1784+
1785+
TEST(vm, getattribute) {
1786+
/* init */
1787+
pikaMemInfo.heapUsedMax = 0;
1788+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1789+
extern unsigned char pikaModules_py_a[];
1790+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1791+
/* run */
1792+
__platform_printf("BEGIN\r\n");
1793+
obj_run(pikaMain,
1794+
"class test:\n"
1795+
" def __getattribute__(self, name):\n"
1796+
" return name\n"
1797+
"t = test()\n"
1798+
"t.a\n");
1799+
/* collect */
1800+
/* assert */
1801+
EXPECT_STREQ(log_buff[0], "'a'\r\n");
1802+
/* deinit */
1803+
obj_deinit(pikaMain);
1804+
EXPECT_EQ(pikaMemNow(), 0);
1805+
}
1806+
1807+
TEST(vm, getattr) {
1808+
/* init */
1809+
pikaMemInfo.heapUsedMax = 0;
1810+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1811+
extern unsigned char pikaModules_py_a[];
1812+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1813+
/* run */
1814+
__platform_printf("BEGIN\r\n");
1815+
obj_run(pikaMain,
1816+
"class test:\n"
1817+
" a = 1\n"
1818+
" def __getattr__(self, name):\n"
1819+
" return name\n"
1820+
"t = test()\n"
1821+
"t.a\n"
1822+
"t.b\n");
1823+
/* collect */
1824+
/* assert */
1825+
EXPECT_STREQ(log_buff[0], "'b'\r\n");
1826+
EXPECT_STREQ(log_buff[1], "1\r\n");
1827+
EXPECT_STREQ(log_buff[2], "BEGIN\r\n");
1828+
/* deinit */
1829+
obj_deinit(pikaMain);
1830+
EXPECT_EQ(pikaMemNow(), 0);
1831+
}
1832+
1833+
TEST(vm, setattr) {
1834+
/* init */
1835+
pikaMemInfo.heapUsedMax = 0;
1836+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1837+
extern unsigned char pikaModules_py_a[];
1838+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1839+
/* run */
1840+
__platform_printf("BEGIN\r\n");
1841+
obj_run(pikaMain,
1842+
"class test:\n"
1843+
" a = 1\n"
1844+
" def __setattr__(self, name, val):\n"
1845+
" print((name, val))\n"
1846+
"t = test()\n"
1847+
"t.a = 1\n"
1848+
"t.b = 'test'\n");
1849+
/* collect */
1850+
/* assert */
1851+
EXPECT_STREQ(log_buff[2], "BEGIN\r\n");
1852+
EXPECT_STREQ(log_buff[1], "('a', 1)\r\n");
1853+
EXPECT_STREQ(log_buff[0], "('b', 'test')\r\n");
1854+
/* deinit */
1855+
obj_deinit(pikaMain);
1856+
EXPECT_EQ(pikaMemNow(), 0);
1857+
}
1858+
1859+
TEST(vm, c_module_get_set_attr) {
1860+
/* init */
1861+
pikaMemInfo.heapUsedMax = 0;
1862+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1863+
extern unsigned char pikaModules_py_a[];
1864+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1865+
/* run */
1866+
__platform_printf("BEGIN\r\n");
1867+
obj_run(pikaMain,
1868+
"t = GTestTask.ProxyTest()\n"
1869+
"t.a\n"
1870+
"t.b\n"
1871+
"t.a = 'test1'\n"
1872+
"t.b = 'test2'\n");
1873+
/* collect */
1874+
/* assert */
1875+
EXPECT_STREQ(log_buff[3], "'a'\r\n");
1876+
EXPECT_STREQ(log_buff[2], "'b'\r\n");
1877+
EXPECT_STREQ(log_buff[1], "GTestTask_ProxyTest___setattr__: a, test1\r\n");
1878+
EXPECT_STREQ(log_buff[0], "GTestTask_ProxyTest___setattr__: b, test2\r\n");
1879+
/* deinit */
1880+
obj_deinit(pikaMain);
1881+
EXPECT_EQ(pikaMemNow(), 0);
1882+
}
1883+
17841884
#endif

port/linux/test/compile-test.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -622,3 +622,21 @@ TEST(compiler, __list) {
622622
Parser_linesToArray(lines);
623623
EXPECT_EQ(pikaMemNow(), 0);
624624
}
625+
626+
TEST(compiler, getattr) {
627+
char* lines = "@res = __getattribute__(@name)";
628+
Parser_linesToArray(lines);
629+
EXPECT_EQ(pikaMemNow(), 0);
630+
}
631+
632+
TEST(compiler, getattr2) {
633+
char* lines = "@res = __getattr__(@name)";
634+
Parser_linesToArray(lines);
635+
EXPECT_EQ(pikaMemNow(), 0);
636+
}
637+
638+
TEST(compiler, setattr) {
639+
char* lines = "__setattr__(@name, @value)";
640+
Parser_linesToArray(lines);
641+
EXPECT_EQ(pikaMemNow(), 0);
642+
}

src/PikaObj.c

+35-8
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,15 @@ int64_t obj_getInt(PikaObj* self, char* argPath) {
197197
}
198198

199199
Arg* obj_getArg(PikaObj* self, char* argPath) {
200-
PIKA_BOOL isClass = PIKA_FALSE;
201-
PikaObj* obj = obj_getHostObjWithIsTemp(self, argPath, &isClass);
200+
PIKA_BOOL is_temp = PIKA_FALSE;
201+
PikaObj* obj = obj_getHostObjWithIsTemp(self, argPath, &is_temp);
202202
if (NULL == obj) {
203203
return NULL;
204204
}
205+
Arg* res = NULL;
205206
char* argName = strPointToLastToken(argPath, '.');
206-
Arg* res = args_getArg(obj->list, argName);
207-
if (isClass) {
207+
res = args_getArg(obj->list, argName);
208+
if (is_temp) {
208209
obj_setArg(self, "_buf", res);
209210
res = obj_getArg(self, "_buf");
210211
obj_deinit(obj);
@@ -520,13 +521,13 @@ static PikaObj* __obj_getObjWithKeepDeepth(PikaObj* self,
520521
}
521522

522523
PikaObj* obj_getObj(PikaObj* self, char* objPath) {
523-
PIKA_BOOL isClass = PIKA_FALSE;
524-
return __obj_getObjWithKeepDeepth(self, objPath, &isClass, 0);
524+
PIKA_BOOL is_temp = PIKA_FALSE;
525+
return __obj_getObjWithKeepDeepth(self, objPath, &is_temp, 0);
525526
}
526527

527528
PikaObj* obj_getHostObj(PikaObj* self, char* objPath) {
528-
PIKA_BOOL isClass = PIKA_FALSE;
529-
return __obj_getObjWithKeepDeepth(self, objPath, &isClass, 1);
529+
PIKA_BOOL is_temp = PIKA_FALSE;
530+
return __obj_getObjWithKeepDeepth(self, objPath, &is_temp, 1);
530531
}
531532

532533
PikaObj* obj_getHostObjWithIsTemp(PikaObj* self,
@@ -594,6 +595,30 @@ PikaObj* methodArg_getDefContext(Arg* method_arg) {
594595
return context;
595596
}
596597

598+
void _update_proxy(PikaObj* self, char* name) {
599+
#if PIKA_NANO_ENABLE
600+
return;
601+
#endif
602+
if (!(self->proxy & PIKA_PROXY_GETATTRIBUTE)) {
603+
if (strEqu(name, "__getattribute__")) {
604+
self->proxy |= PIKA_PROXY_GETATTRIBUTE;
605+
return;
606+
}
607+
}
608+
if (!(self->proxy & PIKA_PROXY_GETATTR)) {
609+
if (strEqu(name, "__getattr__")) {
610+
self->proxy |= PIKA_PROXY_GETATTR;
611+
return;
612+
}
613+
}
614+
if (!(self->proxy & PIKA_PROXY_SETATTR)) {
615+
if (strEqu(name, "__setattr__")) {
616+
self->proxy |= PIKA_PROXY_SETATTR;
617+
return;
618+
}
619+
}
620+
}
621+
597622
static void obj_saveMethodInfo(PikaObj* self, MethodInfo* method_info) {
598623
Args buffs = {0};
599624
method_info->pars = method_info->dec;
@@ -612,6 +637,7 @@ static void obj_saveMethodInfo(PikaObj* self, MethodInfo* method_info) {
612637
sizeof(method_info_def_context));
613638
arg = arg_append(arg, method_info->pars, size_pars + 1);
614639

640+
_update_proxy(self, method_info->name);
615641
args_setArg(self->list, arg);
616642
strsDeinit(&buffs);
617643
}
@@ -1001,6 +1027,7 @@ PikaObj* New_PikaObj(void) {
10011027
self->list = New_args(NULL);
10021028
self->refcnt = 0;
10031029
self->constructor = NULL;
1030+
self->proxy = 0;
10041031
return self;
10051032
}
10061033

src/PikaObj.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ struct PikaObj {
7171
Args* list;
7272
uint8_t refcnt;
7373
void* constructor;
74+
uint8_t proxy;
7475
};
7576

77+
#define PIKA_PROXY_GETATTRIBUTE 0x01
78+
#define PIKA_PROXY_GETATTR 0x02
79+
#define PIKA_PROXY_SETATTR 0x04
80+
7681
typedef PikaObj* (*NewFun)(Args* args);
7782
typedef PikaObj* (*InitFun)(PikaObj* self, Args* args);
7883
typedef PikaObj VMParameters;
@@ -128,8 +133,8 @@ int32_t obj_addOther(PikaObj* self, char* subObjectName, void* new_projcetFun);
128133
PikaObj* obj_getObj(PikaObj* self, char* objPath);
129134
PikaObj* obj_getHostObj(PikaObj* self, char* objPath);
130135
PikaObj* obj_getHostObjWithIsTemp(PikaObj* self,
131-
char* objPath,
132-
PIKA_BOOL* pIsClass);
136+
char* objPath,
137+
PIKA_BOOL* pIsClass);
133138

134139
// subProcess
135140
int32_t obj_freeObj(PikaObj* self, char* subObjectName);

0 commit comments

Comments
 (0)