tuple creation in C extensions

Alex cut_me_out at hotmail.com
Sun Jun 11 13:29:12 EDT 2000


> Do keep digging. Ref-counting is important.

Ref-counting errors can be such a pain in the neck to track down that I
have taken to placing assertions at the end of routines to make sure
the ref-counts are what they ought to be.  I'll probably grow out of it
as I get the hang of it, though.

This is the sort of thing I've been doing:

int dict_add_pattern (PyObject *dict, char *string, int length, long pos[DEPTH]) {
  PyObject *pattern, *coords, *value, *tuple;
  int return_code, pattern_existed;

  assert (length <= DEPTH);

  coords = dict_set_coords (length - 1, pos);
  if (!coords) {goto fail;}
  
  pattern = Py_BuildValue ("s#N", string, length, coords);
  if (!pattern) {Py_DECREF (coords); goto fail;}

  value = PyDict_GetItem(dict, pattern);
  if (!PyDict_GetItem(dict, pattern)) {
    pattern_existed = 0;
    value = PyInt_FromLong( 1 );
    return_code = PyDict_SetItem(dict, pattern, value);
  } else {
    pattern_existed = 1;
    assert (PyInt_Check( value ));
    value = PyNumber_Add( value, PyInt_FromLong( 1 ));
    if (value == NULL) {goto fail;}
    return_code = PyDict_SetItem(dict, pattern, value);
  }
  /* If a tuple equal to pattern was already in dict, then pattern will not be
     referred to by dict, and should have a refcnt of 0.  If there was no such
     tuple, then PyDict_SetItem increased the refcnt of dict by one.  In
     either case, the refcnt has to be decremented, now.
     */
  Py_DECREF (pattern);
      
  if (return_code == -1) {
    goto fail;
  } else {
    if (DEBUG_REFCOUNTS) {
      printf ("coords: %i\npattern: %i\nvalue: %i\n",
	      coords->ob_refcnt, pattern->ob_refcnt, value->ob_refcnt);
    }
    if (DEBUG_LIST_PATTERNS) {
      PyObject_Print (dict, stdout, 0); printf ("\n");
    }
    goto pass;
  }

fail:
  return 0;
pass:
  assert (pattern->ob_refcnt == (!pattern_existed));
  assert ((coords->ob_refcnt == (!pattern_existed)) | (length == 1));
  return 1;
}



More information about the Python-list mailing list