I read that e.g. PyTupe_SetItem() steals a reference to the given object but I didn't get what that mean to me and why doesn't PyDict_SetItem() do it either?


Recommended Answers

All 8 Replies

All I can think of is that a tuple is an immutable object and a dictionary is a mutable object.

exactly that was my first guess but PyList_SetItem() also steals the reference and lists aren't immutable ;(

There must be something that tuples and lists share in C code that the other types don't. You might have to check the Python C source code.

Okay maybe I have to check that. Thanks. But the main thing is what is the difference of stealing functions to those who don't steal a reference, respectively what does steal mean?

Steal means that the item will be referenced in the tuple, but without increasing it's reference count. When the tuple is deleted, the object will be decrefed.
For example if you create a python integer with PyInt_FromLong, you normally need to decref this integer before leaving the current function, otherwise you create a memory leak. But if you give the integer to PyTuple_SetItem, you must not decref the integer, because it will be decrefed when the tuple is deleted.
I think this implementation was chosen for performance reasons. Tuples are created all the time in python, for example each function call fills a tuple with the arguments of the call. So the implementation avoids a number of Py_INCREF or Py_DECREF.


thanks for you reply. Okay I understand now how it works but this destroys my conceive idea of the parameter passing.
The interpreter does automatic tuple-packing when it passes the parameters to a function. And it guarantees that the arguments won't be freed during the call.
I thought this works because it creates a new tuple with the specific arguments and the function that adds these arguments would increase the ref-count of each item. I figured that this function would be PyTuple_SetItem().
Am I wrong with that or does the parameter passing part just uses another function or explicitly call Py_INCREF().
Do you know more about it? Thanks a lot.


A complete answer requires to browse python's source code. However, consider a piece of python code like this

x = aValue()
F( G(), x )

Since the value returned by G() is a new reference, it could be inserted with PyTuple_SetItem in the arguments tuple of F. The argument x is a variable in the local namespace. It must be increfed when the arguments tuple is built, but this can be detected at compile time...

Oh okay that makes sense to me :icon_idea:
Thanks a lot for your expert advise.


Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.