714
static void RAISE_GENERATOR_EXCEPTION( Nuitka_GeneratorObject *generator )
716
assertObject( generator->m_exception_type );
718
Py_INCREF( generator->m_exception_type );
719
Py_XINCREF( generator->m_exception_value );
720
Py_XINCREF( generator->m_exception_tb );
723
generator->m_exception_type,
724
generator->m_exception_value,
725
(PyObject *)generator->m_exception_tb
728
generator->m_exception_type = NULL;
729
generator->m_exception_value = NULL;
730
generator->m_exception_tb = NULL;
733
extern PyObject *ERROR_GET_STOP_ITERATION_VALUE();
734
extern PyObject *PyGen_Send( PyGenObject *gen, PyObject *arg );
736
extern PyObject *const_str_plain_send;
738
PyObject *YIELD_FROM( Nuitka_GeneratorObject *generator, PyObject *value )
740
// This is the value, propagated back and forth the sub-generator and the
741
// yield from consumer.
742
PyObject *send_value = Py_None;
746
// Send iteration value to the sub-generator, which may be a CPython
747
// generator object, something with an iterator next, or a send method,
748
// where the later is only required if values other than "None" need to
752
// Exception, was thrown into us, need to send that to sub-generator.
753
if ( generator->m_exception_type )
755
// The yielding generator is being closed, but we also are tasked to
756
// immediately close the currently running sub-generator.
757
if ( PyErr_GivenExceptionMatches( generator->m_exception_type, PyExc_GeneratorExit ) )
759
PyObject *close_method = PyObject_GetAttrString( value, (char *)"close" );
763
PyObject *close_value = PyObject_Call( close_method, const_tuple_empty, NULL );
764
Py_DECREF( close_method );
766
if (unlikely( close_value == NULL ))
771
Py_DECREF( close_value );
773
else if ( !PyErr_ExceptionMatches( PyExc_AttributeError ) )
775
PyErr_WriteUnraisable( (PyObject *)generator );
778
RAISE_GENERATOR_EXCEPTION( generator );
782
PyObject *throw_method = PyObject_GetAttrString( value, (char *)"throw" );
786
retval = PyObject_CallFunctionObjArgs( throw_method, generator->m_exception_type, generator->m_exception_value, generator->m_exception_tb, NULL );
787
Py_DECREF( throw_method );
789
if (unlikely( send_value == NULL ))
791
if ( PyErr_ExceptionMatches( PyExc_StopIteration ) )
793
return ERROR_GET_STOP_ITERATION_VALUE();
800
generator->m_exception_type = NULL;
801
generator->m_exception_value = NULL;
802
generator->m_exception_tb = NULL;
804
else if ( PyErr_ExceptionMatches( PyExc_AttributeError ) )
808
RAISE_GENERATOR_EXCEPTION( generator );
817
else if ( PyGen_CheckExact( value ) )
819
retval = PyGen_Send( (PyGenObject *)value, Py_None );
821
else if ( send_value == Py_None )
823
retval = Py_TYPE( value )->tp_iternext( value );
827
// Bug compatibility here, before 3.3 tuples were unrolled in calls, which is what
828
// PyObject_CallMethod does.
829
#if PYTHON_VERSION >= 340
830
retval = PyObject_CallMethodObjArgs( value, const_str_plain_send, send_value, NULL );
832
retval = PyObject_CallMethod( value, (char *)"send", (char *)"O", send_value );
836
// Check the sub-generator result
837
if ( retval == NULL )
839
if ( !ERROR_OCCURED() )
841
return INCREASE_REFCOUNT( Py_None ) ;
844
// The sub-generator has given an exception. In case of
845
// StopIteration, we need to check the value, as it is going to be
846
// the expression value of this "yield from", and we are done. All
847
// other errors, we need to raise.
848
if (likely( PyErr_ExceptionMatches( PyExc_StopIteration ) ))
850
return ERROR_GET_STOP_ITERATION_VALUE();
857
generator->m_yielded = retval;
859
// Return to the calling context.
860
swapFiber( &generator->m_yielder_context, &generator->m_caller_context );
862
send_value = generator->m_yielded;
864
assertObject( send_value );