mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Compare commits
9 Commits
antocuni/p
...
2023.05.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
848d77b1c2 | ||
|
|
e4e8f2edae | ||
|
|
ea9bdcc961 | ||
|
|
79ad39260e | ||
|
|
f4936316ab | ||
|
|
8879187e6a | ||
|
|
258b80a6a5 | ||
|
|
a108e6e97e | ||
|
|
dfef7eda3b |
6
.github/workflows/build-unstable.yml
vendored
6
.github/workflows/build-unstable.yml
vendored
@@ -20,7 +20,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
BuildAndTest:
|
BuildAndTest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: pyscriptjs
|
working-directory: pyscriptjs
|
||||||
@@ -85,7 +85,7 @@ jobs:
|
|||||||
path: pyscriptjs/test_results
|
path: pyscriptjs/test_results
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
eslint:
|
eslint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: pyscriptjs
|
working-directory: pyscriptjs
|
||||||
@@ -118,7 +118,7 @@ jobs:
|
|||||||
run: npx eslint src -c .eslintrc.js
|
run: npx eslint src -c .eslintrc.js
|
||||||
|
|
||||||
Deploy:
|
Deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
needs: BuildAndTest
|
needs: BuildAndTest
|
||||||
if: github.ref == 'refs/heads/main' # Only deploy on merge into main
|
if: github.ref == 'refs/heads/main' # Only deploy on merge into main
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
2
.github/workflows/docs-release.yml
vendored
2
.github/workflows/docs-release.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|||||||
2
.github/workflows/docs-review.yml
vendored
2
.github/workflows/docs-review.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.repository_owner == 'pyscript'
|
if: github.repository_owner == 'pyscript'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|||||||
2
.github/workflows/docs-unstable.yml
vendored
2
.github/workflows/docs-unstable.yml
vendored
@@ -9,7 +9,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|||||||
18
.github/workflows/prepare-release.yml
vendored
18
.github/workflows/prepare-release.yml
vendored
@@ -15,7 +15,7 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -44,8 +44,20 @@ jobs:
|
|||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: make setup
|
run: make setup
|
||||||
|
|
||||||
- name: Build and Test
|
- name: Build
|
||||||
run: make test
|
run: make build
|
||||||
|
|
||||||
|
- name: TypeScript Tests
|
||||||
|
run: make test-ts
|
||||||
|
|
||||||
|
- name: Python Tests
|
||||||
|
run: make test-py
|
||||||
|
|
||||||
|
- name: Integration Tests
|
||||||
|
run: make test-integration-parallel
|
||||||
|
|
||||||
|
- name: Examples Tests
|
||||||
|
run: make test-examples
|
||||||
|
|
||||||
- name: Zip build folder
|
- name: Zip build folder
|
||||||
run: zip -r -q ./build.zip ./build
|
run: zip -r -q ./build.zip ./build
|
||||||
|
|||||||
18
.github/workflows/publish-release.yml
vendored
18
.github/workflows/publish-release.yml
vendored
@@ -14,7 +14,7 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
@@ -46,8 +46,20 @@ jobs:
|
|||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: make setup
|
run: make setup
|
||||||
|
|
||||||
- name: Build and Test
|
- name: Build
|
||||||
run: make test
|
run: make build
|
||||||
|
|
||||||
|
- name: TypeScript Tests
|
||||||
|
run: make test-ts
|
||||||
|
|
||||||
|
- name: Python Tests
|
||||||
|
run: make test-py
|
||||||
|
|
||||||
|
- name: Integration Tests
|
||||||
|
run: make test-integration-parallel
|
||||||
|
|
||||||
|
- name: Examples Tests
|
||||||
|
run: make test-examples
|
||||||
|
|
||||||
# Upload to S3
|
# Upload to S3
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
|
|||||||
2
.github/workflows/publish-snapshot.yml
vendored
2
.github/workflows/publish-snapshot.yml
vendored
@@ -11,7 +11,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
snapshot:
|
snapshot:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|||||||
2
.github/workflows/sync-examples.yml
vendored
2
.github/workflows/sync-examples.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
|
|||||||
128
.github/workflows/test-next.yml
vendored
Normal file
128
.github/workflows/test-next.yml
vendored
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
name: "[CI] Test Next"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push: # Only run on merges into main that modify files under pyscriptjs/ and examples/
|
||||||
|
branches:
|
||||||
|
- next
|
||||||
|
paths:
|
||||||
|
- pyscript.core/**
|
||||||
|
- pyscriptjs/**
|
||||||
|
- examples/**
|
||||||
|
- .github/workflows/test-next.yml # Test that workflow works when changed
|
||||||
|
|
||||||
|
pull_request: # Run on any PR that modifies files under pyscriptjs/ and examples/
|
||||||
|
branches:
|
||||||
|
- next
|
||||||
|
paths:
|
||||||
|
- pyscript.core/**
|
||||||
|
- pyscriptjs/**
|
||||||
|
- examples/**
|
||||||
|
- .github/workflows/test-next.yml # Test that workflow works when changed
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
BuildAndTest:
|
||||||
|
runs-on: ubuntu-latest-8core
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: pyscriptjs
|
||||||
|
env:
|
||||||
|
MINICONDA_PYTHON_VERSION: py38
|
||||||
|
MINICONDA_VERSION: 4.11.0
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v3
|
||||||
|
env:
|
||||||
|
cache-name: cache-node-modules
|
||||||
|
with:
|
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
|
||||||
|
- name: setup Miniconda
|
||||||
|
uses: conda-incubator/setup-miniconda@v2
|
||||||
|
|
||||||
|
- name: Setup Environment
|
||||||
|
run: make setup
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: make build
|
||||||
|
|
||||||
|
- name: TypeScript Tests (core)
|
||||||
|
run: make test-ts
|
||||||
|
|
||||||
|
- name: Python Tests
|
||||||
|
run: make test-py
|
||||||
|
|
||||||
|
- name: install next deps
|
||||||
|
working-directory: pyscript.core
|
||||||
|
run: npm i
|
||||||
|
|
||||||
|
- name: Run next tests
|
||||||
|
working-directory: pyscript.core
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
- name: Integration Tests
|
||||||
|
run: make test-integration-parallel
|
||||||
|
|
||||||
|
- name: Examples Tests
|
||||||
|
run: make test-examples
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: pyscript
|
||||||
|
path: |
|
||||||
|
pyscriptjs/build/
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: success() || failure()
|
||||||
|
with:
|
||||||
|
name: test_results
|
||||||
|
path: pyscriptjs/test_results
|
||||||
|
if-no-files-found: error
|
||||||
|
eslint:
|
||||||
|
runs-on: ubuntu-latest-8core
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: pyscriptjs
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v3
|
||||||
|
env:
|
||||||
|
cache-name: cache-node-modules
|
||||||
|
with:
|
||||||
|
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
|
||||||
|
- name: npm install
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Eslint
|
||||||
|
run: npx eslint src -c .eslintrc.js
|
||||||
2
.github/workflows/test_report.yml
vendored
2
.github/workflows/test_report.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
- completed
|
- completed
|
||||||
jobs:
|
jobs:
|
||||||
report:
|
report:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-8core
|
||||||
steps:
|
steps:
|
||||||
- uses: dorny/test-reporter@v1.6.0
|
- uses: dorny/test-reporter@v1.6.0
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ Features
|
|||||||
- Added a `stderr` attribute of `py-repl` tags to route `sys.stderr` to a DOM element with the given ID. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
|
- Added a `stderr` attribute of `py-repl` tags to route `sys.stderr` to a DOM element with the given ID. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
|
||||||
- Resored the `output-mode` attribute of `py-repl` tags. If `output-mode` == 'append', the DOM element where output is printed is _not_ cleared before writing new results.
|
- Resored the `output-mode` attribute of `py-repl` tags. If `output-mode` == 'append', the DOM element where output is printed is _not_ cleared before writing new results.
|
||||||
- Load code from the attribute src of py-repl and preload it into the corresponding py-repl tag by use the attribute `str` in your `py-repl` tag([#1292](https://github.com/pyscript/pyscript/pull/1292))
|
- Load code from the attribute src of py-repl and preload it into the corresponding py-repl tag by use the attribute `str` in your `py-repl` tag([#1292](https://github.com/pyscript/pyscript/pull/1292))
|
||||||
|
- <py-repl> elements now have a `getPySrc()` method, which returns the code inside the REPL as a string.([#1516](https://github.com/pyscript/pyscript/pull/1292))
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
- Plugins may now implement the `beforePyReplExec()` and `afterPyReplExec()` hooks, which are called immediately before and after code in a `py-repl` tag is executed. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
|
- Plugins may now implement the `beforePyReplExec()` and `afterPyReplExec()` hooks, which are called immediately before and after code in a `py-repl` tag is executed. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
|
||||||
@@ -57,7 +58,7 @@ Docs
|
|||||||
|
|
||||||
- Add docs for event handlers
|
- Add docs for event handlers
|
||||||
|
|
||||||
2023.01.1
|
2023.03.1
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ The ID of an element in the DOM that `stderr` will be written to. Defaults to No
|
|||||||
### `src`
|
### `src`
|
||||||
If a \<py-repl\> tag has the `src` attribute, during page initialization, resource in the `src` will be preloaded into the REPL. Please note that this will not run in advance. If there is content in the \<py-repl\> tag, it will be cleared and replaced with preloaded resource.
|
If a \<py-repl\> tag has the `src` attribute, during page initialization, resource in the `src` will be preloaded into the REPL. Please note that this will not run in advance. If there is content in the \<py-repl\> tag, it will be cleared and replaced with preloaded resource.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
The following are methods that can be called on the \<py-repl\> element, from within Python or JavaScript
|
||||||
|
|
||||||
|
### `getPySrc()`
|
||||||
|
|
||||||
|
Returns the current code contents of the REPL as a string.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### `<py-repl>` element set to auto-generate
|
### `<py-repl>` element set to auto-generate
|
||||||
|
|||||||
20
pyscriptjs/package-lock.json
generated
20
pyscriptjs/package-lock.json
generated
@@ -34,7 +34,7 @@
|
|||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
"pyodide": "0.23.2",
|
"pyodide": "0.23.2",
|
||||||
"synclink": "0.2.4",
|
"synclink": "0.2.4",
|
||||||
"ts-jest": "29.0.3",
|
"ts-jest": "29.1.0",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.0.4",
|
||||||
"xterm": "^5.1.0"
|
"xterm": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -5674,15 +5674,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-jest": {
|
"node_modules/ts-jest": {
|
||||||
"version": "29.0.3",
|
"version": "29.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz",
|
||||||
"integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
|
"integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bs-logger": "0.x",
|
"bs-logger": "0.x",
|
||||||
"fast-json-stable-stringify": "2.x",
|
"fast-json-stable-stringify": "2.x",
|
||||||
"jest-util": "^29.0.0",
|
"jest-util": "^29.0.0",
|
||||||
"json5": "^2.2.1",
|
"json5": "^2.2.3",
|
||||||
"lodash.memoize": "4.x",
|
"lodash.memoize": "4.x",
|
||||||
"make-error": "1.x",
|
"make-error": "1.x",
|
||||||
"semver": "7.x",
|
"semver": "7.x",
|
||||||
@@ -5699,7 +5699,7 @@
|
|||||||
"@jest/types": "^29.0.0",
|
"@jest/types": "^29.0.0",
|
||||||
"babel-jest": "^29.0.0",
|
"babel-jest": "^29.0.0",
|
||||||
"jest": "^29.0.0",
|
"jest": "^29.0.0",
|
||||||
"typescript": ">=4.3"
|
"typescript": ">=4.3 <6"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@babel/core": {
|
"@babel/core": {
|
||||||
@@ -10247,15 +10247,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ts-jest": {
|
"ts-jest": {
|
||||||
"version": "29.0.3",
|
"version": "29.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz",
|
||||||
"integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
|
"integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bs-logger": "0.x",
|
"bs-logger": "0.x",
|
||||||
"fast-json-stable-stringify": "2.x",
|
"fast-json-stable-stringify": "2.x",
|
||||||
"jest-util": "^29.0.0",
|
"jest-util": "^29.0.0",
|
||||||
"json5": "^2.2.1",
|
"json5": "^2.2.3",
|
||||||
"lodash.memoize": "4.x",
|
"lodash.memoize": "4.x",
|
||||||
"make-error": "1.x",
|
"make-error": "1.x",
|
||||||
"semver": "7.x",
|
"semver": "7.x",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
"pyodide": "0.23.2",
|
"pyodide": "0.23.2",
|
||||||
"synclink": "0.2.4",
|
"synclink": "0.2.4",
|
||||||
"ts-jest": "29.0.3",
|
"ts-jest": "29.1.0",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.0.4",
|
||||||
"xterm": "^5.1.0"
|
"xterm": "^5.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
|
|||||||
pyReplTag: this,
|
pyReplTag: this,
|
||||||
result,
|
result,
|
||||||
});
|
});
|
||||||
|
await interpreter._remote.destroyIfProxy(result);
|
||||||
this.autogenerateMaybe();
|
this.autogenerateMaybe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
|
|||||||
await app.plugins.beforePyScriptExec({ interpreter, src, pyScriptTag });
|
await app.plugins.beforePyScriptExec({ interpreter, src, pyScriptTag });
|
||||||
const { result } = await pyExec(interpreter, src, pyScriptTag);
|
const { result } = await pyExec(interpreter, src, pyScriptTag);
|
||||||
await app.plugins.afterPyScriptExec({ interpreter, src, pyScriptTag, result });
|
await app.plugins.afterPyScriptExec({ interpreter, src, pyScriptTag, result });
|
||||||
|
await interpreter._remote.destroyIfProxy(result);
|
||||||
} finally {
|
} finally {
|
||||||
releaseLock();
|
releaseLock();
|
||||||
app.decrementPendingTags();
|
app.decrementPendingTags();
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export let runtime;
|
|||||||
export class PyScriptApp {
|
export class PyScriptApp {
|
||||||
config: AppConfig;
|
config: AppConfig;
|
||||||
interpreter: InterpreterClient;
|
interpreter: InterpreterClient;
|
||||||
|
unwrapped_remote: RemoteInterpreter;
|
||||||
readyPromise: Promise<void>;
|
readyPromise: Promise<void>;
|
||||||
PyScript: ReturnType<typeof make_PyScript>;
|
PyScript: ReturnType<typeof make_PyScript>;
|
||||||
plugins: PluginManager;
|
plugins: PluginManager;
|
||||||
@@ -139,10 +140,10 @@ export class PyScriptApp {
|
|||||||
await this.plugins.configure(this.config);
|
await this.plugins.configure(this.config);
|
||||||
this.plugins.beforeLaunch(this.config);
|
this.plugins.beforeLaunch(this.config);
|
||||||
await this.loadInterpreter();
|
await this.loadInterpreter();
|
||||||
interpreter = this.interpreter;
|
interpreter = this.unwrapped_remote;
|
||||||
// TODO: This is for backwards compatibility, it should be removed
|
// TODO: This is for backwards compatibility, it should be removed
|
||||||
// when we finish the deprecation cycle of `runtime`
|
// when we finish the deprecation cycle of `runtime`
|
||||||
runtime = this.interpreter;
|
runtime = this.unwrapped_remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lifecycle (2)
|
// lifecycle (2)
|
||||||
@@ -193,6 +194,7 @@ export class PyScriptApp {
|
|||||||
logger.info('Starting the interpreter in the main thread');
|
logger.info('Starting the interpreter in the main thread');
|
||||||
// this is basically equivalent to worker_initialize()
|
// this is basically equivalent to worker_initialize()
|
||||||
const remote_interpreter = new RemoteInterpreter(interpreter_cfg.src);
|
const remote_interpreter = new RemoteInterpreter(interpreter_cfg.src);
|
||||||
|
this.unwrapped_remote = remote_interpreter;
|
||||||
const { port1, port2 } = new Synclink.FakeMessageChannel() as unknown as MessageChannel;
|
const { port1, port2 } = new Synclink.FakeMessageChannel() as unknown as MessageChannel;
|
||||||
port1.start();
|
port1.start();
|
||||||
port2.start();
|
port2.start();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from contextlib import contextmanager
|
|||||||
|
|
||||||
from js import Object
|
from js import Object
|
||||||
from pyodide.code import eval_code
|
from pyodide.code import eval_code
|
||||||
from pyodide.ffi import JsProxy
|
from pyodide.ffi import JsProxy, to_js
|
||||||
|
|
||||||
from ._event_loop import (
|
from ._event_loop import (
|
||||||
defer_user_asyncio,
|
defer_user_asyncio,
|
||||||
@@ -103,7 +103,7 @@ def run_pyscript(code: str, id: str = None) -> JsProxy:
|
|||||||
with display_target(id), defer_user_asyncio():
|
with display_target(id), defer_user_asyncio():
|
||||||
result = eval_code(code, globals=__main__.__dict__)
|
result = eval_code(code, globals=__main__.__dict__)
|
||||||
|
|
||||||
return Object.new(result=result)
|
return to_js({"result": result}, depth=1, dict_converter=Object.fromEntries)
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|||||||
@@ -274,6 +274,20 @@ export class RemoteInterpreter extends Object {
|
|||||||
this.FS.writeFile(path, data, { canOwn: true });
|
this.FS.writeFile(path, data, { canOwn: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyIfProxy(px: any): void {
|
||||||
|
if (this.interface.ffi) {
|
||||||
|
// Pyodide 0.23
|
||||||
|
if (px instanceof this.interface.ffi.PyProxy) {
|
||||||
|
px.destroy();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// older Pyodide
|
||||||
|
if (this.interface.isPyProxy(px)) {
|
||||||
|
px.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delegates clearing importlib's module path
|
* delegates clearing importlib's module path
|
||||||
* caches to the underlying interface
|
* caches to the underlying interface
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from .support import PyScriptTest
|
from .support import PyScriptTest, skip_worker
|
||||||
|
|
||||||
|
|
||||||
class TestInterpreterAccess(PyScriptTest):
|
class TestInterpreterAccess(PyScriptTest):
|
||||||
"""Test accessing Python objects from JS via pyscript.interpreter"""
|
"""Test accessing Python objects from JS via pyscript.interpreter"""
|
||||||
|
|
||||||
|
@skip_worker("WONTFIX: used without synclink to avoid awaits")
|
||||||
def test_interpreter_python_access(self):
|
def test_interpreter_python_access(self):
|
||||||
self.pyscript_run(
|
self.pyscript_run(
|
||||||
"""
|
"""
|
||||||
@@ -17,9 +18,9 @@ class TestInterpreterAccess(PyScriptTest):
|
|||||||
|
|
||||||
self.run_js(
|
self.run_js(
|
||||||
"""
|
"""
|
||||||
const x = await pyscript.interpreter.globals.get('x');
|
const x = pyscript.interpreter.globals.get('x');
|
||||||
const py_func = await pyscript.interpreter.globals.get('py_func');
|
const py_func = pyscript.interpreter.globals.get('py_func');
|
||||||
const py_func_res = await py_func();
|
const py_func_res = py_func();
|
||||||
console.log(`x is ${x}`);
|
console.log(`x is ${x}`);
|
||||||
console.log(`py_func() returns ${py_func_res}`);
|
console.log(`py_func() returns ${py_func_res}`);
|
||||||
"""
|
"""
|
||||||
@@ -29,13 +30,14 @@ class TestInterpreterAccess(PyScriptTest):
|
|||||||
"py_func() returns 2",
|
"py_func() returns 2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@skip_worker("WONTFIX: used without synclink")
|
||||||
def test_interpreter_script_execution(self):
|
def test_interpreter_script_execution(self):
|
||||||
"""Test running Python code from js via pyscript.interpreter"""
|
"""Test running Python code from js via pyscript.interpreter"""
|
||||||
self.pyscript_run("")
|
self.pyscript_run("")
|
||||||
|
|
||||||
self.run_js(
|
self.run_js(
|
||||||
"""
|
"""
|
||||||
const interface = pyscript.interpreter._remote.interface;
|
const interface = pyscript.interpreter.interface;
|
||||||
await interface.runPython('print("Interpreter Ran This")');
|
await interface.runPython('print("Interpreter Ran This")');
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -46,13 +48,14 @@ class TestInterpreterAccess(PyScriptTest):
|
|||||||
py_terminal = self.page.wait_for_selector("py-terminal")
|
py_terminal = self.page.wait_for_selector("py-terminal")
|
||||||
assert py_terminal.text_content() == expected_message
|
assert py_terminal.text_content() == expected_message
|
||||||
|
|
||||||
|
@skip_worker("WONTFIX: used without synclink")
|
||||||
def test_backward_compatibility_runtime_script_execution(self):
|
def test_backward_compatibility_runtime_script_execution(self):
|
||||||
"""Test running Python code from js via pyscript.runtime"""
|
"""Test running Python code from js via pyscript.runtime"""
|
||||||
self.pyscript_run("")
|
self.pyscript_run("")
|
||||||
|
|
||||||
self.run_js(
|
self.run_js(
|
||||||
"""
|
"""
|
||||||
const interface = pyscript.runtime._remote.interpreter;
|
const interface = pyscript.runtime.interpreter;
|
||||||
await interface.runPython('print("Interpreter Ran This")');
|
await interface.runPython('print("Interpreter Ran This")');
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -63,6 +66,7 @@ class TestInterpreterAccess(PyScriptTest):
|
|||||||
py_terminal = self.page.wait_for_selector("py-terminal")
|
py_terminal = self.page.wait_for_selector("py-terminal")
|
||||||
assert py_terminal.text_content() == expected_message
|
assert py_terminal.text_content() == expected_message
|
||||||
|
|
||||||
|
@skip_worker("WONTFIX: used without synclink to avoid awaits")
|
||||||
def test_backward_compatibility_runtime_python_access(self):
|
def test_backward_compatibility_runtime_python_access(self):
|
||||||
"""Test accessing Python objects from JS via pyscript.runtime"""
|
"""Test accessing Python objects from JS via pyscript.runtime"""
|
||||||
self.pyscript_run(
|
self.pyscript_run(
|
||||||
@@ -77,9 +81,9 @@ class TestInterpreterAccess(PyScriptTest):
|
|||||||
|
|
||||||
self.run_js(
|
self.run_js(
|
||||||
"""
|
"""
|
||||||
const x = await pyscript.interpreter.globals.get('x');
|
const x = pyscript.runtime.globals.get('x');
|
||||||
const py_func = await pyscript.interpreter.globals.get('py_func');
|
const py_func = pyscript.runtime.globals.get('py_func');
|
||||||
const py_func_res = await py_func();
|
const py_func_res = py_func();
|
||||||
console.log(`x is ${x}`);
|
console.log(`x is ${x}`);
|
||||||
console.log(`py_func() returns ${py_func_res}`);
|
console.log(`py_func() returns ${py_func_res}`);
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -595,6 +595,26 @@ class TestPyRepl(PyScriptTest):
|
|||||||
alert_banner = self.page.wait_for_selector(".alert-banner")
|
alert_banner = self.page.wait_for_selector(".alert-banner")
|
||||||
assert expected_alert_banner_msg in alert_banner.inner_text()
|
assert expected_alert_banner_msg in alert_banner.inner_text()
|
||||||
|
|
||||||
|
def test_getPySrc_Contents(self):
|
||||||
|
"""Test that an empty REPL returns an empty string as src, and that the typed contents
|
||||||
|
are returned as the source
|
||||||
|
"""
|
||||||
|
self.pyscript_run(
|
||||||
|
"""
|
||||||
|
<py-repl>
|
||||||
|
</py-repl>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
py_repl = self.page.locator("py-repl")
|
||||||
|
src = py_repl.evaluate("node => node.getPySrc()")
|
||||||
|
assert src == ""
|
||||||
|
assert type(src) == str
|
||||||
|
|
||||||
|
py_repl.focus()
|
||||||
|
py_repl.type("Hello, world!")
|
||||||
|
src = py_repl.evaluate("node => node.getPySrc()")
|
||||||
|
assert src == "Hello, world!"
|
||||||
|
|
||||||
def test_repl_load_content_from_src(self):
|
def test_repl_load_content_from_src(self):
|
||||||
self.writefile("loadReplSrc1.py", "print('1')")
|
self.writefile("loadReplSrc1.py", "print('1')")
|
||||||
self.pyscript_run(
|
self.pyscript_run(
|
||||||
@@ -654,3 +674,47 @@ class TestPyRepl(PyScriptTest):
|
|||||||
"Are your filename and path correct?"
|
"Are your filename and path correct?"
|
||||||
)
|
)
|
||||||
assert self.console.error.lines[-1] == errorMsg
|
assert self.console.error.lines[-1] == errorMsg
|
||||||
|
|
||||||
|
@skip_worker("dont-care")
|
||||||
|
def test_repl_results(self):
|
||||||
|
self.writefile("loadReplSrc2.py", "2")
|
||||||
|
self.writefile("loadReplSrc3.py", "print('3')")
|
||||||
|
|
||||||
|
self.pyscript_run(
|
||||||
|
"""
|
||||||
|
<py-repl id="py-repl1" output="out1">
|
||||||
|
42
|
||||||
|
</py-repl>
|
||||||
|
<div id="out1"></div>
|
||||||
|
|
||||||
|
<py-repl id="py-repl2" output="out2">
|
||||||
|
c = [1,2,3]
|
||||||
|
from sys import getrefcount
|
||||||
|
# should print 2: 1 from the reference c and 1 since getrefcount
|
||||||
|
# holds a reference to its argument
|
||||||
|
print(getrefcount(c))
|
||||||
|
c
|
||||||
|
</py-repl>
|
||||||
|
<div id="out2"></div>
|
||||||
|
|
||||||
|
<py-repl id="py-repl3" output="out3">
|
||||||
|
# should also print 2: if it prints 3 that would mean that c was not properly
|
||||||
|
# released by py-repl
|
||||||
|
getrefcount(c)
|
||||||
|
</py-repl>
|
||||||
|
<div id="out3"></div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
py_repl1 = self.page.locator("py-repl#py-repl1")
|
||||||
|
py_repl1.locator("button").click()
|
||||||
|
|
||||||
|
py_repl2 = self.page.locator("py-repl#py-repl2")
|
||||||
|
py_repl2.locator("button").click()
|
||||||
|
|
||||||
|
py_repl3 = self.page.locator("py-repl#py-repl3")
|
||||||
|
py_repl3.locator("button").click()
|
||||||
|
|
||||||
|
assert self.page.wait_for_selector("#out1").inner_text() == "42"
|
||||||
|
assert self.page.wait_for_selector("#out2").inner_text() == "2\n\n[1, 2, 3]"
|
||||||
|
# Check that c was released
|
||||||
|
assert self.page.wait_for_selector("#out3").inner_text() == "2"
|
||||||
|
|||||||
Reference in New Issue
Block a user