Skip to content

Commit a8efa7b

Browse files
committed
add tests
1 parent afdfd74 commit a8efa7b

File tree

9 files changed

+528
-48
lines changed

9 files changed

+528
-48
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
# SOFTWARE.
3737

3838
import sys
39+
from string import Formatter
3940
os = sys.modules.get("posix", sys.modules.get("nt", None))
4041
if os is None:
4142
raise ImportError("posix or nt module is required in builtin modules")
@@ -97,13 +98,13 @@ def ccompile(self, name):
9798
if (!PyArg_ParseTuple(___arg, "{argspec}", {derefargumentnames})) {{
9899
return NULL;
99100
}}
100-
}}
101+
}}
101102
#ifdef SINGLEARG
102103
else {{
103104
{singleargumentname} = ___arg;
104105
}}
105106
#endif
106-
107+
107108
return Py_BuildValue("{resultspec}", {callfunction}({argumentnames}));
108109
}}
109110
@@ -145,7 +146,7 @@ def ccompile(self, name):
145146
if (!PyArg_ParseTuple(___arg, "{argspec}", {derefargumentnames})) {{
146147
return NULL;
147148
}}
148-
}}
149+
}}
149150
#ifdef SINGLEARG
150151
else {{
151152
{singleargumentname} = ___arg;
@@ -197,12 +198,12 @@ def ccompile(self, name):
197198
return NULL;
198199
}}
199200
}}
200-
#ifdef SINGLEARG
201+
#ifdef SINGLEARG
201202
else {{
202203
{singleargumentname} = ___arg;
203204
}}
204205
#endif
205-
206+
206207
res = {callfunction}({argumentnames}{resultvarlocations});
207208
208209
return Py_BuildValue("{resultspec}", res {resultvarnames});
@@ -305,7 +306,6 @@ def test(self):
305306
cresult = ctest(cargs[i])
306307
except BaseException as e:
307308
cresult = e
308-
309309
try:
310310
presult = self.pfunc(pargs[i])
311311
except BaseException as e:
@@ -376,4 +376,135 @@ def create_module(self, name=None):
376376
super(CPyExtFunctionVoid, self).create_module(name)
377377

378378

