@@ -452,8 +452,8 @@ gen_close(PyObject *self, PyObject *args)
452
452
453
453
454
454
PyDoc_STRVAR (throw_doc ,
455
- "throw(value)\n\
456
- throw(type[,value[,tb]])\n\
455
+ "throw(value, /, *, exc_context=None )\n\
456
+ throw(type[,value[,tb]], /, *, exc_context=None )\n\
457
457
\n\
458
458
Raise exception in generator, return next yielded value or raise\n\
459
459
StopIteration.\n\
@@ -592,14 +592,22 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
592
592
return NULL ;
593
593
}
594
594
595
+ /*
596
+ throw(...) method of builtins.generator instance
597
+ throw(value, /, *, exc_context=None)
598
+ throw(type[,value[,tb]], /, *, exc_context=None)
595
599
600
+ Raise exception in generator, return next yielded value or raise
601
+ StopIteration.
602
+ */
596
603
static PyObject *
597
- gen_throw (PyObject * op , PyObject * const * args , Py_ssize_t nargs )
604
+ gen_throw (PyObject * op , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
598
605
{
599
606
PyGenObject * gen = _PyGen_CAST (op );
600
607
PyObject * typ ;
601
608
PyObject * tb = NULL ;
602
609
PyObject * val = NULL ;
610
+ PyObject * exc_context = NULL ;
603
611
604
612
if (!_PyArg_CheckPositional ("throw" , nargs , 1 , 3 )) {
605
613
return NULL ;
@@ -612,6 +620,18 @@ gen_throw(PyObject *op, PyObject *const *args, Py_ssize_t nargs)
612
620
return NULL ;
613
621
}
614
622
}
623
+
624
+ static const char * const _keywords [] = {"" , "" , "" , "exc_context" , NULL };
625
+ static _PyArg_Parser _parser = {
626
+ .keywords = _keywords ,
627
+ .fname = "throw" ,
628
+ };
629
+ PyObject * argsbuf [4 ];
630
+ args = _PyArg_UnpackKeywords (args , nargs , NULL , kwnames , & _parser , 1 , 3 , 0 , 1 , argsbuf );
631
+ if (!args ) {
632
+ return NULL ;
633
+ }
634
+
615
635
typ = args [0 ];
616
636
if (nargs == 3 ) {
617
637
val = args [1 ];
@@ -620,6 +640,17 @@ gen_throw(PyObject *op, PyObject *const *args, Py_ssize_t nargs)
620
640
else if (nargs == 2 ) {
621
641
val = args [1 ];
622
642
}
643
+
644
+ if (kwnames && PyTuple_GET_SIZE (kwnames )){
645
+ exc_context = args [3 ];
646
+ if (!Py_IsNone (exc_context ) && !PyExceptionInstance_Check (exc_context )){
647
+ PyErr_SetString (PyExc_TypeError , "exc_context must be an Exception object or None" );
648
+ return NULL ;
649
+ }
650
+ }
651
+ // update the generator's current exception context before throwing the
652
+ // exception into it
653
+ PyErr_SetHandledException (exc_context == NULL ? Py_None : exc_context );
623
654
return _gen_throw (gen , 1 , typ , val , tb );
624
655
}
625
656
@@ -841,7 +872,7 @@ PyDoc_STRVAR(sizeof__doc__,
841
872
842
873
static PyMethodDef gen_methods [] = {
843
874
{"send" , gen_send , METH_O , send_doc },
844
- {"throw" , _PyCFunction_CAST (gen_throw ), METH_FASTCALL , throw_doc },
875
+ {"throw" , _PyCFunction_CAST (gen_throw ), METH_FASTCALL | METH_KEYWORDS , throw_doc },
845
876
{"close" , gen_close , METH_NOARGS , close_doc },
846
877
{"__sizeof__" , gen_sizeof , METH_NOARGS , sizeof__doc__ },
847
878
{"__class_getitem__" , Py_GenericAlias , METH_O |METH_CLASS , PyDoc_STR ("See PEP 585" )},
@@ -1187,8 +1218,8 @@ PyDoc_STRVAR(coro_send_doc,
1187
1218
return next iterated value or raise StopIteration." );
1188
1219
1189
1220
PyDoc_STRVAR (coro_throw_doc ,
1190
- "throw(value)\n\
1191
- throw(type[,value[,traceback]] )\n\
1221
+ "throw(value, /, *, exc_context=None )\n\
1222
+ throw(type[,value[,tb]], *, exc_context=None )\n\
1192
1223
\n\
1193
1224
Raise exception in coroutine, return next iterated value or raise\n\
1194
1225
StopIteration.\n\
@@ -1201,7 +1232,7 @@ PyDoc_STRVAR(coro_close_doc,
1201
1232
1202
1233
static PyMethodDef coro_methods [] = {
1203
1234
{"send" , gen_send , METH_O , coro_send_doc },
1204
- {"throw" ,_PyCFunction_CAST (gen_throw ), METH_FASTCALL , coro_throw_doc },
1235
+ {"throw" , _PyCFunction_CAST (gen_throw ), METH_FASTCALL | METH_KEYWORDS , coro_throw_doc },
1205
1236
{"close" , gen_close , METH_NOARGS , coro_close_doc },
1206
1237
{"__sizeof__" , gen_sizeof , METH_NOARGS , sizeof__doc__ },
1207
1238
{"__class_getitem__" , Py_GenericAlias , METH_O |METH_CLASS , PyDoc_STR ("See PEP 585" )},
@@ -1291,10 +1322,10 @@ coro_wrapper_send(PyObject *self, PyObject *arg)
1291
1322
}
1292
1323
1293
1324
static PyObject *
1294
- coro_wrapper_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs )
1325
+ coro_wrapper_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1295
1326
{
1296
1327
PyCoroWrapper * cw = _PyCoroWrapper_CAST (self );
1297
- return gen_throw ((PyObject * )cw -> cw_coroutine , args , nargs );
1328
+ return gen_throw ((PyObject * )cw -> cw_coroutine , args , nargs , kwnames );
1298
1329
}
1299
1330
1300
1331
static PyObject *
@@ -1314,8 +1345,8 @@ coro_wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1314
1345
1315
1346
static PyMethodDef coro_wrapper_methods [] = {
1316
1347
{"send" , coro_wrapper_send , METH_O , coro_send_doc },
1317
- {"throw" , _PyCFunction_CAST (coro_wrapper_throw ), METH_FASTCALL ,
1318
- coro_throw_doc },
1348
+ {"throw" , _PyCFunction_CAST (coro_wrapper_throw ),
1349
+ METH_FASTCALL | METH_KEYWORDS , coro_throw_doc },
1319
1350
{"close" , coro_wrapper_close , METH_NOARGS , coro_close_doc },
1320
1351
{NULL , NULL } /* Sentinel */
1321
1352
};
@@ -1827,7 +1858,7 @@ async_gen_asend_iternext(PyObject *ags)
1827
1858
1828
1859
1829
1860
static PyObject *
1830
- async_gen_asend_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs )
1861
+ async_gen_asend_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
1831
1862
{
1832
1863
PyAsyncGenASend * o = _PyAsyncGenASend_CAST (self );
1833
1864
@@ -1851,7 +1882,7 @@ async_gen_asend_throw(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1851
1882
o -> ags_gen -> ag_running_async = 1 ;
1852
1883
}
1853
1884
1854
- PyObject * result = gen_throw ((PyObject * )o -> ags_gen , args , nargs );
1885
+ PyObject * result = gen_throw ((PyObject * )o -> ags_gen , args , nargs , kwnames );
1855
1886
result = async_gen_unwrap_value (o -> ags_gen , result );
1856
1887
1857
1888
if (result == NULL ) {
@@ -1871,7 +1902,7 @@ async_gen_asend_close(PyObject *self, PyObject *args)
1871
1902
Py_RETURN_NONE ;
1872
1903
}
1873
1904
1874
- PyObject * result = async_gen_asend_throw (self , & PyExc_GeneratorExit , 1 );
1905
+ PyObject * result = async_gen_asend_throw (self , & PyExc_GeneratorExit , 1 , NULL );
1875
1906
if (result == NULL ) {
1876
1907
if (PyErr_ExceptionMatches (PyExc_StopIteration ) ||
1877
1908
PyErr_ExceptionMatches (PyExc_StopAsyncIteration ) ||
@@ -1899,7 +1930,8 @@ async_gen_asend_finalize(PyObject *self)
1899
1930
1900
1931
static PyMethodDef async_gen_asend_methods [] = {
1901
1932
{"send" , async_gen_asend_send , METH_O , send_doc },
1902
- {"throw" , _PyCFunction_CAST (async_gen_asend_throw ), METH_FASTCALL , throw_doc },
1933
+ {"throw" , _PyCFunction_CAST (async_gen_asend_throw ),
1934
+ METH_FASTCALL |METH_KEYWORDS , throw_doc },
1903
1935
{"close" , async_gen_asend_close , METH_NOARGS , close_doc },
1904
1936
{NULL , NULL } /* Sentinel */
1905
1937
};
@@ -2227,7 +2259,7 @@ async_gen_athrow_send(PyObject *self, PyObject *arg)
2227
2259
2228
2260
2229
2261
static PyObject *
2230
- async_gen_athrow_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs )
2262
+ async_gen_athrow_throw (PyObject * self , PyObject * const * args , Py_ssize_t nargs , PyObject * kwnames )
2231
2263
{
2232
2264
PyAsyncGenAThrow * o = _PyAsyncGenAThrow_CAST (self );
2233
2265
@@ -2258,7 +2290,7 @@ async_gen_athrow_throw(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2258
2290
o -> agt_gen -> ag_running_async = 1 ;
2259
2291
}
2260
2292
2261
- PyObject * retval = gen_throw ((PyObject * )o -> agt_gen , args , nargs );
2293
+ PyObject * retval = gen_throw ((PyObject * )o -> agt_gen , args , nargs , kwnames );
2262
2294
if (o -> agt_args ) {
2263
2295
retval = async_gen_unwrap_value (o -> agt_gen , retval );
2264
2296
if (retval == NULL ) {
@@ -2311,7 +2343,7 @@ async_gen_athrow_close(PyObject *self, PyObject *args)
2311
2343
Py_RETURN_NONE ;
2312
2344
}
2313
2345
PyObject * result = async_gen_athrow_throw ((PyObject * )agt ,
2314
- & PyExc_GeneratorExit , 1 );
2346
+ & PyExc_GeneratorExit , 1 , NULL );
2315
2347
if (result == NULL ) {
2316
2348
if (PyErr_ExceptionMatches (PyExc_StopIteration ) ||
2317
2349
PyErr_ExceptionMatches (PyExc_StopAsyncIteration ) ||
@@ -2342,7 +2374,7 @@ async_gen_athrow_finalize(PyObject *op)
2342
2374
static PyMethodDef async_gen_athrow_methods [] = {
2343
2375
{"send" , async_gen_athrow_send , METH_O , send_doc },
2344
2376
{"throw" , _PyCFunction_CAST (async_gen_athrow_throw ),
2345
- METH_FASTCALL , throw_doc },
2377
+ METH_FASTCALL | METH_KEYWORDS , throw_doc },
2346
2378
{"close" , async_gen_athrow_close , METH_NOARGS , close_doc },
2347
2379
{NULL , NULL } /* Sentinel */
2348
2380
};
0 commit comments