Skip to content

Commit 2ae65fd

Browse files
committed
[GR-34916] Intrinsity python_cext - PySet/Bytes/List_XXX.
PullRequest: graalpython/2047
2 parents 8faa685 + f52bf9a commit 2ae65fd

File tree

12 files changed

+1203
-236
lines changed

12 files changed

+1203
-236
lines changed

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ def _reference_from_string_n(args):
4848
arg_n = args[1]
4949
return bytes(arg_str[0:arg_n], "utf-8")
5050

51+
def _reference_from_object(args):
52+
obj = args[0]
53+
if type(obj) == bytes:
54+
return obj
55+
if isinstance(obj, (list, tuple, memoryview)) or (not isinstance(obj, str) and hasattr(obj, "__iter__")):
56+
return bytes(obj)
57+
raise TypeError("cannot convert '%s' object to bytes" % type(obj).__name__)
58+
5159

5260
def _as_string_and_size(args):
5361
arg_bytes = args[0]
@@ -60,6 +68,9 @@ def _reference_format(args):
6068
fmt_args = tuple(args[1:])
6169
return (fmt % fmt_args).encode()
6270

71+
class CIter:
72+
def __iter__(self):
73+
return iter([1, 2, 3])
6374

6475
class TestPyBytes(CPyExtTestCase):
6576

@@ -148,10 +159,25 @@ def compile_module(self, name):
148159
argspec="sssi",
149160
arguments=["char* fmt", "char* arg0", "char* arg1", "int arg2"],
150161
)
162+
163+
# PyBytes_FromObject
164+
test_PyBytes_FromObject = CPyExtFunction(
165+
_reference_from_object,
166+
lambda: (("hello", ),
167+
(bytes(1), ),
168+
(1, ),
169+
([1, 2, 4], ),
170+
((1, 2, 3), ),
171+
(memoryview(b'abc'), ),
172+
(CIter(),)),
173+
resultspec="O",
174+
argspec="O",
175+
cmpfunc=unhandled_error_compare
176+
)
151177

