8000 split interpreter class (#1218) · Conan520/pyscript@727267a · GitHub
[go: up one dir, main page]

Skip to content

Commit 727267a

Browse files
split interpreter class (pyscript#1218)
* split interpreter class * add new files * add newlines * disable eslint for run * remove usage of interpreter from unit test * delete fakeinterpreter class * fix unit tests * add comments * remove interpreter.ts and pyodide.ts files * suggested changes
1 parent b5d15c2 commit 727267a

17 files changed

+190
-250
lines changed

pyscriptjs/src/components/elements.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { Interpreter } from '../interpreter';
1+
import { InterpreterClient } from '../interpreter_client';
22
import { make_PyRepl } from './pyrepl';
33
import { make_PyWidget } from './pywidget';
44

5-
function createCustomElements(interpreter: Interpreter) {
5+
function createCustomElements(interpreter: InterpreterClient) {
66
const PyWidget = make_PyWidget(interpreter);
77
const PyRepl = make_PyRepl(interpreter);
88

pyscriptjs/src/components/pyrepl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import { defaultKeymap } from '@codemirror/commands';
77
import { oneDarkTheme } from '@codemirror/theme-one-dark';
88

99
import { getAttribute, ensureUniqueId, htmlDecode } from '../utils';
10-
import type { Interpreter } from '../interpreter';
1110
import { pyExec, pyDisplay } from '../pyexec';
1211
import { getLogger } from '../logger';
12+
import { InterpreterClient } from '../interpreter_client';
1313

1414
const logger = getLogger('py-repl');
1515
const RUNBUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
1616

17-
export function make_PyRepl(interpreter: Interpreter) {
17+
export function make_PyRepl(interpreter: InterpreterClient) {
1818
/* High level structure of py-repl DOM, and the corresponding JS names.
1919
2020
this <py-repl>

pyscriptjs/src/components/pyscript.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
2-
import type { Interpreter } from '../interpreter';
32
import { getLogger } from '../logger';
43
import { pyExec, displayPyException } from '../pyexec';
54
import { _createAlertBanner } from '../exceptions';
65
import { robustFetch } from '../fetch';
76
import { PyScriptApp } from '../main';
87
import { Stdio } from '../stdio';
8+
import { InterpreterClient } from '../interpreter_client';
99

1010
const logger = getLogger('py-script');
1111

12-
export function make_PyScript(interpreter: Interpreter, app: PyScriptApp) {
12+
export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp) {
1313
class PyScript extends HTMLElement {
1414
srcCode: string;
1515
stdout_manager: Stdio | null;
@@ -158,15 +158,15 @@ const pyAttributeToEvent: Map<string, string> = new Map<string, string>([
158158
]);
159159

160160
/** Initialize all elements with py-* handlers attributes */
161-
export function initHandlers(interpreter: Interpreter) {
161+
export function initHandlers(interpreter: InterpreterClient) {
162162
logger.debug('Initializing py-* event handlers...');
163163
for (const pyAttribute of pyAttributeToEvent.keys()) {
164164
createElementsWithEventListeners(interpreter, pyAttribute);
165165
}
166166
}
167167

168168
/** Initializes an element with the given py-on* attribute and its handler */
169-
function createElementsWithEventListeners(interpreter: Interpreter, pyAttribute: string) {
169+
function createElementsWithEventListeners(interpreter: InterpreterClient, pyAttribute: string) {
170170
const matches: NodeListOf<HTMLElement> = document.querySelectorAll(`[${pyAttribute}]`);
171171
for (const el of matches) {
172172
// If the element doesn't have an id, let's add one automatically!
@@ -223,7 +223,7 @@ function createElementsWithEventListeners(interpreter: Interpreter, pyAttribute:
223223
}
224224

225225
/** Mount all elements with attribute py-mount into the Python namespace */
226-
export async function mountElements(interpreter: Interpreter) {
226+
export async function mountElements(interpreter: InterpreterClient) {
227227
const matches: NodeListOf<HTMLElement> = document.querySelectorAll('[py-mount]');
228228
logger.info(`py-mount: found ${matches.length} elements`);
229229

pyscriptjs/src/components/pywidget.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { Interpreter } from '../interpreter';
21
import type { PyProxy } from 'pyodide';
32
import { getLogger } from '../logger';
43
import { robustFetch } from '../fetch';
4+
import { InterpreterClient } from '../interpreter_client';
55

66
const logger = getLogger('py-register-widget');
77

8-
function createWidget(interpreter: Interpreter, name: string, code: string, klass: string) {
8+
function createWidget(interpreter: InterpreterClient, name: string, code: string, klass: string) {
99
class CustomWidget extends HTMLElement {
1010
shadow: ShadowRoot;
1111
wrapper: HTMLElement;
@@ -44,7 +44,7 @@ function createWidget(interpreter: Interpreter, name: string, code: string, klas
4444
/* eslint-enable @typescript-eslint/no-unused-vars */
4545
}
4646

47-
export function make_PyWidget(interpreter: Interpreter) {
47+
export function make_PyWidget(interpreter: InterpreterClient) {
4848
class PyWidget extends HTMLElement {
4949
shadow: ShadowRoot;
5050
name: string;

pyscriptjs/src/interpreter.ts

Lines changed: 0 additions & 105 deletions
This file was deleted.

pyscriptjs/src/interpreter_client.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { AppConfig } from './pyconfig';
2+
import { RemoteInterpreter } from './remote_interpreter';
3+
import type { PyProxy } from 'pyodide';
4+
import { getLogger } from './logger';
5+
import type { Stdio } from './stdio';
6+
7+
const logger = getLogger('pyscript/interpreter');
8+
9+
/*
10+
InterpreterClient class is responsible to request code execution
11+
(among other things) from a `RemoteInterpreter`
12+
*/
13+
export class InterpreterClient extends Object {
14+
15+
_remote: RemoteInterpreter;
16+
config: AppConfig;
17+
/**
18+
* global symbols table for the underlying interface.
19+
* */
20+
globals: PyProxy;
21+
stdio: Stdio;
22+
23+
constructor(config: AppConfig, stdio: Stdio) {
24+
super();
25+
this.config = config;
26+
this._remote = new RemoteInterpreter(this.config.interpreters[0].src);
27+
this.stdio = stdio;
28+
}
29+
30+
/**
31+
* initializes the remote interpreter, which further loads the underlying
32+
* interface.
33+
* */
34+
async initializeRemote(): Promise<void> {
35+
await this._remote.loadInterpreter(this.config, this.stdio);
36+
this.globals = this._remote.globals;
37+
}
38+
39+
/**
40+
* delegates the code to be run to the underlying interface of
41+
* the remote interpreter.
42+
* Python exceptions are turned into JS exceptions.
43+
* */
44+
async run(code: string): Promise<{result: any}> {
45+
return await this._remote.run(code);
46+
}
47+
48+
/**
49+
* Same as run, but Python exceptions are not propagated: instead, they
50+
* are logged to the console.
51+
*
52+
* This is a bad API and should be killed/refactored/changed eventually,
53+
* but for now we have code which relies on it.
54+
* */
55+
async runButDontRaise(code: string): Promise<unknown> {
56+
let result: unknown;
57+
try {
58+
result = (await this.run(code)).result;
59+
} catch (error: unknown) {
60+
logger.error('Error:', error);
61+
}
62+
return result;
63+
}
64+
}

0 commit comments

Comments
 (0)
0