@@ -254,6 +254,54 @@ 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 noitem ;
290
+ }
291
+
292
+ * result = val ;
293
+
294
+ return 0 ;
295
+
296
+ noitem :
297
+ _PyErr_SetKeyError (item );
298
+ return -2 ;
299
+
300
+ error :
301
+ return -1 ;
302
+ }
303
+
304
+
257
305
static PyObject *
258
306
record_subscript (ApgRecordObject * o , PyObject * item )
259
307
{
@@ -299,42 +347,13 @@ record_subscript(ApgRecordObject* o, PyObject* item)
299
347
}
300
348
}
301
349
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
- }
350
+ PyObject * result ;
322
351
323
- result = record_item (o , i );
324
- if (result == NULL ) {
325
- PyErr_Clear ();
326
- goto noitem ;
327
- }
352
+ if (record_item_by_name (o , item , & result ) < 0 )
353
+ return NULL ;
354
+ else
328
355
return result ;
329
- }
330
- else {
331
- goto noitem ;
332
- }
333
356
}
334
-
335
- noitem :
336
- _PyErr_SetKeyError (item );
337
- return NULL ;
338
357
}
339
358
340
359
@@ -483,6 +502,28 @@ record_contains(ApgRecordObject *o, PyObject *arg)
483
502
}
484
503
485
504
505
+ static PyObject *
506
+ record_get (ApgRecordObject * o , PyObject * args )
507
+ {
508
+ PyObject * key ;
509
+ PyObject * defval = Py_None ;
510
+ PyObject * val = NULL ;
511
+ int res ;
512
+
513
+ if (!PyArg_UnpackTuple (args , "get" , 1 , 2 , & key , & defval ))
514
+ return NULL ;
515
+
516
+ res = record_item_by_name (o , key , & val );
517
+ if (res == -2 ) {
518
+ PyErr_Clear ();
519
+ Py_INCREF (defval );
520
+ val = defval ;
521
+ }
522
+
523
+ return val ;
524
+ }
525
+
526
+
486
527
static PySequenceMethods record_as_sequence = {
487
528
(lenfunc )record_length , /* sq_length */
488
529
0 , /* sq_concat */
@@ -506,6 +547,7 @@ static PyMethodDef record_methods[] = {
506
547
{"values" , (PyCFunction )record_values , METH_NOARGS },
507
548
{"keys" , (PyCFunction )record_keys , METH_NOARGS },
508
549
{"items" , (PyCFunction )record_items , METH_NOARGS },
550
+ {"get" , (PyCFunction )record_get , METH_VARARGS },
509
551
{NULL , NULL } /* sentinel */
510
552
};
511
553
0 commit comments