mirror of
https://github.com/pyscript/pyscript.git
synced 2026-02-18 04:01:10 -05:00
Refactor pyexec (#1318)
This is some refactoring I did on the way towards resolving pyscript#1313. I added a new _run_pyscript Python function which executes the code inside a context manager that sets the display target. We can then return a JS object wrapper directly from Python. I moved the "installation" of the pyscript module to loadInterpreter, and pyimport pyscript_py there and give it a type. This avoids a bunch of creating and deleting of proxies for pyscript_py and allows us to give it a type once and for all. I also did some minor logic cleanup in a few places.
This commit is contained in:
@@ -2,8 +2,7 @@ import { getLogger } from './logger';
|
||||
import { ensureUniqueId } from './utils';
|
||||
import { UserError, ErrorCode } from './exceptions';
|
||||
import { InterpreterClient } from './interpreter_client';
|
||||
import type { PyProxyCallable, PyProxy } from 'pyodide';
|
||||
import type { Remote } from 'synclink';
|
||||
import type { PyProxyCallable } from 'pyodide';
|
||||
|
||||
const logger = getLogger('pyexec');
|
||||
|
||||
@@ -13,39 +12,30 @@ export async function pyExec(
|
||||
outElem: HTMLElement,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): Promise<{ result: any }> {
|
||||
const pyscript_py = (await interpreter.pyimport('pyscript')) as Remote<
|
||||
PyProxy & {
|
||||
set_current_display_target(id: string): void;
|
||||
uses_top_level_await(code: string): boolean;
|
||||
}
|
||||
>;
|
||||
ensureUniqueId(outElem);
|
||||
await pyscript_py.set_current_display_target(outElem.id);
|
||||
if (await interpreter._remote.pyscript_py.uses_top_level_await(pysrc)) {
|
||||
const err = new UserError(
|
||||
ErrorCode.TOP_LEVEL_AWAIT,
|
||||
'The use of top-level "await", "async for", and ' +
|
||||
'"async with" has been removed.' +
|
||||
'\nPlease write a coroutine containing ' +
|
||||
'your code and schedule it using asyncio.ensure_future() or similar.' +
|
||||
'\nSee https://docs.pyscript.net/latest/guides/asyncio.html for more information.',
|
||||
);
|
||||
displayPyException(err, outElem);
|
||||
return { result: undefined };
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
if (await pyscript_py.uses_top_level_await(pysrc)) {
|
||||
throw new UserError(
|
||||
ErrorCode.TOP_LEVEL_AWAIT,
|
||||
'The use of top-level "await", "async for", and ' +
|
||||
'"async with" has been removed.' +
|
||||
'\nPlease write a coroutine containing ' +
|
||||
'your code and schedule it using asyncio.ensure_future() or similar.' +
|
||||
'\nSee https://docs.pyscript.net/latest/guides/asyncio.html for more information.',
|
||||
);
|
||||
}
|
||||
return await interpreter.run(pysrc);
|
||||
} catch (e) {
|
||||
const err = e as Error;
|
||||
// XXX: currently we display exceptions in the same position as
|
||||
// the output. But we probably need a better way to do that,
|
||||
// e.g. allowing plugins to intercept exceptions and display them
|
||||
// in a configurable way.
|
||||
displayPyException(err, outElem);
|
||||
return { result: undefined };
|
||||
}
|
||||
} finally {
|
||||
await pyscript_py.set_current_display_target(undefined);
|
||||
await pyscript_py.destroy();
|
||||
return await interpreter.run(pysrc, outElem.id);
|
||||
} catch (e) {
|
||||
const err = e as Error;
|
||||
// XXX: currently we display exceptions in the same position as
|
||||
// the output. But we probably need a better way to do that,
|
||||
// e.g. allowing plugins to intercept exceptions and display them
|
||||
// in a configurable way.
|
||||
displayPyException(err, outElem);
|
||||
return { result: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user