gh-132775: Expand the Capability of Interpreter.call() (gh-133484) · python/cpython@52deabe · GitHub
Skip to content

Commit 52deabe

Browse files
gh-132775: Expand the Capability of Interpreter.call() (gh-133484)
It now supports most callables, full args, and return values.
1 parent eb145fa commit 52deabe

10 files changed

Lines changed: 1257 additions & 301 deletions

File tree

Include/internal/pycore_crossinterp.h

Lines changed: 27 additions & 8 deletions

Lib/test/_code_definitions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ def spam_with_globals_and_builtins():
5757
print(res)
5858

5959

60+
def spam_full_args(a, b, /, c, d, *args, e, f, **kwargs):
61+
return (a, b, c, d, e, f, args, kwargs)
62+
63+
64+
def spam_full_args_with_defaults(a=-1, b=-2, /, c=-3, d=-4, *args,
65+
e=-5, f=-6, **kwargs):
66+
return (a, b, c, d, e, f, args, kwargs)
67+
68+
6069
def spam_args_attrs_and_builtins(a, b, /, c, d, *args, e, f, **kwargs):
6170
if args.__len__() > 2:
6271
return None
@@ -67,6 +76,10 @@ def spam_returns_arg(x):
6776
return x
6877

6978

79+
def spam_raises():
80+
raise Exception('spam!')
81+
82+
7083
def spam_with_inner_not_closure():
7184
def eggs():
7285
pass
@@ -177,8 +190,11 @@ def ham_C_closure(z):
177190
spam_minimal,
178191
spam_with_builtins,
179192
spam_with_globals_and_builtins,
193+
spam_full_args,
194+
spam_full_args_with_defaults,
180195
spam_args_attrs_and_builtins,
181196
spam_returns_arg,
197+
spam_raises,
182198
spam_with_inner_not_closure,
183199
spam_with_inner_closure,
184200
spam_annotated,
@@ -219,8 +235,10 @@ def ham_C_closure(z):
219235
spam,
220236
spam_minimal,
221237
spam_with_builtins,
238+
spam_full_args,
222239
spam_args_attrs_and_builtins,
223240
spam_returns_arg,
241+
spam_raises,
224242
spam_annotated,
225243
spam_with_inner_not_closure,
226244
spam_with_inner_closure,
@@ -238,6 +256,7 @@ def ham_C_closure(z):
238256
STATELESS_CODE = [
239257
*STATELESS_FUNCTIONS,
240258
script_with_globals,
259+
spam_full_args_with_defaults,
241260
spam_with_globals_and_builtins,
242261
spam_full,
243262
]
@@ -248,6 +267,7 @@ def ham_C_closure(z):
248267
script_with_explicit_empty_return,
249268
spam_minimal,
250269
spam_with_builtins,
270+
spam_raises,
251271
spam_with_inner_not_closure,
252272
spam_with_inner_closure,
253273
]

Lib/test/support/interpreters/__init__.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -226,33 +226,32 @@ def exec(self, code, /):
226226
if excinfo is not None:
227227
raise ExecutionFailed(excinfo)
228228

229-
def call(self, callable, /):
230-
"""Call the object in the interpreter with given args/kwargs.
229+
def _call(self, callable, args, kwargs):
230+
res, excinfo = _interpreters.call(self._id, callable, args, kwargs, restrict=True)
231+
if excinfo is not None:
232+
raise ExecutionFailed(excinfo)
233+
return res
231234

232-
Only functions that take no arguments and have no closure
233-
are supported.
235+
def call(self, callable, /, *args, **kwargs):
236+
"""Call the object in the interpreter with given args/kwargs.
234237
235-
The return value is discarded.
238+
Nearly all callables, args, kwargs, and return values are
239+
supported. All "shareable" objects are supported, as are
240+
"stateless" functions (meaning non-closures that do not use
241+
any globals). This method will fall back to pickle.
236242
237243
If the callable raises an exception then the error display
238-
(including full traceback) is send back between the interpreters
244+
(including full traceback) is sent back between the interpreters
239245
and an ExecutionFailed exception is raised, much like what
240246
happens with Interpreter.exec().
241247
"""
242-
# XXX Support args and kwargs.
243-
# XXX Support arbitrary callables.
244-
# XXX Support returning the return value (e.g. via pickle).
245-
excinfo = _interpreters.call(self._id, callable, restrict=True)
246-
if excinfo is not None:
247-
raise ExecutionFailed(excinfo)
248+
return self._call(callable, args, kwargs)
248249

249-
def call_in_thread(self, callable, /):
250+
def call_in_thread(self, callable, /, *args, **kwargs):
250251
"""Return a new thread that calls the object in the interpreter.
251252
252253
The return value and any raised exception are discarded.
253254
"""
254-
def task():
255-
self.call(callable)
256-
t = threading.Thread(target=task)
255+
t = threading.Thread(target=self._call, args=(callable, args, kwargs))
257256
t.start()
258257
return t

Lib/test/test_code.py

Lines changed: 46 additions & 2 deletions

0 commit comments

Comments
 (0)