Skip to content

gh-132775: Expand the Capability of Interpreter.call() #133484

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

Merged
merged 13 commits into from
May 30, 2025

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented May 6, 2025

It now supports most callables, full args, and return values.

Comment on lines 235 to 238
def call(self, callable, /, *args, **kwargs):
"""Call the object in the interpreter with given args/kwargs.

Only functions that take no arguments and have no closure
Copy link
Contributor

@neonene neonene May 13, 2025

Choose a reason for hiding this comment

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

The docstring looks partially outdated (here or in Lib/interpreters/__init__.py). The same would apply for _interpretersmodule.c?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@ericsnowcurrently ericsnowcurrently force-pushed the interp-call-expansion branch 4 times, most recently from d58f54e to 4152f17 Compare May 22, 2025 15:16
@ericsnowcurrently ericsnowcurrently marked this pull request as ready for review May 22, 2025 16:34
@ericsnowcurrently ericsnowcurrently removed the request for review from kumaraditya303 May 26, 2025 22:59
@ericsnowcurrently

This comment was marked as outdated.

@bedevere-bot

This comment was marked as outdated.

@ericsnowcurrently

This comment was marked as outdated.

@bedevere-bot

This comment was marked as outdated.

Copy link
Contributor

@neonene neonene left a comment

Choose a reason for hiding this comment

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

This review focuses on the refleaks in test_api (Py_GIL_DISABLED seems to skip the test).

_PyFunction_VerifyStateless:

if (defaults != NULL && defaults != Py_None && PyDict_Size(defaults) > 0)

  • PyDict_Size(defaults) needs PyDict_Check() or _PyErr_Clear().
  • The same goes for PyDict_Size(kwdefaults) at L1275.

Comment on lines 439 to 442
struct interp_call temp = *call;
*call = (struct interp_call){0};
if (temp.func != NULL) {
_PyXIData_Clear(NULL, temp.func);
Copy link
Contributor

Choose a reason for hiding this comment

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

_PyXIData_Clear() here does not work expectedly on MSVC.

struct interp_call temp = *call;
printf("before: %p %p %p\n", temp.func, temp.func->data, temp.func->obj);
*call = (struct interp_call){0};
printf("after : %p %p %p\n", temp.func, temp.func->data, temp.func->obj);

before: 0000000000C3CF58 00000000057763B0 0000000002BFCEF0
after : 0000000000C3CF58 0000000000000000 0000000000000000

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, the logic here is wrong because the pointers in temp point to the call fields, which have been nulled out. I'm fixing that.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

Comment on lines 467 to 472
PyObject *exc = _PyErr_GetRaisedException(tstate);
if (_PyPickle_GetXIData(tstate, func, &call->_preallocated.func) < 0) {
_PyErr_SetRaisedException(tstate, exc);
//unwrap_not_shareable(tstate);
return -1;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Py_DECREF(exc) seems missing after L472.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

}

_PyXI_FreeSession(session);
return res;
Copy link
Contributor

Choose a reason for hiding this comment

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

Py_CLEAR(result.preserved) before L665 seems effective?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

PyObject *func, *args, *kwargs;
if (_interp_call_unpack(call, &func, &args, &kwargs) == 0) {
// Either the problem is intermittent or only affects subinterpreters.
// This is highly unlikely.
Copy link
Contributor

Choose a reason for hiding this comment

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

Py_DECREF(func); Py_DECREF(args); Py_XDECREF(kwargs);?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

if (kwargs_obj != NULL) {
_PyErr_SetString(tstate, PyExc_ValueError, "got unexpected kwargs");
struct interp_call call = {0};
if (_interp_call_pack(tstate, &call, callable, args_obj, kwargs_obj) < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

_interp_call_clear(&call) in the branch?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@ericsnowcurrently
Copy link
Member Author

ericsnowcurrently commented May 28, 2025

  • PyDict_Size(defaults) needs PyDict_Check() or _PyErr_Clear().
  • The same goes for PyDict_Size(kwdefaults) at L1275.

Nice catch. I also got it wrong with defaults because it's supposed to be a tuple, not a dict.

@ericsnowcurrently
Copy link
Member Author

!buildbot AMD64 Fedora Stable Refleaks

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @ericsnowcurrently for commit 17beeda 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F133484%2Fmerge

The command will test the builders whose names match following regular expression: AMD64 Fedora Stable Refleaks

The builders matched are:

  • AMD64 Fedora Stable Refleaks PR

@ericsnowcurrently
Copy link
Member Author

@neonene, thanks again for all the help chasing down leaks! You saved me a bunch of time.

@ericsnowcurrently
Copy link
Member Author

Unless there are any objections, I'll merge this first thing in the morning (~16:00 UTC).

@ericsnowcurrently ericsnowcurrently merged commit 52deabe into python:main May 30, 2025
38 checks passed
@miss-islington-app
Copy link

Thanks @ericsnowcurrently for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 30, 2025
…h-133484)

It now supports most callables, full args, and return values.
(cherry picked from commit 52deabe)

Co-authored-by: Eric Snow <[email protected]>
@ericsnowcurrently ericsnowcurrently deleted the interp-call-expansion branch May 30, 2025 15:15
@bedevere-app
Copy link

bedevere-app bot commented May 30, 2025

GH-134933 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label May 30, 2025
ericsnowcurrently pushed a commit that referenced this pull request May 30, 2025
)

It now supports most callables, full args, and return values.

(cherry picked from commit 52deabe, AKA gh-133484)

Co-authored-by: Eric Snow [email protected]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants