Skip to content

Instantly share code, notes, and snippets.

@riga
Created January 22, 2020 12:52
Show Gist options
  • Save riga/0a751a4555276804b54fdfeb97629a6a to your computer and use it in GitHub Desktop.
Save riga/0a751a4555276804b54fdfeb97629a6a to your computer and use it in GitHub Desktop.
Python reference count manipulation
# coding: utf-8
import sys
import gc
import ctypes
# configuration of Py_IncRef and Py_DecRef
_c_inc_ref = ctypes.pythonapi.Py_IncRef
_c_inc_ref.argtypes = [ctypes.py_object]
_c_dec_ref = ctypes.pythonapi.Py_DecRef
_c_dec_ref.argtypes = [ctypes.py_object]
def inc_ref(obj, n=1):
"""
Increases the reference count of an object *obj* by *n*.
"""
for _ in range(n):
_c_inc_ref(obj)
def dec_ref(obj, n=1, collect=True):
"""
Decreases the reference count of an object *obj* by *n*. When *collect* is *True*, the garbage
collector is initiated afterwards.
"""
for _ in range(n):
_c_dec_ref(obj)
if collect:
gc.collect()
def ref_count(obj):
"""
Returns the number of references to an object *obj*.
"""
# subtract 3 for: function argument, reference in getrefcount, and the function stack
return sys.getrefcount(obj) - 3
# return len(gc.get_referrers(obj)) - 1
if __name__ == "__main__":
# some tests which print (expected value, actual value)
obj = object()
print(1, ref_count(obj))
obj2 = obj
print(2, ref_count(obj))
del obj2
print(1, ref_count(obj))
inc_ref(obj)
print(2, ref_count(obj))
dec_ref(obj)
print(1, ref_count(obj))
dec_ref(obj)
print("random number", ref_count(obj)) # obj is garbage collected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment