Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consequences of using Py_TPFLAGS_HAVE_GC are incompletely explained #50378

Closed
exarkun mannequin opened this issue May 27, 2009 · 5 comments
Closed

Consequences of using Py_TPFLAGS_HAVE_GC are incompletely explained #50378

exarkun mannequin opened this issue May 27, 2009 · 5 comments
Labels
docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@exarkun
Copy link
Mannequin

exarkun mannequin commented May 27, 2009

BPO 6128
Nosy @birkenfeld, @tiran
Files
  • gcsupport-doc.diff: Proposed doc patch for gcsupport.rst
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2009-05-27.20:48:54.537>
    labels = ['type-feature', 'docs']
    title = 'Consequences of using Py_TPFLAGS_HAVE_GC are incompletely explained'
    updated_at = <Date 2014-02-03.15:37:37.940>
    user = 'https://bugs.python.org/exarkun'

    bugs.python.org fields:

    activity = <Date 2014-02-03.15:37:37.940>
    actor = 'BreamoreBoy'
    assignee = 'docs@python'
    closed = False
    closed_date = None
    closer = None
    components = ['Documentation']
    creation = <Date 2009-05-27.20:48:54.537>
    creator = 'exarkun'
    dependencies = []
    files = ['33497']
    hgrepos = []
    issue_num = 6128
    keywords = ['patch']
    message_count = 4.0
    messages = ['88441', '112282', '192371', '208283']
    nosy_count = 5.0
    nosy_names = ['georg.brandl', 'exarkun', 'christian.heimes', 'docs@python', 'Greek0']
    pr_nums = []
    priority = 'low'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue6128'
    versions = ['Python 3.4', 'Python 3.5']

    @exarkun
    Copy link
    Mannequin Author

    exarkun mannequin commented May 27, 2009

    Creation of GC'd types is explained at
    <http://docs.python.org/c-api/gcsupport.html\>.

    The docs claim that PyObject_GC_Track must be called once an object
    created with PyObject_GC_New is initialized. The docs fail to explain
    what should be done if there is an error during initialization of an
    object created with PyObject_GC_New. Should PyObject_GC_Track still be
    called? Should some other API be called to free the object?

    Overall, the docs are missing an explanation of the overall working of
    the GC and GC APIs, so it is hard to build an understanding of the
    system. Without an understand, it's difficult to read between the lines
    of the API docs, meaning they need to cover every possible case, which
    they don't currently.

    @exarkun exarkun mannequin assigned birkenfeld May 27, 2009
    @exarkun exarkun mannequin added the docs Documentation in the Doc dir label May 27, 2009
    @BreamoreBoy
    Copy link
    Mannequin

    BreamoreBoy mannequin commented Aug 1, 2010

    Can someone in the know provide a doc patch for this?

    @BreamoreBoy BreamoreBoy mannequin assigned docspython and unassigned birkenfeld Aug 1, 2010
    @tiran
    Copy link
    Member

    tiran commented Jul 5, 2013

    Python's extension modules aren't consistent. Some places deallocate the object with PyObject_Del(), other places are using PyObject_GC_Del() or simple Py_DECREF().

    @tiran tiran added the type-feature A feature request or enhancement label Jul 5, 2013
    @Greek0
    Copy link
    Mannequin

    Greek0 mannequin commented Jan 16, 2014

    I concur that this aspect of writing Python types in C/C++ needs better
    documentation. For a new extension writer (like me), it is not obvious when
    PyObject_GC_Track/PyObject_GC_UnTrack must be called or not. Similarly, it is
    not clear from the current documentation how to ensure that memory is allocated
    with PyObject_GC_New.

    The gcsupport documentation suffers from being written from the perspective
    of the GC, instead of the perspective of extension writers. Thus, I've attached
    a patch that tries to shed some light on how to correctly write types
    implementing cyclic GC support.

    I'd appreciate comments/editing suggestions/advice and would welcome the patch
    to go into Python in some form. I myself consider the change to be trivial, but
    if necessary I can sign the contributor agreement.

    --
    PS: Informal explanation about what's really going on:

    The Python GC code deals with memory allocation, not with initialization in any
    way. For most extension types, allocation is handled by tp_alloc which is
    called typically called from tp_new (either the default tp_new or your own
    tp_new handler).

    The default tp_alloc (PyType_GenericAlloc()) looks at tp_flags, and if
    Py_TPFLAGS_HAVE_GC is specified, it uses the appropriate GC malloc function and
    calls _PyObject_GC_TRACK when finished). Thus, if you allocate your memory via
    tp_alloc, and don't override the tp_alloc handler, you've just fulfilled the
    GC's constructor requirements.

    Similarly, the GC doesn't care about object destruction. It cares about freeing
    memory, that is tp_free, NOT tp_dealloc! Again, if you don't intentionally
    provide a custom tp_free handler, the default one will take care to obey the GC
    rules.

    Thus, most extension writers can get away with 4 simple rules:

    • Set Py_TPFLAGS_HAVE_GC in tp_flags.
    • Do not specify tp_alloc or tp_free.
    • Make sure your object actually allocates it's memory via tp_alloc.
      Three possibilities to achieve this:
      + Do not add a tp_new handler, or
      + Call tp_alloc from your tp_new handler, or
      + Call a base class's tp_new from your own tp_new handler
    • Implement tp_traverse and tp_clear. They are usually straight-forward.

    And if you really do want a custom allocator, you're screwed anyway, as the
    last part of my patch hints at. Custom memory management is just not compatible with the GC at this point.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @erlend-aasland
    Copy link
    Contributor

    The Supporting Garbage Collection section of the C API docs has changed considerably since 2009. I suggest closing this as outdated.

    @erlend-aasland erlend-aasland added the pending The issue will be closed if no feedback is provided label Jun 27, 2023
    @hugovk hugovk closed this as not planned Won't fix, can't repro, duplicate, stale Oct 6, 2023
    @erlend-aasland erlend-aasland removed the pending The issue will be closed if no feedback is provided label Oct 6, 2023
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    docs Documentation in the Doc dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants