Skip to content

Commit e122c8a

Browse files
committed
Implement C API function 'PyIter_Next'.
1 parent 5f85b39 commit e122c8a

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,12 @@ PyObject * PyNumber_Float(PyObject *o) {
199199
}
200200
return to_sulong(result);
201201
}
202+
203+
PyObject * PyIter_Next(PyObject *iter) {
204+
void* result = polyglot_invoke(PY_TRUFFLE_CEXT, "PyIter_Next", to_java(iter), ERROR_MARKER);
205+
if (result == ERROR_MARKER && PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration)) {
206+
PyErr_Clear();
207+
return NULL;
208+
}
209+
return to_sulong(result);
210+
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ def _reference_asssize_t(args):
7575
return -1
7676

7777

78+
def _reference_next(args):
79+
iterObj = args[0]
80+
n = args[1]
81+
try:
82+
for i in range(n-1):
83+
next(iterObj)
84+
return next(iterObj)
85+
except BaseException:
86+
raise SystemError
87+
88+
7889
class NoNumber():
7990
pass
8091

@@ -495,3 +506,27 @@ def compile_module(self, name):
495506
arguments=["PyObject* sequence"],
496507
)
497508

509+
test_PyIter_Next = CPyExtFunction(
510+
_reference_next,
511+
lambda: (
512+
(iter((1,2,3)),0),
513+
(iter((1,2,3)),3),
514+
(iter((None,)),1),
515+
(iter([]),1),
516+
(iter(['a','b','c']),2),
517+
(iter({'a':0,'b':1,'c':2}),2)
518+
),
519+
code='''PyObject* wrap_PyIter_Next(PyObject* iter, int n) {
520+
for (int i = 0; i < n - 1; i++) {
521+
PyIter_Next(iter);
522+
}
523+
return PyIter_Next(iter);
524+
}
525+
''',
526+
resultspec="O",
527+
argspec='Oi',
528+
callfunction="wrap_PyIter_Next",
529+
arguments=["PyObject* sequence", "int n"],
530+
cmpfunc=unhandled_error_compare
531+
)
532+

graalpython/lib-graalpython/python_cext.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,16 @@ def PyNumber_Long(v, error_marker):
452452
return error_marker
453453

454454

455+
def PyIter_Next(itObj, error_marker):
456+
typ = val = tb = None
457+
try:
458+
return next(itObj)
459+
except BaseException:
460+
typ, val, tb = sys.exc_info()
461+
PyErr_Restore(typ, val, tb)
462+
return error_marker
463+
464+
455465
##################### UNICODE
456466

457467

0 commit comments

Comments
 (0)