Skip to content

[C API] Promote _PyObject_Dump() to a public function #141070

Description

@vstinner

As a follow-up of discussion, I propose promoting _PyObject_Dump() to a public function: PyObject_Dump().

Linked PRs

Activity

  1. added 2 commits that reference this issue on Nov 5, 2025
  2. 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
  3. added a commit that references this issue on Nov 18, 2025
  4. ZeroIntensity commented on Nov 20, 2025

    @ZeroIntensity
    Member

    @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:

    1. 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.
    2. 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.

  5. encukou commented on Nov 20, 2025

    @encukou
    Member

    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))

    Should we add _Py_Dump, or Py_Dump?

  6. ZeroIntensity commented on Nov 20, 2025

    @ZeroIntensity
    Member

    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.

    Should we add _Py_Dump, or Py_Dump?

    What are you envisioning?

  7. vstinner commented on Nov 20, 2025

    @vstinner
    MemberAuthor

    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.

  8. ZeroIntensity commented on Nov 20, 2025

    @ZeroIntensity
    Member

    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.

  9. ZeroIntensity commented on Nov 20, 2025

    @ZeroIntensity
    Member

    Basically, my argument is that _PyObject_Dump isn't going to benefit from being unstable, so we might as well make it easier to use when debugging.

  10. encukou commented on Nov 26, 2025

    @encukou
    Member

    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.

  11. ZeroIntensity commented on Nov 26, 2025

    @ZeroIntensity
    Member

    I'd be very happy with Py_Dump, or even PyUnstable_Dump, since that's not nearly as cumbersome to type as PyUnstable_Object_Dump.

  12. encukou commented on Nov 27, 2025

    @encukou
    Member

    Want to start a Discourse topic? More opinions would be helpful here.

  13. ZeroIntensity commented on Nov 27, 2025

    @ZeroIntensity
    Member
  14. added a commit that references this issue on Dec 6, 2025
  15. added a commit that references this issue on Jan 16, 2026
  16. added a commit that references this issue on Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions