@@ -254,6 +254,55 @@ record_item(ApgRecordObject *o, Py_ssize_t i)
254
254
}
255
255
256
256
257
+ /* Lookup a record value by its name. Return 0 on success, -2 if the
258
+ * value was not found (with KeyError set), and -1 on all other errors.
259
+ */
260
+ static int
261
+ record_item_by_name (ApgRecordObject * o , PyObject * item , PyObject * * result )
262
+ {
263
+ PyObject * mapped ;
264
+ PyObject * val ;
265
+ Py_ssize_t i ;
266
+
267
+ mapped = PyObject_GetItem (o -> desc -> mapping , item );
268
+ if (mapped == NULL ) {
269
+ goto noitem ;
270
+ }
271
+
272
+ if (!PyIndex_Check (mapped )) {
273
+ Py_DECREF (mapped );
274
+ goto error ;
275
+ }
276
+
277
+ i = PyNumber_AsSsize_t (mapped , PyExc_IndexError );
278
+ Py_DECREF (mapped );
279
+
280
+ if (i < 0 ) {
281
+ if (PyErr_Occurred ())
282
+ PyErr_Clear ();
283
+ goto error ;
284
+ }
285
+
286
+ val = record_item (o , i );
287
+ if (val == NULL ) {
288
+ PyErr_Clear ();
289
+ goto error ;
290
+ }
291
+
292
+ * result = val ;
293
+
294
+ return 0 ;
295
+
296
+ noitem :
297
+ _PyErr_SetKeyError (item );
298
+ return -2 ;
299
+
300
+ error :
301
+ PyErr_SetString (PyExc_RuntimeError , "invalid record descriptor" );
302
+ return -1 ;
303
+ }
304
+
305
+
257
306
static PyObject *
258
307
record_subscript (ApgRecordObject * o , PyObject * item )
259
308
{
@@ -299,42 +348,13 @@ record_subscript(ApgRecordObject* o, PyObject* item)
299
348
}
300
349
}
301
350
else {
302
- PyObject * mapped ;
303
- mapped = PyObject_GetItem (o -> desc -> mapping , item );
304
- if (mapped != NULL ) {
305
- Py_ssize_t i ;
306
- PyObject * result ;
307
-
308
- if (!PyIndex_Check (mapped )) {
309
- Py_DECREF (mapped );
310
- goto noitem ;
311
- }
312
-
313
- i = PyNumber_AsSsize_t (mapped , PyExc_IndexError );
314
- Py_DECREF (mapped );
315
-
316
- if (i < 0 ) {
317
- if (PyErr_Occurred ()) {
318
- PyErr_Clear ();
319
- }
320
- goto noitem ;
321
- }
351
+ PyObject * result ;
322
352
323
- result = record_item (o , i );
324
- if (result == NULL ) {
325
- PyErr_Clear ();
326
- goto noitem ;
327
- }
353
+ if (record_item_by_name (o , item , & result ) < 0 )
354
+ return NULL ;
355
+ else
328
356
return result ;
329
- }
330
- else {
331
- goto noitem ;
332
- }
333
357
}
334
-
335
- noitem :
336
- _PyErr_SetKeyError (item );
337
- return NULL ;
338
358
}
339
359
340
360
@@ -483,6 +503,28 @@ record_contains(ApgRecordObject *o, PyObject *arg)
483
503
}
484
504
485
505
506
+ static PyObject *
507
+ record_get (ApgRecordObject * o , PyObject * args )
508
+ {
509
+ PyObject * key ;
510
+ PyObject * defval = Py_None ;
511
+ PyObject * val = NULL ;
512
+ int res ;
513
+
514
+ if (!PyArg_UnpackTuple (args , "get" , 1 , 2 , & key , & defval ))
515
+ return NULL ;
516
+
517
+ res = record_item_by_name (o , key , & val );
518
+ if (res == -2 ) {
519
+ PyErr_Clear ();
520
+ Py_INCREF (defval );
521
+ val = defval ;
522
+ }
523
+
524
+ return val ;
525
+ }
526
+
527
+
486
528
static PySequenceMethods record_as_sequence = {
487
529
(lenfunc )record_length , /* sq_length */
488
530
0 , /* sq_concat */
@@ -506,6 +548,7 @@ static PyMethodDef record_methods[] = {
506
548
{"values" , (PyCFunction )record_values , METH_NOARGS },
507
549
{"keys" , (PyCFunction )record_keys , METH_NOARGS },
508
550
{"items" , (PyCFunction )record_items , METH_NOARGS },
551
+ {"get" , (PyCFunction )record_get , METH_VARARGS },
509
552
{NULL , NULL } /* sentinel */
510
553
};
511
554
0 commit comments