Skip to main content

Overview

Python uses reference counting for memory management. Every Python object has a reference count tracking how many references point to it. When the count reaches zero, the object is deallocated.
Reference counting errors are the most common source of bugs in C extensions. Always track ownership carefully!

Reference Count Basics

Py_INCREF

Increment the reference count. Indicates taking a new strong reference.
PyObject*
required
Object to increment (must not be NULL)
Example:
Py_INCREF does nothing if the object is immortal (Python 3.12+), but you should still call it.

Py_DECREF

Decrement the reference count. When count reaches zero, the object is deallocated.
PyObject*
required
Object to decrement (must not be NULL)
Example:
Deallocation Side EffectsWhen an object’s refcount reaches zero, its __del__ method can execute arbitrary Python code. Ensure objects are in consistent state before calling Py_DECREF:

Py_XINCREF / Py_XDECREF

Same as Py_INCREF/Py_DECREF but safe for NULL pointers. Example:

Creating References

Py_NewRef

Increment reference count and return the object. Convenient for assignment.
PyObject*
required
Object (must not be NULL)
Returns: The same object (with incremented refcount) Example:

Py_XNewRef

Same as Py_NewRef but accepts NULL (returns NULL unchanged). Example:

Safe Reference Management

Py_CLEAR

Safely decrement reference and set variable to NULL. Avoids use-after-free bugs.
PyObject*
required
Reference to clear (variable, not just value)
Example:
Expands to:

Py_SETREF

Safely replace a reference. Assigns src to dst before decrementing old value. Example:
Expands to:

Py_XSETREF

Like Py_SETREF but uses Py_XDECREF (safer if dst might be NULL).

Reference Ownership

Borrowed References

Some functions return borrowed references - you don’t own them and shouldn’t decrement. Common borrowed reference functions:
  • PyList_GetItem() - Returns borrowed reference
  • PyTuple_GetItem() - Returns borrowed reference
  • PyDict_GetItem() - Returns borrowed reference
  • PyModule_GetDict() - Returns borrowed reference
Example:

Owned References (New References)

Most functions return new references - you own them and must decrement. Common new reference functions:
  • PyLong_FromLong() - Returns new reference
  • PyUnicode_FromString() - Returns new reference
  • PyList_New() - Returns new reference
  • PyObject_GetAttr() - Returns new reference
  • PySequence_GetItem() - Returns new reference (even for lists!)
Example:

Stealing References

Some functions steal references - they take ownership without incrementing. Functions that steal:
  • PyList_SetItem() - Steals reference to item
  • PyTuple_SetItem() - Steals reference to item
  • PyModule_AddObject() - Steals reference to value
Example:
If you need to keep a reference:

Common Patterns

Function Return Values

Functions should return owned references (new references):
Or for None:

Error Handling

Clean up references on error:

Structure Members

Manage references in structures:

Setter Functions

Implement setters correctly:

Debugging Reference Counts

Py_REFCNT

Get current reference count.
Reference counts may not reflect actual usage:
  • Immortal objects have very high refcounts
  • Internal caching affects counts
  • Use only for debugging
Example:

Py_SET_REFCNT

Set reference count directly. Rarely needed.

Best Practices

Track OwnershipAlways know whether you own a reference:
Initialize to NULL
Common Mistakes
Use Helper MacrosPrefer Py_CLEAR, Py_SETREF, Py_XSETREF over manual reference management:

Function Versions

Py_IncRef / Py_DecRef

Function versions of Py_XINCREF/Py_XDECREF. Used for runtime dynamic embedding.

See Also

Object Protocol

Generic object operations

Memory Allocation

Allocating Python objects

Type Objects

Custom type definitions

Exception Handling

Error handling in C extensions