152178
# PyBytes_Concat
153179
test_PyBytes_Concat = CPyExtFunctionOutVars(
154-
lambda args: (0, args[0] + args[1]),
180+
lambda args: (0, args[0] + args[1]),
155181
lambda: tuple([tuple(["hello".encode(), " world".encode()])]),
156182
code='''int wrap_PyBytes_Concat(PyObject** arg0, PyObject* arg1) {
157183
if(*arg0) {
@@ -280,6 +306,17 @@ def compile_module(self, name):
280306
cmpfunc=unhandled_error_compare
281307
)
282308

309+
test__PyBytes_Join = CPyExtFunction(
310+
lambda args: args[0].join(args[1]),
311+
lambda: (
312+
(b"hello", b"world"),
313+
),
314+
resultspec="O",
315+
argspec="OO",
316+
arguments=["PyObject* original", "PyObject* newPart"],
317+
cmpfunc=unhandled_error_compare
318+
)
319+
283320
test_PyBytes_Resize_NativeStorage = CPyExtFunction(
284321
lambda args: args[1],
285322
lambda: (

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ def compile_module(self, name):
323323
# PyDict_Next
324324
test_PyDict_Next = CPyExtFunctionOutVars(
325325
_reference_next,
326-
# lambda: (({'a': "hello"}, 0), ({'a': "hello", 'b': 'world'}, 1), ({'a': "hello"}, 1)),
327-
lambda: (({'a': "hello"}, 1),),
326+
lambda: (({'a': "hello"}, 1), ({'a': "hello"}, 0), ({'a': "hello", 'b': 'world'}, 1), ({'a': "hello"}, 1)),
328327
code='''int wrap_PyDict_Next(PyObject* dict, Py_ssize_t* ppos, PyObject** key, PyObject** value) {
329328
int res = 0;
330329
Py_ssize_t iterations = *ppos;
@@ -366,7 +365,7 @@ def compile_module(self, name):
366365
PyObject* value;
367366
Py_hash_t phash;
368367
369-
_PyDict_Next(dict, &ppos, &key, &value, &phash);
368+
_PyDict_Next(dict, &ppos, &key, &value, &phash);
370369
_PyDict_SetItem_KnownHash(result, key, value, phash);
371370
return result;
372371
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
__dir__ = __file__.rpartition("/")[0]
4343

4444

45+
def raise_Py6_SystemError():
46+
if sys.version_info.minor >= 6:
47+
raise SystemError
48+
else:
49+
return -1
50+
4551
def _reference_new_list(args):
4652
n = args[0]
4753
if n < 0:
@@ -67,6 +73,14 @@ def _reference_setitem(args):
6773
listObj[pos] = newitem
6874
return listObj
6975

76+
def _reference_setslice(args):
77+
if not isinstance(args[0], list):
78+
raise_Py6_SystemError()
79+
try:
80+
args[0][args[1]:args[2]] = args[3]
81+
return 0;
82+
except:
83+
return raise_Py6_SystemError()
7084

7185
def _reference_reverse(args):
7286
args[0].reverse()
@@ -257,6 +271,20 @@ def compile_module(self, name):
257271
arguments=["PyObject* op", "Py_ssize_t ilow", "Py_ssize_t ihigh"],
258272
cmpfunc=unhandled_error_compare
259273
)
274+
275+
test_PyList_SetSlice = CPyExtFunction(
276+
_reference_setslice,
277+
lambda: (
278+
([1,2,3,4],0,4,[5,6,7,8]),
279+
([],1,2, [5,6]),
280+
([1,2,3,4],10,20,[5,6,7,8]),
281+
(DummyClass(),10,20, [1]),
282+
),
283+
resultspec="i",
284+
argspec='OnnO',
285+
arguments=["PyObject* op", "Py_ssize_t ilow", "Py_ssize_t ihigh", "PyObject* v"],
286+
cmpfunc=unhandled_error_compare
287+
)
260288

261289
test_PyList_Size = CPyExtFunction(
262290
lambda args: len(args[0]),

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

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,38 @@ def _reference_clear(args):
6363
return args[0]
6464

6565

66+
def _reference_next(args):
67+
try:
68+
s = args[0]
69+
i = 0
70+
for k in s:
71+
if i == args[1]:
72+
return (1, k, hash(k))
73+
i = i + 1
74+
return (0, None, 0)
75+
except:
76+
return (0, None, 0)
77+
78+
def _reference_pop(args):
79+
try:
80+
s = args[0]
81+
return s.pop()
82+
except AttributeError:
83+
return raise_Py6_SystemError()
84+
85+
def _reference_discard(args):
86+
try:
87+
s = args[0]
88+
if not (isinstance(s, set)):
89+
raise SystemError
90+
91+
if args[1] in s:
92+
s.discard(args[1])
93+
return 1
94+
return 0
95+
except AttributeError:
96+
return raise_Py6_SystemError()
97+
6698
class FrozenSetSubclass(frozenset):
6799
pass
68100

@@ -229,3 +261,71 @@ def compile_module(self, name):
229261
cmpfunc=unhandled_error_compare
230262
)
231263

264+
test_PySet_NextEntry = CPyExtFunctionOutVars(
265+
_reference_next,
266+
lambda: ((set(),1),
267+
(set([1, 2, 3]),1),
268+
(set({'a', 'b'}),1),
269+
(frozenset([1, 2, 3]),1),
270+
(frozenset({'a', 'b'}),1),
271+
(frozenset([None]),1),
272+
(FrozenSetSubclass(),1),
273+
(SetSubclass([None]),1),),
274+
code='''int wrap_PySet_NextEntry(PyObject* set, Py_ssize_t* ppos, PyObject **key, Py_hash_t* hash) {
275+
int res = 0;
276+
Py_ssize_t iterations = *ppos;
277+
Py_ssize_t i;
278+
*ppos = 0;
279+
for(i=0; i < iterations; i++) {
280+
_PySet_NextEntry(set, ppos, key, hash);
281+
}
282+
res = _PySet_NextEntry(set, ppos, key, hash);
283+
if (!res) {
284+
// avoid problems when building the result value
285+
*key = set;
286+
*hash = 0;
287+
Py_INCREF(set);
288+
}
289+
return res;
290+
}
291+
''',
292+
resultspec="iOn",
293+
argspec='On',
294+
arguments=("PyObject* set", "Py_ssize_t ppos"),
295+
resulttype="int",
296+
argumentnames=("set, &ppos"),
297+
resultvars=("PyObject* key", "Py_hash_t hash"),
298+
callfunction="wrap_PySet_NextEntry",
299+
cmpfunc=lambda x, y: type(x) == tuple and type(y) == tuple and len(x) == 3 and len(y) == 3 and (x[0] == 0 and y[0] == 0 or x == y)
300+
)
301+
302+
# PySet_Pop
303+
test_PySet_Pop = CPyExtFunction(
304+
_reference_pop,
305+
lambda: ((set(),),
306+
(set([1, 2, 3]),),
307+
(set({'a', 'b'}),),
308+
(frozenset([1, 2, 3]),),
309+
(FrozenSetSubclass(),),
310+
(SetSubclass([None]),),),
311+
resultspec="O",
312+
argspec='O',
313+
cmpfunc=unhandled_error_compare
314+
)
315+
316+
# PySet_Discard
317+
test_PySet_Discard = CPyExtFunction(
318+
_reference_discard,
319+
lambda: ((set(),1),
320+
(set([1, 2, 3]),1),
321+
(set([1, 2, 3]),None),
322+
(set({'a', 'b'}),1),
323+
(frozenset([1, 2, 3]),1),
324+
(FrozenSetSubclass(),1),
325+
(SetSubclass([None]),1)),
326+
resultspec="i",
327+
argspec='OO',
328+
arguments=("PyObject* set", "PyObject* key"),
329+
argumentnames=("set, key"),
330+
cmpfunc=unhandled_error_compare
331+
)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ protected static boolean isSubtypeOfFloat(VirtualFrame frame, IsSubtypeNode isSu
966966
// frozenset([iterable])
967967
@Builtin(name = FROZENSET, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PFrozenSet)
968968
@GenerateNodeFactory
969-
public abstract static class FrozenSetNode extends PythonBuiltinNode {
969+
public abstract static class FrozenSetNode extends PythonBinaryBuiltinNode {
970970

971971
@Specialization(guards = "isNoValue(arg)")
972972
public PFrozenSet frozensetEmpty(Object cls, @SuppressWarnings("unused") PNone arg) {
@@ -3168,7 +3168,7 @@ Object initArgs(Object cls, Object[] args, @SuppressWarnings("unused") PKeyword[
31683168

31693169
@Builtin(name = "mappingproxy", constructsClass = PythonBuiltinClassType.PMappingproxy, isPublic = false, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
31703170
@GenerateNodeFactory
3171-
public abstract static class MappingproxyNode extends PythonBuiltinNode {
3171+
public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode {
31723172
@Specialization(guards = "!isNoValue(obj)")
31733173
Object doMapping(Object klass, Object obj,
31743174
@Cached PyMappingCheckNode mappingCheckNode) {

0 commit comments

Comments
 (0)