@@ -258,6 +258,52 @@ ttuple_item(AtntTupleObject *o, Py_ssize_t i)
258258}
259259
260260
261+ static int
262+ ttuple_item_by_name (AtntTupleObject * o , PyObject * item , PyObject * * result )
263+ {
264+ if (o -> fields == NULL ) {
265+ goto noitem ;
266+ }
267+
268+ PyObject * mapped ;
269+ Py_ssize_t i ;
270+ PyObject * value ;
271+
272+ mapped = PyObject_GetItem (o -> fields -> _mapping , item );
273+ if (mapped == NULL ) {
274+ goto noitem ;
275+ }
276+
277+ if (!PyIndex_Check (mapped )) {
278+ Py_DECREF (mapped );
279+ goto noitem ;
280+ }
281+
282+ i = PyNumber_AsSsize_t (mapped , PyExc_IndexError );
283+ Py_DECREF (mapped );
284+
285+ if (i < 0 ) {
286+ if (PyErr_Occurred ()) {
287+ PyErr_Clear ();
288+ }
289+ goto noitem ;
290+ }
291+
292+ value = ttuple_item (o , i );
293+ if (result == NULL ) {
294+ PyErr_Clear ();
295+ goto noitem ;
296+ }
297+
298+ * result = value ;
299+ return 0 ;
300+
301+ noitem :
302+ PyErr_SetObject (PyExc_KeyError , item );
303+ return -1 ;
304+ }
305+
306+
261307static PyObject *
262308ttuple_subscript (AtntTupleObject * o , PyObject * item )
263309{
@@ -287,58 +333,29 @@ ttuple_subscript(AtntTupleObject* o, PyObject* item)
287333 if (slicelength <= 0 ) {
288334 return PyTuple_New (0 );
289335 }
290- else {
291- result = PyTuple_New (slicelength );
292- if (!result ) return NULL ;
293-
294- src = o -> ob_item ;
295- dest = ((PyTupleObject * )result )-> ob_item ;
296- for (cur = start , i = 0 ; i < slicelength ; cur += step , i ++ ) {
297- it = src [cur ];
298- Py_INCREF (it );
299- dest [i ] = it ;
300- }
301-
302- return result ;
303- }
304- }
305- else if (o -> fields != NULL ) {
306- PyObject * mapped ;
307- mapped = PyObject_GetItem (o -> fields -> _mapping , item );
308- if (mapped != NULL ) {
309- Py_ssize_t i ;
310- PyObject * result ;
311-
312- if (!PyIndex_Check (mapped )) {
313- Py_DECREF (mapped );
314- goto noitem ;
315- }
316336
317- i = PyNumber_AsSsize_t ( mapped , PyExc_IndexError );
318- Py_DECREF ( mapped ) ;
337+ result = PyTuple_New ( slicelength );
338+ if (! result ) return NULL ;
319339
320- if (i < 0 ) {
321- if (PyErr_Occurred ()) {
322- PyErr_Clear ();
323- }
324- goto noitem ;
325- }
326-
327- result = ttuple_item (o , i );
328- if (result == NULL ) {
329- PyErr_Clear ();
330- goto noitem ;
331- }
332- return result ;
333- }
334- else {
335- goto noitem ;
340+ src = o -> ob_item ;
341+ dest = ((PyTupleObject * )result )-> ob_item ;
342+ for (cur = start , i = 0 ; i < slicelength ; cur += step , i ++ ) {
343+ it = src [cur ];
344+ Py_INCREF (it );
345+ dest [i ] = it ;
336346 }
347+
348+ return result ;
337349 }
350+ else {
351+ /* map by name */
352+ PyObject * result = NULL ;
353+ if (ttuple_item_by_name (o , item , & result ) < 0 ) {
354+ return NULL ;
355+ }
338356
339- noitem :
340- _PyErr_SetKeyError (item );
341- return NULL ;
357+ return result ;
358+ }
342359}
343360
344361
@@ -511,6 +528,28 @@ ttuple_contains(AtntTupleObject *o, PyObject *arg)
511528}
512529
513530
531+ static PyObject *
532+ ttuple_get (AtntTupleObject * o , PyObject * args )
533+ {
534+ PyObject * key ;
535+ PyObject * defval = Py_None ;
536+ PyObject * val = NULL ;
537+ int res ;
538+
539+ if (!PyArg_UnpackTuple (args , "get" , 1 , 2 , & key , & defval ))
540+ return NULL ;
541+
542+ res = ttuple_item_by_name (o , key , & val );
543+ if (res < 0 ) {
544+ PyErr_Clear ();
545+ Py_INCREF (defval );
546+ val = defval ;
547+ }
548+
549+ return val ;
550+ }
551+
552+
514553static PySequenceMethods ttuple_as_sequence = {
515554 (lenfunc )ttuple_length , /* sq_length */
516555 0 , /* sq_concat */
@@ -531,10 +570,11 @@ static PyMappingMethods ttuple_as_mapping = {
531570
532571
533572static PyMethodDef ttuple_methods [] = {
534- {"values" , (PyCFunction )ttuple_values , METH_NOARGS },
535- {"keys" , (PyCFunction )ttuple_keys , METH_NOARGS },
536- {"items" , (PyCFunction )ttuple_items , METH_NOARGS },
537- {NULL , NULL } /* sentinel */
573+ {"values" , (PyCFunction ) ttuple_values , METH_NOARGS },
574+ {"keys" , (PyCFunction ) ttuple_keys , METH_NOARGS },
575+ {"items" , (PyCFunction ) ttuple_items , METH_NOARGS },
576+ {"get" , (PyCFunction ) ttuple_get , METH_VARARGS },
577+ {NULL , NULL } /* sentinel */
538578};
539579
540580
0 commit comments