There is reason this function is private. Using this function is potentially dangerous, the name is misleading and it is may be perpetuating a misunderstanding of how Python objects are implemented.
It is dangerous, because assigning directly to the pointer returned by this function could result in the object and its __dict__ getting out of sync.
Its name is misleading as it suggests that it is getting a pointer, without side effects, and that pointer can be written to.
It also perpetuates the idea that all objects have a dictionary (at the C level), and that accessing that dictionary is cheap.
Just because something is widely used does not mean we should make it public. We should be helping extension authors to write good code, not perpetuating their mistakes.
Why are C extensions using this method anyway? If they are using it just to get the object's dictionary for legitimate reasons, then we should add a PyObject_GetDict function for that purpose.
Also, we should probably change the docs for PyObject_GenericGetDict to make it clear that it is for implementing the __dict__ slot, not to be called as an API.
This function is also broken on free-threading because free-threading stores and reads dict pointer atomically, it is not safe to read the dict pointer directly as returned by this function.
Why are C extensions using this method anyway? If they are using it just to get the object's dictionary for legitimate reasons, then we should add a PyObject_GetDict function for that purpose.
For various reasons, see for example #139854 (comment). Should we add a PyObject_SetDict() function as well?
Should we add a PyObject_SetDict() function as well?
Not with the current evidence. I'd be interested to know if SWIG_PYTHON_SLOW_GETSET_THIS is helpful nowadays -- ideally PyObject_SetAttr would be all they need.
One of Cython's uses of this I think is duplicating PyType_Lookup so could probably go away if you provided that.
I think in general PyObject_GetDict would be more useful than GetDictPtr.
At least some of the time I'm using the dict rather than GetAttr/SetAttr because I can do PyDict_SetDefault and I know it'll be thread safe. That's very useful for lazy initialization, and is something you can't easily replicate without the dict.
I think in general PyObject_GetDict would be more useful than GetDictPtr.
Ok, I created #139968 to add PyObject_GetDict() function. It's similar to PyObject_GenericGetDict() but has a different API and doesn't raise an exception if the __dict__ doesn't exist.
Activity
pythongh-139852: Add PyObject_GetDictPtr() function
markshannon commented on Oct 10, 2025
I don't think this is a good idea.
There is reason this function is private. Using this function is potentially dangerous, the name is misleading and it is may be perpetuating a misunderstanding of how Python objects are implemented.
It is dangerous, because assigning directly to the pointer returned by this function could result in the object and its __dict__ getting out of sync.
Its name is misleading as it suggests that it is getting a pointer, without side effects, and that pointer can be written to.
It also perpetuates the idea that all objects have a dictionary (at the C level), and that accessing that dictionary is cheap.
Just because something is widely used does not mean we should make it public. We should be helping extension authors to write good code, not perpetuating their mistakes.
Why are C extensions using this method anyway? If they are using it just to get the object's dictionary for legitimate reasons, then we should add a PyObject_GetDict function for that purpose.
Also, we should probably change the docs for PyObject_GenericGetDict to make it clear that it is for implementing the __dict__ slot, not to be called as an API.
kumaraditya303 commented on Oct 10, 2025
This function is also broken on free-threading because free-threading stores and reads dict pointer atomically, it is not safe to read the dict pointer directly as returned by this function.
vstinner commented on Oct 10, 2025
For various reasons, see for example #139854 (comment). Should we add a PyObject_SetDict() function as well?
encukou commented on Oct 10, 2025
Not with the current evidence. I'd be interested to know if SWIG_PYTHON_SLOW_GETSET_THIS is helpful nowadays -- ideally PyObject_SetAttr would be all they need.
da-woods commented on Oct 11, 2025
One of Cython's uses of this I think is duplicating PyType_Lookup so could probably go away if you provided that.
I think in general PyObject_GetDict would be more useful than GetDictPtr.
At least some of the time I'm using the dict rather than GetAttr/SetAttr because I can do PyDict_SetDefault and I know it'll be thread safe. That's very useful for lazy initialization, and is something you can't easily replicate without the dict.
vstinner commented on Oct 11, 2025
I created #139847 to add PyType_Lookup() function.
pythongh-139852: Add PyObject_GetDict() function
pythongh-139852: Add PyObject_GetDict() function
vstinner commented on Oct 11, 2025
Ok, I created #139968 to add PyObject_GetDict() function. It's similar to PyObject_GenericGetDict() but has a different API and doesn't raise an exception if the __dict__ doesn't exist.
vstinner commented on Nov 17, 2025
And the decision is to not add the PyObject_GetDict() function. So I close the issue.