Skip to content

Commit 0016e79

Browse files
committed
Complete 'PySequence_*' C API functions.
1 parent 192c4d1 commit 0016e79

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

graalpython/com.oracle.graal.python.cext/src/abstract.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,52 @@ PyObject * PyIter_Next(PyObject *iter) {
208208
}
209209
return to_sulong(result);
210210
}
211+
212+
int PySequence_Check(PyObject *s) {
213+
if (s == NULL) {
214+
return 0;
215+
}
216+
return polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PySequence_Check", to_java(s)));
217+
}
218+
219+
Py_ssize_t PySequence_Size(PyObject *s) {
220+
return polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PyObject_Size", to_java(s)));
221+
}
222+
223+
// taken from CPython "Objects/abstract.c"
224+
#undef PySequence_Length
225+
Py_ssize_t PySequence_Length(PyObject *s) {
226+
return PySequence_Size(s);
227+
}
228+
#define PySequence_Length PySequence_Size
229+
230+
PyObject* PySequence_GetItem(PyObject *s, Py_ssize_t i)
231+
{
232+
void* result = polyglot_invoke(PY_TRUFFLE_CEXT, "PyObject_GetItem", to_java(s), i, ERROR_MARKER);
233+
if(result == ERROR_MARKER) {
234+
return NULL;
235+
}
236+
return to_sulong(result);
237+
}
238+
239+
int PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) {
240+
return polyglot_as_i32(polyglot_invoke(PY_TRUFFLE_CEXT, "PyObject_SetItem", to_java(s), i, to_java(o)));
241+
}
242+
243+
PyObject* PySequence_Tuple(PyObject *v) {
244+
void* result = polyglot_invoke(PY_TRUFFLE_CEXT, "PySequence_Tuple", to_java(v), ERROR_MARKER);
245+
if(result == ERROR_MARKER) {
246+
return NULL;
247+
}
248+
return to_sulong(result);
249+
}
250+
251+
PyObject *
252+
PySequence_Fast(PyObject *v, const char *m)
253+
{
254+
void* result = polyglot_invoke(PY_TRUFFLE_CEXT, "PySequence_Fast", to_java(v), polyglot_from_string(m, "ascii"), ERROR_MARKER);
255+
if(result == ERROR_MARKER) {
256+
return NULL;
257+
}
258+
return to_sulong(result);
259+
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ def __float__(self):
110110
return 2.71828
111111

112112

113+
class DummySequence():
114+
def __getitem__(self, idx):
115+
return idx * 10
116+
117+
118+
class DummyListSubclass(list):
119+
pass
120+
121+
113122
def _default_bin_arith_args():
114123
return (
115124
(0,0),
@@ -531,3 +540,24 @@ def compile_module(self, name):
531540
cmpfunc=unhandled_error_compare
532541
)
533542

543+
test_PySequence_Check = CPyExtFunction(
544+
lambda args: not isinstance(args[0], dict) and hasattr(args[0], '__getitem__'),
545+
lambda: (
546+
(tuple(),),
547+
((1,2,3),),
548+
((None,),),
549+
([],),
550+
(['a','b','c'],),
551+
([None],),
552+
(dict(),),
553+
(set(),),
554+
({'a', 'b'},),
555+
({'a':0, 'b':1},),
556+
(DummySequence(),),
557+
(DummyListSubclass(),),
558+
),
559+
resultspec="i",
560+
argspec='O',
561+
arguments=["PyObject* sequence"],
562+
)
563+

graalpython/lib-graalpython/python_cext.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,43 @@ def PyIter_Next(itObj, error_marker):
462462
return error_marker
463463

464464

465+
##################### SEQUENCE
466+
467+
468+
def PySequence_Tuple(obj, error_marker):
469+
typ = val = tb = None
470+
try:
471+
return tuple(obj)
472+
except BaseException:
473+
typ, val, tb = sys.exc_info()
474+
PyErr_Restore(typ, val, tb)
475+
return error_marker
476+
477+
478+
def PySequence_Fast(obj, msg, error_marker):
479+
typ = val = tb = None
480+
if isinstance(obj, tuple) or isinstance(obj, list):
481+
return obj
482+
try:
483+
return list(obj)
484+
except TypeError:
485+
try:
486+
raise TypeError(msg)
487+
except TypeError:
488+
typ, val, tb = sys.exc_info()
489+
except BaseException:
490+
typ, val, tb = sys.exc_info()
491+
PyErr_Restore(typ, val, tb)
492+
return error_marker
493+
494+
495+
def PySequence_Check(obj):
496+
# dictionaries are explicitly excluded
497+
if isinstance(obj, dict):
498+
return False
499+
return hasattr(obj, '__getitem__')
500+
501+
465502
##################### UNICODE
466503

467504

0 commit comments

Comments
 (0)