8000 synclink integration by madhur-tandon · Pull Request #1258 · pyscript/pyscript · GitHub
[go: up one dir, main page]

Skip to content

synclink integration #1258

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 73 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
c9276a3
integrate synclink
madhur-tandon Feb 24, 2023
a3fd1f8
fix a few more tests
madhur-tandon Feb 24, 2023
621286f
more improvements
madhur-tandon Feb 24, 2023
d741d17
fix test_interpreter.py
madhur-tandon Mar 7, 2023
a5537d7
lint + fix most of py-repl tests
madhur-tandon Mar 7, 2023
c9dce56
fixed py-repls
madhur-tandon Mar 7, 2023
04951e2
fix one more flaky py-repl test
madhur-tandon Mar 9, 2023
1c08c3a
fix more tests
madhur-tandon Mar 9, 2023
cd76379
fix one more flaky test
madhur-tandon Mar 9, 2023
6aebe5b
more linting fix
madhur-tandon Mar 15, 2023
52ee4c5
trying to fix plugins...
madhur-tandon Mar 15, 2023
769be90
fix lot of examples
madhur-tandon Mar 15, 2023 8000
5120fc2
fix test_interpreter again
madhur-tandon Mar 20, 2023
a26e21f
fix more tests
madhur-tandon Mar 20, 2023
4f737cc
linting
madhur-tandon Mar 20, 2023
d3318b9
fix py-repl test once again
madhur-tandon Mar 21, 2023
a9882a7
remove redundant print
madhur-tandon Mar 21, 2023
7d70b93
remove unused import
madhur-tandon Mar 21, 2023
1467c80
try fixing js unit tests
madhur-tandon Mar 21, 2023
2d1293c
add beforePyReplExec and afterPyReplExec as methods for Plugin Class
madhur-tandon Mar 23, 2023
6b6eda6
fix linting
madhur-tandon Mar 23, 2023
d1eee4b
fix jest based issues
madhur-tandon Mar 23, 2023
c4b9abb
fix unit tests
madhur-tandon Mar 23, 2023
6095571
linting
madhur-tandon Mar 23, 2023
826d85a
fix test_dynamically_add_py_script_tag
madhur-tandon Mar 23, 2023
464ed3e
Fix async execution order (#1303)
hoodmane Mar 23, 2023
d94cb28
minor improvements to unit tests
madhur-tandon Mar 24, 2023
ce17350
Revert "Fix async execution order (#1303)"
madhur-tandon Mar 24, 2023
cce13d0
remove unused import
madhur-tandon Mar 24, 2023
66287e7
resolve conflicts
madhur-tandon Mar 24, 2023
4be1711
xfail integration tests
madhur-tandon Mar 24, 2023
d28f022
remove redundant imports
madhur-tandon Mar 24, 2023
54d55b7
comment out main.test.ts
madhur-tandon Mar 24, 2023
68a4043
fix jest for CI
madhur-tandon Mar 25, 2023
e1e0c71
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 25, 2023
4b124c3
comment out whole block instead of single lines
madhur-tandon Mar 25, 2023
8c2e875
fix python unit tests
madhur-tandon Mar 25, 2023
a07ed13
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 25, 2023
e623021
make py-repl tests more reliable
madhur-tandon Mar 25, 2023
ec939fc
more robust py-repl tests
madhur-tandon Mar 25, 2023
d106d73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 25, 2023
999090c
fix codespell false positive
madhur-tandon Mar 25, 2023
740098b
increase line length for ruff
madhur-tandon Mar 25, 2023
60dfa45
make one more py-repl test robust
madhur-tandon Mar 25, 2023
8d52815
more py-repl tests fixes
madhur-tandon Mar 25, 2023
9e88bca
more py-repl fixes
madhur-tandon Mar 25, 2023
d1a40a7
suggested changes
madhur-tandon Mar 25, 2023
cfb232d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 25, 2023
f661d48
fix line too long
madhur-tandon Mar 25, 2023
cb52a62
add awaits for afterPyReplExec
madhur-tandon Mar 25, 2023
e059f1d
fix test_image_display
madhur-tandon Mar 25, 2023
bbd7b99
disable eslint for some lines
madhur-tandon Mar 25, 2023
b4d138e
fix py-repl test + suggestions from Andrea
madhur-tandon Mar 27, 2023
fcee8fa
add numPendingTags check inside decrementNumPendingTags function
madhur-tandon Mar 27, 2023
fad1958
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 27, 2023
c9a29eb
rename pending tags functions
madhur-tandon Mar 27, 2023
575b9fa
add a Makefile rule to run pre-commit checks
antocuni Mar 27, 2023
3b31f99
modify the eslint rules. We want to be able to use the 'any' type
antocuni Mar 27, 2023
7958bd2
these should be off, not error
antocuni Mar 27, 2023
73d4332
Revert "disable eslint for some lines"
madhur-tandon Mar 27, 2023
ace163e
change 2000 to 200 for timeout in run_js tests
madhur-tandon Mar 27, 2023
a0e30ec
fix a few eslint issues
madhur-tandon Mar 27, 2023
2760b72
use any instead of wrong type
madhur-tandon Mar 27, 2023
c68f550
Fix some types
hoodmane Mar 27, 2023
4f23c8b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 27, 2023
282fc7c
more py-repl fixes + remove test for without run_js
madhur-tandon Mar 27, 2023
de03910
use await for registerWidget
madhur-tandon Mar 27, 2023
006d8cf
Fix types more
hoodmane Mar 27, 2023
542b0ff
put the line length back to 105, and fix these two lines by making th…
antocuni Mar 27, 2023
e8458d3
don't use self.page.waitForTimeout, it's much better to wait for a me…
antocuni Mar 27, 2023
1174d93
resolve conflict
madhur-tandon Mar 27, 2023
befdd37
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 27, 2023
dc7505f
skip pylist test
madhur-tandon Mar 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ build-backend = "setuptools.build_meta"
dynamic = ["version"]

[tool.codespell]
ignore-words-list = "afterall"
skip = "pyscriptjs/node_modules/*,*.js,*.json"

[tool.ruff]
Expand Down
14 changes: 10 additions & 4 deletions pyscriptjs/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ module.exports = {
plugins: ['@typescript-eslint'],
ignorePatterns: ['node_modules'],
rules: {
'no-prototype-builtins': 'error',
'@typescript-eslint/no-unused-vars': ['error', { args: 'none' }],
// ts-ignore is already an explicit override, no need to have a second lint
'@typescript-eslint/ban-ts-comment': 'off',

// any related lints
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-return': 'error',

// other rules
'no-prototype-builtins': 'error',
'@typescript-eslint/no-unused-vars': ['error', { args: 'none' }],
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/no-empty-function': 'error',
Expand Down
5 changes: 5 additions & 0 deletions pyscriptjs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ build:
build-fast:
node esbuild.js

# use the following rule to do all the checks done by precommit: in
# particular, use this if you want to run eslint.
precommit-check:
pre-commit run --all-files

examples:
mkdir -p ./examples
cp -r ../examples/* ./examples
Expand Down
28 changes: 28 additions & 0 deletions pyscriptjs/jest-environment-jsdom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

const { TextEncoder, TextDecoder } = require('util');
const { MessageChannel } = require('node:worker_threads');

const { default: $JSDOMEnvironment, TestEnvironment } = require('jest-environment-jsdom');

Object.defineProperty(exports, '__esModule', {
value: true,
});

class JSDOMEnvironment extends $JSDOMEnvironment {
constructor(...args) {
const { global } = super(...args);
if (!global.TextEncoder) {
global.TextEncoder = TextEncoder;
}
if (!global.TextDecoder) {
global.TextDecoder = TextDecoder;
}
if (!global.MessageChannel) {
global.MessageChannel = MessageChannel;
}
}
}

exports.default = JSDOMEnvironment;
exports.TestEnvironment = TestEnvironment === $JSDOMEnvironment ? JSDOMEnvironment : TestEnvironment;
2 changes: 1 addition & 1 deletion pyscriptjs/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jest-environment-jsdom',
testEnvironment: './jest-environment-jsdom.js',
extensionsToTreatAsEsm: ['.ts'],
transform: {
'^.+\\.tsx?$': [
Expand Down
20 changes: 14 additions & 6 deletions pyscriptjs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyscriptjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@codemirror/theme-one-dark": "^6.1.1",
"@codemirror/view": "^6.9.3",
"@hoodmane/toml-j0.4": "^1.1.2",
"codemirror": "^6.0.1"
"codemirror": "6.0.1",
"synclink": "^0.1.1"
}
}
4 changes: 2 additions & 2 deletions pyscriptjs/src/components/pyrepl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
const outEl = this.outDiv;

// execute the python code
app.plugins.beforePyReplExec({ interpreter: interpreter, src: pySrc, outEl: outEl, pyReplTag: this });
await app.plugins.beforePyReplExec({ interpreter: interpreter, src: pySrc, outEl: outEl, pyReplTag: this });
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { result } = await pyExec(interpreter, pySrc, outEl);
app.plugins.afterPyReplExec({
await app.plugins.afterPyReplExec({
interpreter: interpreter,
src: pySrc,
outEl: outEl,
Expand Down
6 changes: 4 additions & 2 deletions pyscriptjs/src/components/pyscript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
*
* Concurrent access to the multiple py-script tags is thus avoided.
*/
app.incrementPendingTags();
let releaseLock: () => void;
try {
releaseLock = await app.tagExecutionLock();
Expand All @@ -34,10 +35,10 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
const pySrc = await this.getPySrc();
this.innerHTML = '';

app.plugins.beforePyScriptExec({ interpreter: interpreter, src: pySrc, pyScriptTag: this });
await app.plugins.beforePyScriptExec({ interpreter: interpreter, src: pySrc, pyScriptTag: this });
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
const result = (await pyExec(interpreter, pySrc, this)).result;
app.plugins.afterPyScriptExec({
await app.plugins.afterPyScriptExec({
interpreter: interpreter,
src: pySrc,
pyScriptTag: this,
Expand All @@ -46,6 +47,7 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
/* eslint-enable @typescript-eslint/no-unsafe-assignment */
} finally {
releaseLock();
app.decrementPendingTags();
}
}

Expand Down
17 changes: 9 additions & 8 deletions pyscriptjs/src/components/pywidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { PyProxy, PyProxyCallable } from 'pyodide';
import { getLogger } from '../logger';
import { robustFetch } from '../fetch';
import { InterpreterClient } from '../interpreter_client';
import type { Remote } from 'synclink';

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

Expand All @@ -13,8 +14,8 @@ function createWidget(interpreter: InterpreterClient, name: string, code: string
name: string = name;
klass: string = klass;
code: string = code;
proxy: PyProxy & { connect(): void };
proxyClass: PyProxyCallable;
proxy: Remote<PyProxy & { connect(): void }>;
proxyClass: Remote<PyProxyCallable>;

constructor() {
super();
Expand All @@ -28,15 +29,15 @@ function createWidget(interpreter: InterpreterClient, name: string, code: string

async connectedCallback() {
await interpreter.runButDontRaise(this.code);
this.proxyClass = interpreter.globals.get(this.klass) as PyProxyCallable;
this.proxy = this.proxyClass(this) as PyProxy & { connect(): void };
this.proxy.connect();
this.registerWidget();
this.proxyClass = (await interpreter.globals.get(this.klass)) as Remote<PyProxyCallable>;
this.proxy = (await this.proxyClass(this)) as Remote<PyProxy & { connect(): void }>;
await this.proxy.connect();
await this.registerWidget();
}

registerWidget() {
async registerWidget() {
logger.info('new widget registered:', this.name);
interpreter.globals.set(this.id, this.proxy);
await interpreter.globals.set(this.id, this.proxy);
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
6 changes: 6 additions & 0 deletions pyscriptjs/src/exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@ export enum ErrorCode {
export class UserError extends Error {
messageType: MessageType;
errorCode: ErrorCode;
/**
* `isinstance` doesn't work correctly across multiple realms.
* Hence, `$$isUserError` flag / marker is used to identify a `UserError`.
*/
$$isUserError: boolean;

constructor(errorCode: ErrorCode, message: string, t: MessageType = 'text') {
super(message);
this.errorCode = errorCode;
this.name = 'UserError';
this.messageType = t;
this.message = `(${errorCode}): ${message}`;
this.$$isUserError = true;
}
}

Expand Down
35 changes: 28 additions & 7 deletions pyscriptjs/src/interpreter_client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { AppConfig } from './pyconfig';
import { RemoteInterpreter } from './remote_interpreter';
import type { PyProxyDict } from 'pyodide';
import type { PyProxyDict, PyProxy } from 'pyodide';
import { getLogger } from './logger';
import type { Stdio } from './stdio';
import * as Synclink from 'synclink';

const logger = getLogger('pyscript/interpreter');

Expand All @@ -11,18 +12,25 @@ InterpreterClient class is responsible to request code execution
(among other things) from a `RemoteInterpreter`
*/
export class InterpreterClient extends Object {
_remote: RemoteInterpreter;
_remote: Synclink.Remote<RemoteInterpreter>;
_unwrapped_remote: RemoteInterpreter;
config: AppConfig;
/**
* global symbols table for the underlying interface.
* */
globals: PyProxyDict;
globals: Synclink.Remote<PyProxyDict>;
stdio: Stdio;

constructor(config: AppConfig, stdio: Stdio) {
constructor(
config: AppConfig,
stdio: Stdio,
remote: Synclink.Remote<RemoteInterpreter>,
unwrapped_remote: RemoteInterpreter,
) {
super();
this.config = config;
this._remote = new RemoteInterpreter(this.config.interpreters[0].src);
this._remote = remote;
this._unwrapped_remote = unwrapped_remote;
this.stdio = stdio;
}

Expand All @@ -31,8 +39,9 @@ export class InterpreterClient extends Object {
* interface.
* */
async initializeRemote(): Promise<void> {
await this._remote.loadInterpreter(this.config, this.stdio);
this.globals = this._remote.globals as PyProxyDict;
await this._unwrapped_remote.loadInterpreter(this.config, this.stdio);
// await this._remote.loadInterpreter(this.config, Synclink.proxy(this.stdio));
this.globals = this._remote.globals;
}

/**
Expand Down Expand Up @@ -61,4 +70,16 @@ export class InterpreterClient extends Object {
}
return result;
}

async pyimport(mod_name: string): Promise<Synclink.Remote<PyProxy>> {
return this._remote.pyimport(mod_name);
}

async mkdirTree(path: string) {
await this._remote.mkdirTree(path);
}

async writeFile(path: string, content: string) {
await this._remote.writeFile(path, content);
}
}
Loading
0