Kaynağa Gözat

kill generator on body raise

blueloveTH 2 yıl önce
ebeveyn
işleme
ca7fb15787
2 değiştirilmiş dosya ile 29 ekleme ve 2 silme
  1. 9 1
      src/iter.cpp
  2. 20 1
      tests/45_yield.py

+ 9 - 1
src/iter.cpp

@@ -49,7 +49,15 @@ namespace pkpy{
         for(PyObject* obj: s_backup) frame._s->push(obj);
         s_backup.clear();
         vm->callstack.push(std::move(frame));
-        PyObject* ret = vm->_run_top_frame();
+
+        PyObject* ret;
+        try{
+            ret = vm->_run_top_frame();
+        }catch(...){
+            state = 2;      // end this generator immediately when an exception is thrown
+            throw;
+        }
+        
         if(ret == PY_OP_YIELD){
             // backup the context
             frame = std::move(vm->callstack.top());

+ 20 - 1
tests/45_yield.py

@@ -45,4 +45,23 @@ def f(n):
             yield j
 
 t = f(3)
-assert list(t) == [0, 1, 0, 2, 0, 1]
+assert list(t) == [0, 1, 0, 2, 0, 1]
+
+def f(n):
+    for i in range(n):
+        if i == n-1:
+            raise ValueError
+        yield i
+
+t = f(3)
+t = iter(t)
+assert next(t) == 0
+assert next(t) == 1
+
+try:
+    next(t)
+    exit(1)
+except ValueError:
+    pass
+
+assert next(t) == StopIteration