Skip to content

fix: release PyObject.call result references after GC - #91

Merged
DjDeveloperr merged 1 commit into
denosaurs:mainfrom
mchao123:fix/call-result-refcount
Sep 16, 2026
Merged

DjDeveloperr merged 1 commit into
denosaurs:mainfrom
mchao123:fix/call-result-refcount

Conversation

@mchao123

Copy link
Copy Markdown
Contributor

Summary

PyObject.call() receives a new Python reference from PyObject_Call, but the returned PyObject is not registered with the module's FinalizationRegistry. Once the JS wrapper is collected, that native reference is never released.

This is observable without memory profiling:

100 calls to a function returning the same object
Python refcount: 3 -> 103

The added regression test asserts that the refcount returns to its baseline after GC.

Fix

Register the call result with refregistry, tying the new Python reference to the lifetime of its JS wrapper. Existing .owned semantics remain unchanged.

Verification

  • deno task test
    • test/test.ts: 15 passed
    • test/test_with_gc.ts: 4 passed
  • deno task check
  • deno fmt --check

@mchao123
mchao123 force-pushed the fix/call-result-refcount branch from 4630880 to cf4a905 Compare September 16, 2026 02:48

@DjDeveloperr DjDeveloperr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@DjDeveloperr
DjDeveloperr merged commit b7a51a3 into denosaurs:main Sep 16, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants