@@ -1405,6 +1405,34 @@ typedef struct channelid {
1405
1405
_channels * channels ;
1406
1406
} channelid ;
1407
1407
1408
+ static int
1409
+ channel_id_converter (PyObject * arg , void * ptr )
1410
+ {
1411
+ int64_t cid ;
1412
+ if (PyObject_TypeCheck (arg , & ChannelIDtype )) {
1413
+ cid = ((channelid * )arg )-> id ;
1414
+ }
1415
+ else if (PyIndex_Check (arg )) {
1416
+ cid = PyLong_AsLongLong (arg );
1417
+ if (cid == -1 && PyErr_Occurred ()) {
1418
+ return 0 ;
1419
+ }
1420
+ if (cid < 0 ) {
1421
+ PyErr_Format (PyExc_ValueError ,
1422
+ "channel ID must be a non-negative int, got %R" , arg );
1423
+ return 0 ;
1424
+ }
1425
+ }
1426
+ else {
1427
+ PyErr_Format (PyExc_TypeError ,
1428
+ "channel ID must be an int, got %.100s" ,
1429
+ arg -> ob_type -> tp_name );
1430
+ return 0 ;
1431
+ }
1432
+ * (int64_t * )ptr = cid ;
1433
+ return 1 ;
1434
+ }
1435
+
1408
1436
static channelid *
1409
1437
newchannelid (PyTypeObject * cls , int64_t cid , int end , _channels * channels ,
1410
1438
int force , int resolve )
@@ -1437,28 +1465,16 @@ static PyObject *
1437
1465
channelid_new (PyTypeObject * cls , PyObject * args , PyObject * kwds )
1438
1466
{
1439
1467
static char * kwlist [] = {"id" , "send" , "recv" , "force" , "_resolve" , NULL };
1440
- PyObject * id ;
1468
+ int64_t cid ;
1441
1469
int send = -1 ;
1442
1470
int recv = -1 ;
1443
1471
int force = 0 ;
1444
1472
int resolve = 0 ;
1445
1473
if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1446
- "O|$pppp:ChannelID.__new__" , kwlist ,
1447
- & id , & send , & recv , & force , & resolve ))
1474
+ "O& |$pppp:ChannelID.__new__" , kwlist ,
1475
+ channel_id_converter , & cid , & send , & recv , & force , & resolve ))
1448
1476
return NULL ;
1449
1477
1450
- // Coerce and check the ID.
1451
- int64_t cid ;
1452
- if (PyObject_TypeCheck (id , & ChannelIDtype )) {
1453
- cid = ((channelid * )id )-> id ;
1454
- }
1455
- else {
1456
- cid = _Py_CoerceID (id );
1457
- if (cid < 0 ) {
1458
- return NULL ;
1459
- }
1460
- }
1461
-
1462
1478
// Handle "send" and "recv".
1463
1479
if (send == 0 && recv == 0 ) {
1464
1480
PyErr_SetString (PyExc_ValueError ,
@@ -1592,30 +1608,28 @@ channelid_richcompare(PyObject *self, PyObject *other, int op)
1592
1608
int equal ;
1593
1609
if (PyObject_TypeCheck (other , & ChannelIDtype )) {
1594
1610
channelid * othercid = (channelid * )other ;
1595
- if (cid -> end != othercid -> end ) {
1596
- equal = 0 ;
1597
- }
1598
- else {
1599
- equal = (cid -> id == othercid -> id );
1600
- }
1611
+ equal = (cid -> end == othercid -> end ) && (cid -> id == othercid -> id );
1601
1612
}
1602
- else {
1603
- other = PyNumber_Long (other );
1604
- if (other == NULL ) {
1605
- PyErr_Clear ();
1606
- Py_RETURN_NOTIMPLEMENTED ;
1607
- }
1608
- int64_t othercid = PyLong_AsLongLong (other );
1609
- Py_DECREF (other );
1610
- if (othercid == -1 && PyErr_Occurred () != NULL ) {
1613
+ else if (PyLong_Check (other )) {
1614
+ /* Fast path */
1615
+ int overflow ;
1616
+ long long othercid = PyLong_AsLongLongAndOverflow (other , & overflow );
1617
+ if (othercid == -1 && PyErr_Occurred ()) {
1611
1618
return NULL ;
1612
1619
}
1613
- if (othercid < 0 ) {
1614
- equal = 0 ;
1615
- }
1616
- else {
1617
- equal = (cid -> id == othercid );
1620
+ equal = !overflow && (othercid >= 0 ) && (cid -> id == othercid );
1621
+ }
1622
+ else if (PyNumber_Check (other )) {
1623
+ PyObject * pyid = PyLong_FromLongLong (cid -> id );
1624
+ if (pyid == NULL ) {
1625
+ return NULL ;
1618
1626
}
1627
+ PyObject * res = PyObject_RichCompare (pyid , other , op );
1628
+ Py_DECREF (pyid );
1629
+ return res ;
1630
+ }
1631
+ else {
1632
+ Py_RETURN_NOTIMPLEMENTED ;
1619
1633
}
1620
1634
1621
1635
if ((op == Py_EQ && equal ) || (op == Py_NE && !equal )) {
@@ -1754,8 +1768,7 @@ static PyTypeObject ChannelIDtype = {
1754
1768
0 , /* tp_getattro */
1755
1769
0 , /* tp_setattro */
1756
1770
0 , /* tp_as_buffer */
1757
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1758
- Py_TPFLAGS_LONG_SUBCLASS , /* tp_flags */
1771
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* tp_flags */
1759
1772
channelid_doc , /* tp_doc */
1760
1773
0 , /* tp_traverse */
1761
1774
0 , /* tp_clear */
@@ -2017,10 +2030,6 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds)
2017
2030
"O:destroy" , kwlist , & id )) {
2018
2031
return NULL ;
2019
2032
}
2020
- if (!PyLong_Check (id )) {
2021
- PyErr_SetString (PyExc_TypeError , "ID must be an int" );
2022
- return NULL ;
2023
- }
2024
2033
2025
2034
// Look up the interpreter.
2026
2035
PyInterpreterState * interp = _PyInterpreterID_LookUp (id );
@@ -2145,10 +2154,6 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
2145
2154
& id , & code , & shared )) {
2146
2155
return NULL ;
2147
2156
}
2148
- if (!PyLong_Check (id )) {
2149
- PyErr_SetString (PyExc_TypeError , "first arg (ID) must be an int" );
2150
- return NULL ;
2151
- }
2152
2157
2153
2158
// Look up the interpreter.
2154
2159
PyInterpreterState * interp = _PyInterpreterID_LookUp (id );
@@ -2216,10 +2221,6 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds)
2216
2221
"O:is_running" , kwlist , & id )) {
2217
2222
return NULL ;
2218
2223
}
2219
- if (!PyLong_Check (id )) {
2220
- PyErr_SetString (PyExc_TypeError , "ID must be an int" );
2221
- return NULL ;
2222
- }
2223
2224
2224
2225
PyInterpreterState * interp = _PyInterpreterID_LookUp (id );
2225
2226
if (interp == NULL ) {
@@ -2268,13 +2269,9 @@ static PyObject *
2268
2269
channel_destroy (PyObject * self , PyObject * args , PyObject * kwds )
2269
2270
{
2270
2271
static char * kwlist [] = {"cid" , NULL };
2271
- PyObject * id ;
2272
- if (!PyArg_ParseTupleAndKeywords (args , kwds ,
2273
- "O:channel_destroy" , kwlist , & id )) {
2274
- return NULL ;
2275
- }
2276
- int64_t cid = _Py_CoerceID (id );
2277
- if (cid < 0 ) {
2272
+ int64_t cid ;
2273
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "O&:channel_destroy" , kwlist ,
2274
+ channel_id_converter , & cid )) {
2278
2275
return NULL ;
2279
2276
}
2280
2277
@@ -2331,14 +2328,10 @@ static PyObject *
2331
2328
channel_send (PyObject * self , PyObject * args , PyObject * kwds )
2332
2329
{
2333
2330
static char * kwlist [] = {"cid" , "obj" , NULL };
2334
- PyObject * id ;
2331
+ int64_t cid ;
2335
2332
PyObject * obj ;
2336
- if (!PyArg_ParseTupleAndKeywords (args , kwds ,
2337
- "OO:channel_send" , kwlist , & id , & obj )) {
2338
- return NULL ;
2339
- }
2340
- int64_t cid = _Py_CoerceID (id );
2341
- if (cid < 0 ) {
2333
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "O&O:channel_send" , kwlist ,
2334
+ channel_id_converter , & cid , & obj )) {
2342
2335
return NULL ;
2343
2336
}
2344
2337
@@ -2357,13 +2350,9 @@ static PyObject *
2357
2350
channel_recv (PyObject * self , PyObject * args , PyObject * kwds )
2358
2351
{
2359
2352
static char * kwlist [] = {"cid" , NULL };
2360
- PyObject * id ;
2361
- if (!PyArg_ParseTupleAndKeywords (args , kwds ,
2362
- "O:channel_recv" , kwlist , & id )) {
2363
- return NULL ;
2364
- }
2365
- int64_t cid = _Py_CoerceID (id );
2366
- if (cid < 0 ) {
2353
+ int64_t cid ;
2354
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "O&:channel_recv" , kwlist ,
2355
+ channel_id_converter , & cid )) {
2367
2356
return NULL ;
2368
2357
}
2369
2358
@@ -2379,17 +2368,13 @@ static PyObject *
2379
2368
channel_close (PyObject * self , PyObject * args , PyObject * kwds )
2380
2369
{
2381
2370
static char * kwlist [] = {"cid" , "send" , "recv" , "force" , NULL };
2382
- PyObject * id ;
2371
+ int64_t cid ;
2383
2372
int send = 0 ;
2384
2373
int recv = 0 ;
2385
2374
int force = 0 ;
2386
2375
if (!PyArg_ParseTupleAndKeywords (args , kwds ,
2387
- "O|$ppp:channel_close" , kwlist ,
2388
- & id , & send , & recv , & force )) {
2389
- return NULL ;
2390
- }
2391
- int64_t cid = _Py_CoerceID (id );
2392
- if (cid < 0 ) {
2376
+ "O&|$ppp:channel_close" , kwlist ,
2377
+ channel_id_converter , & cid , & send , & recv , & force )) {
2393
2378
return NULL ;
2394
2379
}
2395
2380
@@ -2431,17 +2416,13 @@ channel_release(PyObject *self, PyObject *args, PyObject *kwds)
2431
2416
{
2432
2417
// Note that only the current interpreter is affected.
2433
2418
static char * kwlist [] = {"cid" , "send" , "recv" , "force" , NULL };
2434
- PyObject * id ;
2419
+ int64_t cid ;
2435
2420
int send = 0 ;
2436
2421
int recv = 0 ;
2437
2422
int force = 0 ;
2438
2423
if (!PyArg_ParseTupleAndKeywords (args , kwds ,
2439
- "O|$ppp:channel_release" , kwlist ,
2440
- & id , & send , & recv , & force )) {
2441
- return NULL ;
2442
- }
2443
- int64_t cid = _Py_CoerceID (id );
2444
- if (cid < 0 ) {
2424
+ "O&|$ppp:channel_release" , kwlist ,
2425
+ channel_id_converter , & cid , & send , & recv , & force )) {
2445
2426
return NULL ;
2446
2427
}
2447
2428
if (send == 0 && recv == 0 ) {
@@ -2538,7 +2519,6 @@ PyInit__xxsubinterpreters(void)
2538
2519
}
2539
2520
2540
2521
/* Initialize types */
2541
- ChannelIDtype .tp_base = & PyLong_Type ;
2542
2522
if (PyType_Ready (& ChannelIDtype ) != 0 ) {
2543
2523
return NULL ;
2544
2524
}
0 commit comments