Skip to content

Commit

Permalink
Add callSyncifyingKwargs, fix runPythonSyncifying to accept `file…
Browse files Browse the repository at this point in the history
…name` argument

And fix up various documentation comments
  • Loading branch information
hoodmane committed Jan 9, 2024
1 parent 9eadff2 commit c59a553
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 26 deletions.
37 changes: 34 additions & 3 deletions src/core/pyproxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2368,9 +2368,10 @@ export class PyCallableMethods {

/**
* Call the function with stack switching enabled. Functions called this way
* can use :py:meth:`PyodideFuture.syncify` to block until a
* :py:class:`Future` or :js:class:`Promise` is resolved. Only works in
* runtimes with JS Promise integration.
* can use
* :py:meth:`PyodideFuture.syncify() <pyodide.webloop.PyodideFuture.syncify>`
* to block until a :py:class:`~asyncio.Future` or :js:class:`Promise` is
* resolved. Only works in runtimes with JS Promise integration.
*
* .. admonition:: Experimental
* :class: warning
Expand All @@ -2383,6 +2384,36 @@ export class PyCallableMethods {
return callPyObjectKwargsSuspending(_getPtr(this), jsargs, {});
}

/**
* Call the function with stack switching enabled. The last argument must be
* an object with the keyword arguments. Functions called this way can use
* :py:meth:`PyodideFuture.syncify() <pyodide.webloop.PyodideFuture.syncify>`
* to block until a :py:class:`~asyncio.Future` or :js:class:`Promise` is
* resolved. Only works in runtimes with JS Promise integration.
*
* .. admonition:: Experimental
* :class: warning
*
* This feature is not yet stable.
*
* @experimental
*/
callSyncifyingKwargs(...jsargs: any) {
if (jsargs.length === 0) {
throw new TypeError(
"callKwargs requires at least one argument (the key word argument object)",
);
}
let kwargs = jsargs.pop();
if (
kwargs.constructor !== undefined &&
kwargs.constructor.name !== "Object"
) {
throw new TypeError("kwargs argument is not an object");
}
return callPyObjectKwargsSuspending(_getPtr(this), jsargs, kwargs);
}

/**
* The ``bind()`` method creates a new function that, when called, has its
* ``this`` keyword set to the provided value, with a given sequence of
Expand Down
43 changes: 20 additions & 23 deletions src/js/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,16 @@ export class PyodideAPI {
* expression (and the code doesn't end with a semicolon), the value of the
* expression is returned.
*
* @param code Python code to evaluate
* @param code The Python code to run
* @param options
* @param options.globals An optional Python dictionary to use as the globals.
* Defaults to :js:attr:`pyodide.globals`.
* @param options.locals An optional Python dictionary to use as the locals.
* Defaults to the same as ``globals``.
* @param options.filename An optional string to use as the filename. Defaults
* to "<exec>". If the filename does not start with "<" and end with ">",
* the source code will be added to the Python linecache and tracebacks
* will show source lines.
* @param options.filename An optional string to use as the file name.
* Defaults to ``"<exec>"``. If a custom file name is given, the
* traceback for any exception that is thrown will show source lines
* (unless the given file name starts with ``<`` and ends with ``>``).
* @returns The result of the Python code translated to JavaScript. See the
* documentation for :py:func:`~pyodide.code.eval_code` for more info.
* @example
Expand Down Expand Up @@ -262,16 +262,16 @@ export class PyodideAPI {
* import any python packages referenced via ``import`` statements in your
* code. This function will no longer do it for you.
*
* @param code Python code to evaluate
* @param code The Python code to run
* @param options
* @param options.globals An optional Python dictionary to use as the globals.
* Defaults to :js:attr:`pyodide.globals`.
* @param options.locals An optional Python dictionary to use as the locals.
* Defaults to the same as ``globals``.
* @param options.filename An optional string to use as the filename. Defaults
* to "<exec>". If the filename does not start with "<" and end with ">",
* the source code will be added to the Python linecache and tracebacks
* will show source lines.
* @param options.filename An optional string to use as the file name.
* Defaults to ``"<exec>"``. If a custom file name is given, the
* traceback for any exception that is thrown will show source lines
* (unless the given file name starts with ``<`` and ends with ``>``).
* @returns The result of the Python code translated to JavaScript.
* @async
*/
Expand All @@ -288,39 +288,36 @@ export class PyodideAPI {
/**
* Runs a Python code string like :js:func:`pyodide.runPython` but with stack
* switching enabled. Code executed in this way can use
* :py:meth:`PyodideFuture.syncify` to block until a :py:class:`Future` or
* :js:class:`Promise` is resolved. Only works in runtimes with JS Promise
* Integration enabled.
* :py:meth:`PyodideFuture.syncify() <pyodide.webloop.PyodideFuture.syncify>`
* to block until a :py:class:`~asyncio.Future` or :js:class:`Promise` is
* resolved. Only works in runtimes with JS Promise Integration enabled.
*
* .. admonition:: Experimental
* :class: warning
*
* This feature is not yet stable.
*
* @experimental
* @param code The Python code to run
* @param options
* @param options.globals An optional Python dictionary to use as the globals.
* Defaults to :js:attr:`pyodide.globals`.
* @param options.locals An optional Python dictionary to use as the locals.
* Defaults to the same as ``globals``.
* @param options.filename An optional string to use as the filename. Defaults
* to "<exec>". If the filename does not start with "<" and end with
* ">", the source code will be added to the Python linecache and
* tracebacks will show source lines.
* @param options.filename An optional string to use as the file name.
* Defaults to ``"<exec>"``. If a custom file name is given, the
* traceback for any exception that is thrown will show source lines
* (unless the given file name starts with ``<`` and ends with ``>``).
* @returns The result of the Python code translated to JavaScript.
*/
static async runPythonSyncifying(
code: string,
options: { globals?: PyProxy; locals?: PyProxy } = {},
options: { globals?: PyProxy; locals?: PyProxy; filename?: string } = {},
): Promise<any> {
if (!options.globals) {
options.globals = API.globals;
}
return API.pyodide_code.eval_code.callSyncifying(
code,
options.globals,
options.locals,
);
return API.pyodide_code.eval_code.callSyncifyingKwargs(code, options);
}

/**
Expand Down

0 comments on commit c59a553

Please sign in to comment.