Reference counting using PyDict_SetItemString

2024/11/14 15:32:00

I'm wondering how memory management/reference counting works when a new value is set into an existing field within a PyDict (within a C extension).

For instance, assume a dictionary is created and populated in the following way:

myPyDict = PyDict_New();
tempPyObj = PyString_FromString("Original Value");
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj);
Py_DECREF(tempPyObj);

From a memory and reference counting perspective, what happens when there is a subsequent

tempPyObj = PyString_FromString("New Value");
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj);
Py_DECREF(tempPyObj);

Is the reference count for the original value automatically decremented (and the memory automatically released)?

The doc for PyList_SetItem specifically mentions what happens for lists: This function “steals” a reference to item and discards a reference to an item already in the list at the affected position.

But neither PyDic_SetItem nor PyDict_SetItemString say how the replacement is handled for dictionaries.

Answer

The ref count of the old value is decremented automatically by logic of PyList_SetItem function. You shouldn't be decrementing the old value by yourself.

If you want to know details, take a look at CPython source code, specifically at the Objects/dictobject.c file.

1) The PyDict_SetItemString()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L3250-L3262

It it's a thin wrapper around PyDict_SetItem()

2) The PyDict_SetItem()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1537-L1565

Is still quite simple and it's obvious that all the heavy-lifting related to inserting/replacing values in a dict is actually done by insertdict().

3) The insertdict()

https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1097-L1186

is the function which gives us the answer. In this function you can find the crucial code and especially the call:

 Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */

which decrements the ref count of old value.

https://en.xdnf.cn/q/72029.html

Related Q&A

How to use statsmodels.tsa.seasonal.seasonal_decompose with a pandas dataframe

from statsmodels.tsa.seasonal import seasonal_decomposedef seasonal_decomp(df, model="additive"):seasonal_df = Noneseasonal_df = seasonal_decompose(df, model=additive)return seasonal_dfseason…

UnidentifiedImageError: cannot identify image file

Hello I am training a model with TensorFlow and Keras, and the dataset was downloaded from https://www.microsoft.com/en-us/download/confirmation.aspx?id=54765 This is a zip folder that I split in the …

Pydub raw audio data

Im using Pydub in Python 3.4 to try to detect the pitch of some audio files.I have a working pitch detection algorithm (McLeod Pitch Method), which is robust for real-time applications (I even made an …

Create Duplicate Rows and Change Values in Specific Columns

How to create x amount of duplicates based on a row in the dataframe and change a single or multi variables from specific columns. The rows are then added to the end of the same dataframe.A B C D E F 0…

writing and saving CSV file from scraping data using python and Beautifulsoup4

I am trying to scrape data from the PGA.com website to get a table of all of the golf courses in the United States. In my CSV table I want to include the Name of the golf course ,Address ,Ownership ,We…

Performance issue turning rows with start - end into a dataframe with TimeIndex

I have a large dataset where each line represents the value of a certain type (think a sensor) for a time interval (between start and end). It looks like this: start end type value 2015-01-01…

How can I create a key using RSA/ECB/PKCS1Padding in python?

I am struggling to find any method of using RSA in ECB mode with PKCS1 padding in python. Ive looked into pyCrypto, but they dont have PKCS1 padding in the master branch (but do in a patch). Neverthel…

Do full-outer-join with pandas.merge_asof

Hi I need to align some time series data with nearest timestamps, so I think pandas.merge_asof could be a good candidate. However, it does not have an option to set how=outer like in the standard merge…

order of calling constructors in Python

#!/usr/bin/pythonclass Parent(object): # define parent classparentAttr = 100def __init__(self):print "Calling parent constructor"def parentMethod(self):print Calling parent methoddef s…

How do I access data from a python thread

I have a very simple threading example using Python 3.4.2. In this example I am creating a five threads that just returns the character string "Result" and appends it to an array titled thre…