Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pythonnet/pythonnet
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: pythonnet/pythonnet
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: alternative-memleak-fix
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 3 commits
  • 7 files changed
  • 2 contributors

Commits on May 11, 2026

  1. Fix MethodBinding/OverloadMapper memory leak (#691)

    MethodBinding and OverloadMapper held PyObject `target` references that
    were not disposed during tp_clear, leaving Python-side refcount drops to
    wait on the multi-hop .NET finalizer chain. They also shared the same
    C# PyObject instance across mp_subscript/Overloads paths, so freeing one
    could free the underlying Python object out from under the others.
    
    - ExtensionType: add virtual OnClear() hook called from tp_clear before
      the GCHandle is released, letting subclasses eagerly drop owned
      Python references.
    - MethodBinding/OverloadMapper: override OnClear to dispose `target`.
      (`targetType` is intentionally not disposed since Python types are
      long-lived and tracked by other caches.)
    - Take an independent INCREF'd PyObject copy at every site that hands a
      shared target into a new MethodBinding or OverloadMapper, so each
      wrapper owns its own reference.
    
    Result: the three _does_not_leak_memory tests drop from ~485 MB delta
    to ~10 KB delta on Python 3.14.
    greateggsgreg authored and filmor committed May 11, 2026
    Configuration menu
    Copy the full SHA
    a305127 View commit details
    Browse the repository at this point in the history
  2. Tighten leak-test threshold to 10% to actually fail the bug

    The previous 90% threshold (0.9 MB/iter against a 1 MB allocation)
    documented the issue but did not reproduce it: master leaks
    ~600-765 KB/iter, which the 0.9 MB threshold accepts as passing.
    
    Drop the threshold to 10% (104 KB/iter). On the 2026-05-09 verification
    run with Python 3.14 GIL on linux-aarch64:
    
      Without fix (master):   ~572-765 KB/iter (FAIL)
      With fix (this branch): ~-500 B/iter     (PASS)
    
    Margin is roughly 6x in either direction across .NET 8 and .NET 10, so
    the threshold cleanly separates buggy from fixed states without being
    sensitive to GC noise.
    greateggsgreg authored and filmor committed May 11, 2026
    Configuration menu
    Copy the full SHA
    7f8a247 View commit details
    Browse the repository at this point in the history

Commits on May 12, 2026

  1. Bugfix and improvements

    - Handle the `PyType` reference in `OverloadMapper` and `MethodBinding` in the
      same way as the object reference
    - Unconditionally store the `PyType` of the object
    - Introduce `NewReference` helper function for the object and type
      passing
    - Fix the remaining missing reference count bump for the type
      (`MethodObject`)
    - As the count is now correct, `Dispose` the type as well
    filmor committed May 12, 2026
    Configuration menu
    Copy the full SHA
    11bebe4 View commit details
    Browse the repository at this point in the history
Loading