379+
class UnseenFormatter(Formatter):
380+
def get_value(self, key, args, kwds):
381+
if isinstance(key, str):
382+
try:
383+
return kwds[key]
384+
except KeyError:
385+
return 0
386+
else:
387+
return Formatter.get_value(key, args, kwds)
388+
389+
390+
def CPyExtType(name, code, **kwargs):
391+
template = """
392+
#include "Python.h"
393+
394+
{code}
395+
396+
static PyNumberMethods {name}_number_methods = {{
397+
{nb_add},
398+
{nb_subtract},
399+
{nb_multiply},
400+
{nb_remainder},
401+
{nb_divmod},
402+
{nb_power},
403+
{nb_negative},
404+
{nb_positive},
405+
{nb_absolute},
406+
{nb_bool},
407+
{nb_invert},
408+
{nb_lshift},
409+
{nb_rshift},
410+
{nb_and},
411+
{nb_xor},
412+
{nb_or},
413+
{nb_int},
414+
{nb_reserved},
415+
{nb_float},
416+
{nb_inplace_add},
417+
{nb_inplace_subtract},
418+
{nb_inplace_multiply},
419+
{nb_inplace_remainder},
420+
{nb_inplace_power},
421+
{nb_inplace_lshift},
422+
{nb_inplace_rshift},
423+
{nb_inplace_and},
424+
{nb_inplace_xor},
425+
{nb_inplace_or},
426+
{nb_floor_divide},
427+
{nb_true_divide},
428+
{nb_inplace_floor_divide},
429+
{nb_inplace_true_divide},
430+
{nb_index},
431+
{nb_matrix_multiply},
432+
{nb_inplace_matrix_multiply},
433+
}};
434+
435+
typedef struct {{
436+
PyObject_HEAD
437+
}} {name}Object;
438+
439+
static PyTypeObject {name}Type = {{
440+
PyVarObject_HEAD_INIT(NULL, 0)
441+
"{name}.{name}",
442+
sizeof({name}Object), /* tp_basicsize */
443+
0, /* tp_itemsize */
444+
0, /* tp_dealloc */
445+
{tp_print},
446+
{tp_getattr},
447+
{tp_setattr},
448+
0, /* tp_reserved */
449+
{tp_repr},
450+
&{name}_number_methods,
451+
{tp_as_sequence},
452+
{tp_as_mapping},
453+
{tp_hash},
454+
{tp_call},
455+
{tp_str},
456+
{tp_getattro},
457+
{tp_setattro},
458+
{tp_as_buffer},
459+
Py_TPFLAGS_DEFAULT,
460+
"",
461+
}};
462+
463+
static PyModuleDef {name}module = {{
464+
PyModuleDef_HEAD_INIT,
465+
"{name}",
466+
"",
467+
-1,
468+
NULL, NULL, NULL, NULL, NULL
469+
}};
470+
471+
PyMODINIT_FUNC
472+
PyInit_{name}(void)
473+
{{
474+
PyObject* m;
475+
476+
{name}Type.tp_new = PyType_GenericNew;
477+
{ready_code}
478+
if (PyType_Ready(&{name}Type) < 0)
479+
return NULL;
480+
481+
m = PyModule_Create(&{name}module);
482+
if (m == NULL)
483+
return NULL;
484+
485+
Py_INCREF(&{name}Type);
486+
PyModule_AddObject(m, "{name}", (PyObject *)&{name}Type);
487+
return m;
488+
}}
489+
"""
490+
491+
kwargs["name"] = name
492+
kwargs["code"] = code
493+
kwargs.setdefault("ready_code", "")
494+
c_source = UnseenFormatter().format(template, **kwargs)
495+
496+
with open("%s/%s.c" % (__dir__, name), "wb", buffering=0) as f:
497+
if GRAALPYTHON:
498+
f.write(c_source)
499+
else:
500+
f.write(bytes(c_source, 'utf-8'))
501+
ccompile(None, name)
502+
sys.path.insert(0, __dir__)
503+
try:
504+
cmodule = __import__(name)
505+
finally:
506+
sys.path.pop(0)
507+
return getattr(cmodule, name)
508+
509+
379510
CPyExtTestCase.compile_module = ccompile

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def _reference_next(args):
8484
return next(iterObj)
8585
except BaseException:
8686
raise SystemError
87-
87+
8888

8989
def _reference_size(args):
9090
seq = args[0]
@@ -180,31 +180,52 @@ def _default_bin_arith_args():
180180
)
181181

182182

183+
def _default_unarop_args():
184+
return (
185+
(0,),
186+
(-1,),
187+
(0.1,),
188+
(-1.3,),
189+
(False,),
190+
(True,),
191+
("hello",),
192+
((1,2,3),),
193+
(0x7fffffff,),
194+
(0xffffffffffffffffffffffffffffffff,),
195+
(DummyIntable(),),
196+
(DummyIntSubclass(),),
197+
(NoNumber(),),
198+
(DummyFloatable(),),
199+
(DummyFloatSubclass(),),
200+
)
201+
202+
183203
class TestAbstract(CPyExtTestCase):
184204
def compile_module(self, name):
185205
type(self).mro()[1].__dict__["test_%s" % name].create_module(name)
186206
super(TestAbstract, self).compile_module(name)
187207

208+
test_PyNumber_Absolute = CPyExtFunction(
209+
lambda args: abs(args[0]),
210+
_default_unarop_args,
211+
resultspec="O",
212+
argspec='O',
213+
arguments=["PyObject* v"],
214+
cmpfunc=unhandled_error_compare
215+
)
216+
217+
test_PyNumber_Invert = CPyExtFunction(
218+
lambda args: ~(args[0]),
219+
_default_unarop_args,
220+
resultspec="O",
221+
argspec='O',
222+
arguments=["PyObject* v"],
223+
cmpfunc=unhandled_error_compare
224+
)
188225

189226
test_PyNumber_Check = CPyExtFunction(
190227
_reference_checknumber,
191-
lambda: (
192-
(0,),
193-
(-1,),
194-
(0.1,),
195-
(-1.3,),
196-
(False,),
197-
(True,),
198-
("hello",),
199-
((1,2,3),),
200-
(0x7fffffff,),
201-
(0xffffffffffffffffffffffffffffffff,),
202-
(DummyIntable(),),
203-
(DummyIntSubclass(),),
204-
(NoNumber(),),
205-
(DummyFloatable(),),
206-
(DummyFloatSubclass(),),
207-
),
228+
_default_unarop_args,
208229
resultspec="i",
209230
argspec='O',
210231
arguments=["PyObject* v"],
@@ -308,6 +329,15 @@ def compile_module(self, name):
308329
cmpfunc=unhandled_error_compare
309330
)
310331

332+
test_PyNumber_Divmod = CPyExtFunction(
333+
lambda args: divmod(args[0], args[1]),
334+
_default_bin_arith_args,
335+
resultspec="O",
336+
argspec='OO',
337+
arguments=["PyObject* v", "PyObject* w"],
338+
cmpfunc=unhandled_error_compare
339+
)
340+
311341
test_PyNumber_Remainder = CPyExtFunction(
312342
lambda args: args[0] % args[1],
313343
_default_bin_arith_args,
@@ -534,7 +564,7 @@ def compile_module(self, name):
534564
PyObject* result = PyList_New(n);
535565
for (i = 0; i < n; i++) {
536566
PyList_SetItem(result, i, items[i]);
537-
}
567+
}
538568
return result;
539569
}
540570
''',
@@ -558,7 +588,7 @@ def compile_module(self, name):
558588
int i;
559589
for (i = 0; i < n - 1; i++) {
560590
PyIter_Next(iter);
561-
}
591+
}
562592
return PyIter_Next(iter);
563593
}
564594
''',
@@ -607,7 +637,7 @@ def compile_module(self, name):
607637
arguments=["PyObject* sequence"],
608638
cmpfunc=unhandled_error_compare
609639
)
610-
640+
611641
# 'PySequence_Length' is just a redefinition of 'PySequence_Size'
612642
test_PySequence_Length = test_PySequence_Size
613643

@@ -726,4 +756,3 @@ def compile_module(self, name):
726756
arguments=["PyObject* obj"],
727757
cmpfunc=unhandled_error_compare
728758
)
729-

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_capsule.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,37 @@ def compile_module(self, name):
6262
callfunction="wrap_PyCapsule_Check",
6363
cmpfunc=unhandled_error_compare
6464
)
65+
66+
test_PyCapsule_GetPointer = CPyExtFunction(
67+
lambda args: True,
68+
lambda: (
69+
("hello", 0xDEADBEEF),
70+
),
71+
code='''int wrap_PyCapsule_Check(char * name, Py_ssize_t ptr) {
72+
PyObject* capsule = PyCapsule_New((void *)ptr, name, NULL);
73+
return PyCapsule_GetPointer(capsule, name) == (void*)ptr;
74+
}
75+
''',
76+
resultspec="i",
77+
argspec='sn',
78+
arguments=["char* name", "Py_ssize_t ptr"],
79+
callfunction="wrap_PyCapsule_Check",
80+
cmpfunc=unhandled_error_compare
81+
)
82+
83+
test_PyCapsule_GetContext = CPyExtFunction(
84+
lambda args: True,
85+
lambda: (
86+
("hello", 0xDEADBEEF),
87+
),
88+
code='''int wrap_PyCapsule_Check(char * name, Py_ssize_t ptr) {
89+
PyObject* capsule = PyCapsule_New((void *)ptr, name, NULL);
90+
return PyCapsule_GetContext(capsule) == NULL;
91+
}
92+
''',
93+
resultspec="i",
94+
argspec='sn',
95+
arguments=["char* name", "Py_ssize_t ptr"],
96+
callfunction="wrap_PyCapsule_Check",
97+
cmpfunc=unhandled_error_compare
98+
)

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -358,18 +358,3 @@ def setattrstring(args):
358358
# )
359359
# test_PyObject_Init = CPyExtFunction(
360360
# )
361-
362-
test_PyCallable_Check = CPyExtFunction(
363-
lambda args: callable(args[0]),
364-
lambda: (
365-
(len,),
366-
(sum,),
367-
(int,),
368-
("hello",),
369-
(3,),
370-
(None,),
371-
),
372-
arguments=["PyObject* callable"],
373-
resultspec="i",
374-
argspec="O",
375-
)

0 commit comments

Comments
 (0)