GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — C API: _PyObject_VisitManagedDict() function should be public · Issue #107073 · python/cpython

C API: _PyObject_VisitManagedDict() function should be public #107073

New issue
Copy link
New issue
Copy link
Closed
Closed
C API: _PyObject_VisitManagedDict() function should be public#107073
Copy link
Labels
topic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@vstinner
vstinner
opened on Jul 22, 2023
Issue body actions

tl; dr: _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() function should be public.

If a C extension implements a type as a heap type, the type must support the GC protocol: it must implement visit and clear functions, and the dealloc function must DECREF the type.

It seems like if a heap type uses the new Py_TPFLAGS_MANAGED_DICT flag, the visit function must call _PyObject_VisitManagedDict() and the clear function must call _PyObject_ClearManagedDict(). Correct me if I'm wrong.

Problem: _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() functions are private. IMO they must be public.

Either Py_TPFLAGS_MANAGED_DICT flag must be private, or it should be public and all related helper functions should be public as well.

Py_TPFLAGS_MANAGED_DICT was added to Python 3.11.

_PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() functions were added to Python 3.12.

In Python 3.12, typing.TypeVar, typing.ParamSpec, typing.TypeVarTuple are implemented with Py_TPFLAGS_MANAGED_DICT (and use the 2 helper functions).

In Python 3.13, _asyncio.Future and _asyncio.Task are also implemented with Py_TPFLAGS_MANAGED_DICT (and use the 2 helper functions).

Note: In Objects/typeobject.c, subtype_traverse() calls _PyObject_VisitManagedDict() in some cases, and subtype_clear() calls _PyObject_ClearManagedDict() in some cases.

Linked PRs

  • gh-107073: Make PyObject_VisitManagedDict() public #108763
  • gh-107073: Mention pythoncapi-compat for PyObject_VisitManagedDict() #110291
  • gh-107073: fix relevant typo in PyObject_ClearManagedDict #140032
  • [3.14] gh-107073: fix relevant typo in PyObject_ClearManagedDict (GH-140032) #140033
  • [3.13] gh-107073: fix relevant typo in PyObject_ClearManagedDict (GH-140032) #140034

