You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[C API] Promote _PyObject_Dump() to a public function #141070
changed the title [-][C API] Promote _PyObject_Dump() as a public function[/-][+][C API] Promote _PyObject_Dump() to a public function[/+]on Nov 5, 2025
@encukou@vstinner I'm open to convincing, but I really think this should have landed in the public API as PyObject_Dump.
My main motivation here is brevity when debugging: _PyObject_Dump is quick to type, and PyObject_Dump is even quicker. I see PyUnstable_Object_Dump as a significant downgrade there.
I do understand that we shouldn't necessarily name things based on how easy they are to type, but I'm also not particularly convinced that we're helping anything by putting this in PyUnstable:
As far as I can tell, the motivation for moving this to PyUnstable was that it's not suitable for user code, but I don't think that's necessarily true. I could absolutely see myself using this in an extension to output debug information to a user when something has gone horribly wrong, because it's more reliable and helpful than something like PyObject_Print or PyFile_WriteObject.
To me, this seems like a misuse of the unstable API; we're not alleviating any future maintenance burden, because _PyObject_Dump is made up of components that are already part of the stable ABI (the type, the reference count, and the __repr__). Since it would require a huge API break to remove any of those from the C API, I don't see how we're saving anything. Again, if we're concerned about users relying on the exact output, we can document the output as unstable without making the whole API unstable.
I know I'm sounding stubborn and tumultuous, but please consider promoting this to the non-unstable API.
To me, the tiers aren't only about stability guarantees, but also about overall polish. The hard-coded stderr here is the biggest red flag: why shouldn't the info be available for loggers or HTML templates, or as part of an exception message?
I could absolutely see myself using this in an extension to output debug information to a user when something has gone horribly wrong
My imagination is lacking here. Do you have a concrete example of the “something”?
Situations I can think of call for printing either less info, or more (type-specific) info.
When you have the time to think about a good message for users, you can do better than what Dump does.
brevity when debugging
Which is why I use p *v and p *v->ob_type in GDB, rather than _PyObject_Dump.
(I guess with alias -a o = p _PyObject_Dump I could do a(v))
The hard-coded stderr here is the biggest red flag: why shouldn't the info be available for loggers or HTML templates, or as part of an exception message?
My imagination is lacking here. Do you have a concrete example of the “something”?
I think one would generally use _PyObject_Dump when they're pretty sure that the program is about to crash. In my case, I have a number of "runtime assertions" in some of my extensions that will call abort() after printing a message. For example, here; if I had written that more recently, I'd probably have added a _PyObject_Dump(item) call, because if that path is hit, there's almost certainly memory corruption going on.
In Nuitka, we have some CHECK_OBJECT* macros for common object assertions, and I'm honestly surprised we're not already using _PyObject_Dump there. I'll probably change that sometime soon.
Which is why I use p *v and p *v->ob_type in GDB, rather than _PyObject_Dump.
Me too sometimes, but _PyObject_Dump will also give you the repr, which is nice.
PyUnstable prefix is justified by two things: the function hardcodes stderr stream and the output is not well defined.
We could add a parameter to select the stream. The stable ABI discourages usage of FILE* parameters. We could use an int file descriptor instead, but IMO it would make the function less convenient to use (having to pass an "arbitrary" file descriptor 2, or fileno(stderr), to each call).
I don't think that we should specify the output format since it's a debugging function.
My main motivation here is brevity when debugging: _PyObject_Dump is quick to type, and PyObject_Dump is even quicker. I see PyUnstable_Object_Dump as a significant downgrade there.
I think that it's just about changing your habits, it's not a big deal. gdb can complete function names with TAB for example :-)
As far as I can tell, the motivation for moving this to PyUnstable was that it's not suitable for user code
Exposing the function in the public C API makes it easier to use in 3rd party code. It provides a warranty that the function is not going to be removed in 3.x.y bugfix releases.
PyUnstable prefix is justified by two things: the function hardcodes stderr stream and the output is not well defined.
Hardcoding stderr makes sense to me, since _PyObject_Dump should only be used when the process is about to exit/crash. If you care about the stream, then _PyObject_Dump shouldn't be used anyway.
For the output, why can't we just document that as unstable?
I think that it's just about changing your habits, it's not a big deal. gdb can complete function names with TAB for example :-)
Well, you still need to type at least PyUnstable_Object_D for tab to work.
No benefit, but also no disadvantage except for the CLI debugging use case. That's something we historically didn't take into account much. Possible counterpoints there are:
it's fine with the underscore
you're better off defining an alias
If the gdb use case is important, should we name this Py_Dump? It'd be consistent with not having PyObject_IncRef, PyObject_TYPE or PyObject_IsTrue.
Activity
pythongh-141070: Add PyObject_Dump() function
pythongh-141070: Add PyObject_Dump() function
[-][C API] Promote _PyObject_Dump() as a public function[/-][+][C API] Promote _PyObject_Dump() to a public function[/+]gh-141070: Add PyUnstable_Object_Dump() function (#141072)
ZeroIntensity commentedon Nov 20, 2025
@encukou @vstinner I'm open to convincing, but I really think this should have landed in the public API as
PyObject_Dump.My main motivation here is brevity when debugging:
_PyObject_Dumpis quick to type, andPyObject_Dumpis even quicker. I seePyUnstable_Object_Dumpas a significant downgrade there.I do understand that we shouldn't necessarily name things based on how easy they are to type, but I'm also not particularly convinced that we're helping anything by putting this in
PyUnstable:PyUnstablewas that it's not suitable for user code, but I don't think that's necessarily true. I could absolutely see myself using this in an extension to output debug information to a user when something has gone horribly wrong, because it's more reliable and helpful than something likePyObject_PrintorPyFile_WriteObject._PyObject_Dumpis made up of components that are already part of the stable ABI (the type, the reference count, and the__repr__). Since it would require a huge API break to remove any of those from the C API, I don't see how we're saving anything. Again, if we're concerned about users relying on the exact output, we can document the output as unstable without making the whole API unstable.I know I'm sounding stubborn and tumultuous, but please consider promoting this to the non-unstable API.
encukou commentedon Nov 20, 2025
To me, the tiers aren't only about stability guarantees, but also about overall polish. The hard-coded stderr here is the biggest red flag: why shouldn't the info be available for loggers or HTML templates, or as part of an exception message?
My imagination is lacking here. Do you have a concrete example of the “something”?
Situations I can think of call for printing either less info, or more (type-specific) info.
When you have the time to think about a good message for users, you can do better than what
Dumpdoes.Which is why I use
p *vandp *v->ob_typein GDB, rather than_PyObject_Dump.(I guess with
alias -a o = p _PyObject_DumpI could doa(v))Should we add
_Py_Dump, orPy_Dump?ZeroIntensity commentedon Nov 20, 2025
I think one would generally use
_PyObject_Dumpwhen they're pretty sure that the program is about to crash. In my case, I have a number of "runtime assertions" in some of my extensions that will callabort()after printing a message. For example, here; if I had written that more recently, I'd probably have added a_PyObject_Dump(item)call, because if that path is hit, there's almost certainly memory corruption going on.In Nuitka, we have some
CHECK_OBJECT*macros for common object assertions, and I'm honestly surprised we're not already using_PyObject_Dumpthere. I'll probably change that sometime soon.Me too sometimes, but
_PyObject_Dumpwill also give you the repr, which is nice.What are you envisioning?
vstinner commentedon Nov 20, 2025
PyUnstableprefix is justified by two things: the function hardcodesstderrstream and the output is not well defined.We could add a parameter to select the stream. The stable ABI discourages usage of
FILE*parameters. We could use anintfile descriptor instead, but IMO it would make the function less convenient to use (having to pass an "arbitrary" file descriptor 2, orfileno(stderr), to each call).I don't think that we should specify the output format since it's a debugging function.
I think that it's just about changing your habits, it's not a big deal. gdb can complete function names with TAB for example :-)
Exposing the function in the public C API makes it easier to use in 3rd party code. It provides a warranty that the function is not going to be removed in 3.x.y bugfix releases.
ZeroIntensity commentedon Nov 20, 2025
Hardcoding
stderrmakes sense to me, since_PyObject_Dumpshould only be used when the process is about to exit/crash. If you care about the stream, then_PyObject_Dumpshouldn't be used anyway.For the output, why can't we just document that as unstable?
Well, you still need to type at least
PyUnstable_Object_Dfor tab to work.ZeroIntensity commentedon Nov 20, 2025
Basically, my argument is that
_PyObject_Dumpisn't going to benefit from being unstable, so we might as well make it easier to use when debugging.encukou commentedon Nov 26, 2025
No benefit, but also no disadvantage except for the CLI debugging use case. That's something we historically didn't take into account much. Possible counterpoints there are:
If the
gdbuse case is important, should we name thisPy_Dump? It'd be consistent with not havingPyObject_IncRef,PyObject_TYPEorPyObject_IsTrue.ZeroIntensity commentedon Nov 26, 2025
I'd be very happy with
Py_Dump, or evenPyUnstable_Dump, since that's not nearly as cumbersome to type asPyUnstable_Object_Dump.encukou commentedon Nov 27, 2025
Want to start a Discourse topic? More opinions would be helpful here.
ZeroIntensity commentedon Nov 27, 2025
Let's move discussion to https://discuss.python.org/t/bikeshedding-public-function-for-pyobject-dump/105102
pythongh-141070: Add PyUnstable_Object_Dump() function (python#141072)
gh-141070: Rename `PyUnstable_Object_Dump` to `PyObject_Dump` (GH-142848
pythongh-141070: Rename `PyUnstable_Object_Dump` to `PyObject_Dump` (p…