Activity

  1. vstinner
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    topic-C-API
    on Jul 22, 2023
  2. vstinner commented on Jul 22, 2023

    @vstinner
    vstinner
    on Jul 22, 2023
    MemberAuthor
    More actions

    cc @brandtbucher @iritkatriel: Tell me if I'm correct. If yes, I can create a PR to fix this issue.

  3. vstinner commented on Jul 22, 2023

    @vstinner
    vstinner
    on Jul 22, 2023
    MemberAuthor
    More actions

    The doc doesn't say much about how a heap type should be implemented:

    • https://docs.python.org/dev/c-api/typeobj.html#c.Py_TPFLAGS_MANAGED_DICT
  4. vstinner commented on Jul 22, 2023

    @vstinner
    vstinner
    on Jul 22, 2023
    MemberAuthor
    More actions

    pybind11 (C++) uses a strange hack using *_PyObject_GetDictPtr() expression (note the * at the start) which uses the private _PyObject_GetDictPtr() function:
    https://github.com/pybind/pybind11/blob/8d08dc64ca300342852ceaa7b1d65fe9f69dab06/include/pybind11/detail/class.h#L523-L539

    traverse:

        PyObject *&dict = *_PyObject_GetDictPtr(self);
        Py_VISIT(dict);

    clear:

        PyObject *&dict = *_PyObject_GetDictPtr(self);
        Py_CLEAR(dict);

    By the way, should we also make _PyObject_GetDictPtr() function public?

  5. vstinner commented on Jul 23, 2023

    @vstinner
    vstinner
    on Jul 23, 2023
    MemberAuthor
    More actions

    cc @colesbury @ambv

    Reacted by Donghee Na
  6. vstinner
    added 2 commits that reference this issue on Sep 1, 2023

    pythongh-107073: Make PyObject_VisitManagedDict() public

    a8a5a7b

    pythongh-107073: Make PyObject_VisitManagedDict() public

    6d22132
  7. vstinner commented on Sep 1, 2023

    @vstinner
    vstinner
    on Sep 1, 2023
    MemberAuthor
    More actions

    I'm not sure if _PyObject_GetDictPtr() should be made public or not.

  8. vstinner
    added a commit that references this issue on Sep 4, 2023

    pythongh-107073: Make PyObject_VisitManagedDict() public

    a13d2d5
  9. vstinner
    added 2 commits that reference this issue on Sep 13, 2023

    pythongh-107073: Make PyObject_VisitManagedDict() public

    00af801

    pythongh-107073: Make PyObject_VisitManagedDict() public

    8e9d04d
  10. markshannon commented on Oct 2, 2023

    @markshannon
    markshannon
    on Oct 2, 2023
    Member
    More actions

    Just to be clear, the root problem here is that if a class is defined using PyType_FromSpec() and Py_TPFLAGS_MANAGED_DICT is set, there is no way to implement tp_visit and tp_clear.

    That can be fixed by adding _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() (or something with equivalent functionality) to the API so that tp_visit and tp_clear can be implemented.

    However, PyType_FromSpec() inherits many of the flaws of statically declaring PyTypeObjects.
    We should offer a better way to build classes, so maybe add a PyUnstable_ prefix, as we want to come up with a better approach?

  11. markshannon commented on Oct 2, 2023

    @markshannon
    markshannon
    on Oct 2, 2023
    Member
    More actions

    _PyObject_GetDictPtr() should not be made public.
    We should remove it, but not while anyone still uses tp_dictoffset.

  12. markshannon commented on Oct 2, 2023

    @markshannon
    markshannon
    on Oct 2, 2023
    Member
    More actions

    If the PyUnstable_ prefix had existed when these functions were added, I would have used it.

    Having managed dicts is stable, so the functions will continue to have meaning if even the implementation changes.
    In that sense they are stable.

    However, we want to move the responsibility for visiting and clearing from C extensions to the VM. Once we have done that we will no longer need _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict(), so there is an argument for making them PyUnstable.

    On balance, I think they should be public. Making object layout the full responsibility of the VM won't happen for a few releases and even when it does it will need a longish deprecation to remove all the old API. So, we might as well add _PyObject_VisitManagedDict() and _PyObject_ClearManagedDict() to the stable API.

    Reacted by Petr Viktorin
  13. vstinner
    added a commit that references this issue on Oct 2, 2023

    gh-107073: Make PyObject_VisitManagedDict() public (#108763)

    fc2cb86
  14. vstinner commented on Oct 3, 2023

    @vstinner
    vstinner
    on Oct 3, 2023
    MemberAuthor
    More actions

    However, we want to move the responsibility for visiting and clearing from C extensions to the VM.

    Py_VISIT() should only be called once by the GC. So either calling PyObject_VisitManagedDict() should be the responsibility of the C extension, or the VM. But it cannot be both. And it cannot change without adding a new type flag, otherwise it would break the backward compatibility, since PyObject_VisitManagedDict() is public in Python 3.13. No?

    On balance, I think they should be public. Making object layout the full responsibility of the VM won't happen for a few releases

    That sounds like a good practical trade-off.

  15. vstinner commented on Oct 3, 2023

    @vstinner
    vstinner
    on Oct 3, 2023
    MemberAuthor
    More actions

    I added PyObject_VisitManagedDict() and PyObject_ClearManagedDict() functions to pythoncapi-compat for Python 3.11 and Python 3.12 using _PyObject_GetDictPtr(): python/pythoncapi-compat@a594354

  16. vstinner
    added a commit that references this issue on Oct 3, 2023

    pythongh-107073: Mention pythoncapi-compat for PyObject_VisitManagedD…

    6eb6cd5
  17. vstinner
    closed this as completedon Oct 3, 2023
  18. vstinner
    added a commit that references this issue on Oct 3, 2023

    gh-107073: Mention pythoncapi-compat for PyObject_VisitManagedDict() (#…

    eeb4e97
  19. Glyphack
    added 2 commits that reference this issue on Sep 2, 2024

    pythongh-107073: Make PyObject_VisitManagedDict() public (python#108763)

    2d367d8

    pythongh-107073: Mention pythoncapi-compat for PyObject_VisitManagedD…

    d024aa7
  20. vstinner
    added a commit that references this issue on Oct 13, 2025

    gh-107073: fix relevant typo in `PyObject_ClearManagedDict` (#140032)

    52996aa
  21. miss-islington
    added 2 commits that reference this issue on Oct 13, 2025

    pythongh-107073: fix relevant typo in `PyObject_ClearManagedDict` (py…

    3e4a8a1

    pythongh-107073: fix relevant typo in `PyObject_ClearManagedDict` (py…

    6c6bc12
  22. picnixz
    added 2 commits that reference this issue on Oct 13, 2025

    [3.13] gh-107073: fix relevant typo in `PyObject_ClearManagedDict` (G…

    2783841

    [3.14] gh-107073: fix relevant typo in `PyObject_ClearManagedDict` (G…

    3cef780
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

    topic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.