diff --git a/.github/workflows/test-next.yml b/.github/workflows/test-next.yml
index 0e325622..3764459f 100644
--- a/.github/workflows/test-next.yml
+++ b/.github/workflows/test-next.yml
@@ -44,17 +44,18 @@ jobs:
${{ runner.os }}-build-
${{ runner.os }}-
- - name: install next deps
- working-directory: pyscript.core
- run: npm i; npx playwright install
+ # TODO: this will likely change soon to pyscript.next
+ # - name: install next deps
+ # working-directory: pyscript.core
+ # run: npm i; npx playwright install
- - name: build next
- working-directory: pyscript.core
- run: npm run build
+ # - name: build next
+ # working-directory: pyscript.core
+ # run: npm run build
- - name: Run next tests
- working-directory: pyscript.core
- run: npm run test
+ # - name: Run next tests
+ # working-directory: pyscript.core
+ # run: npm run test
# TODO: DO we want to upload next yet?
# - uses: actions/upload-artifact@v3
diff --git a/.gitignore b/.gitignore
index 71e28403..cc7325e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,12 +141,3 @@ coverage/
# junit xml for test results
test_results
-
-# pyscript.core
-pyscript.core/coverage/
-pyscript.core/node_modules/
-pyscript.core/cjs/
-!pyscript.core/cjs/package.json
-pyscript.core/min.js
-pyscript.core/esm/worker/xworker.js
-pyscript.core/types/
diff --git a/.prettierignore b/.prettierignore
index 24675894..bff93a89 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -3,10 +3,3 @@ ISSUE_TEMPLATE
package-lock.json
docs
examples/panel.html
-pyscript.core/micropython/
-pyscript.core/pyscript/
-pyscript.core/types/
-pyscript.core/esm/worker/xworker.js
-pyscript.core/cjs/package.json
-pyscript.core/min.js
-pyscript.core/pyscript.js
diff --git a/pyscript.core/.eslintrc.json b/pyscript.core/.eslintrc.json
deleted file mode 100644
index 66c656ce..00000000
--- a/pyscript.core/.eslintrc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "env": {
- "browser": true,
- "es2022": true
- },
- "extends": "eslint:recommended",
- "parserOptions": {
- "ecmaVersion": 12,
- "sourceType": "module"
- },
- "ignorePatterns": ["__template.js"],
- "rules": {}
-}
diff --git a/pyscript.core/.github/workflows/node.js.yml b/pyscript.core/.github/workflows/node.js.yml
deleted file mode 100644
index c8046464..00000000
--- a/pyscript.core/.github/workflows/node.js.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
-# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
-
-name: build
-
-on: [push, pull_request]
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [20]
-
- steps:
- - uses: actions/checkout@v2
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v2
- with:
- node-version: ${{ matrix.node-version }}
- cache: "npm"
- - run: npm ci
- - run: npm run build --if-present
- - run: npm test
- - run: npm run coverage --if-present
- - name: Coveralls
- uses: coverallsapp/github-action@master
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/pyscript.core/.gitignore b/pyscript.core/.gitignore
deleted file mode 100644
index 51c31f4d..00000000
--- a/pyscript.core/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.DS_Store
-coverage/
-node_modules/
-cjs/
-!cjs/package.json
-core.js
-pyscript.js
-esm/worker/xworker.js
-esm/worker/__template.js
-types/
diff --git a/pyscript.core/.npmignore b/pyscript.core/.npmignore
deleted file mode 100644
index c5cc42aa..00000000
--- a/pyscript.core/.npmignore
+++ /dev/null
@@ -1,21 +0,0 @@
-.DS_Store
-.nyc_output
-.eslintrc.json
-.github/
-.travis.yml
-.eslintrc.json
-*.log
-coverage/
-micropython/
-node_modules/
-pyscript/
-rollup/
-test/
-index.html
-node.importmap
-sw.js
-tsconfig.json
-cjs/worker/_template.js
-cjs/worker/__template.js
-esm/worker/_template.js
-esm/worker/__template.js
diff --git a/pyscript.core/.npmrc b/pyscript.core/.npmrc
deleted file mode 100644
index cafe685a..00000000
--- a/pyscript.core/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-package-lock=true
diff --git a/pyscript.core/README.md b/pyscript.core/README.md
index 43291320..dec5f522 100644
--- a/pyscript.core/README.md
+++ b/pyscript.core/README.md
@@ -1,92 +1,5 @@
-# @pyscript/core
+# @pyscript/core - deprecated
-[](https://github.com/WebReflection/python/actions/workflows/node.js.yml) [](https://coveralls.io/github/WebReflection/python?branch=api)
+After various discussions around this topic, we decided to avoid any confusion around this folder which never really belonged in here, as _core_ as we meant it was meant to be a _PyScript Next_ dependency, not the _PyScript Next_ itself.
----
-
-## Documentation
-
-Please read [the documentation page](./docs/README.md) to know all the user-facing details around this module.
-
-## Development
-
-The working folder (source code of truth) is the `./esm` one, while the `./cjs` is populated as a dual module and to test (but it's 1:1 code, no transpilation except for imports/exports).
-
-```sh
-# install all dependencies needed by core
-npm i
-```
-
-### Build / Artifacts
-
-This project requires some automatic artifact creation to:
-
- * create a _Worker_ as a _Blob_ based on the same code used by this repo
- * create automatically the list of runtimes available via the module
- * create the `core.js` or the `pyscript.js` file used by most integration tests
- * create a sha256 version of the Blob content for CSP cases
-
-Accordingly, to build latest project:
-
-```sh
-# create all artifacts needed to test core
-npm run build
-
-# optionally spin a server with CORS, COOP, and COEP enabled
-npm run server
-```
-
-If **no minification** is desired or helpful while debugging potential issues, please use `NO_MIN=1` in front of the _build_ step:
-
-```sh
-NO_MIN=1 npm run build
-
-npm run server
-```
-
-### Dev Build
-
-Besides spinning the _localhost_ server via `npm run server`, the `npm run dev` will watch changes in the `./esm` folder and it will build automatically non optimized artifacts out of the box.
-
-## Integration Tests
-
-To keep it simple, and due to technical differences between what was in PyScript before and what we actually need for core (special headers, multiple interpreters, different bootstrap logic), core integration tests can be performed simply by running:
-
-```sh
-npm run test:integration
-```
-
-The package's entry takes care of eventually bootstrapping localhost, starting in parallel all tests, and shutting down the server after, if any was bootstrapped.
-
-The tool to test integration is still _playwright_ but moves things a bit faster (from my side) tests are written in JS.
-
-#### Integration Tests Structure
-
-```
-integration
- ├ interpreter
- │ ├ micropython
- │ ├ pyodide
- │ ├ ruby-wasm-wasi
- │ ├ wasmoon
- │ ├ xxx.yy
- │ ├ xxx.toml
- │ └ utils.js
- ├ _shared.js
- ├ micropython.js
- ├ pyodide.js
- ├ ruby-wasm-wasi.js
- └ wasmoon.js
-```
-
-- **interpreter** this folder contains, per each interpreter, a dedicated folder with the interpreter's name. Each of these sub-folders will contain all `.html` and other files to test every specific behavior. In this folder, it's possible to share files, config, or anything else that makes sense for one or more interpreters.
-- **\_shared.js** contains some utility used across all tests. Any file prefixed with `_` (underscore) will be ignored for tests purposes but it can be used by the code itself.
-- **micropython.js** and all others contain the actual test per each interpreter. If a test is the same across multiple interpreters it can be exported via the `_shared.js` file as it is for most _Pyodide_ and _MicroPython_ cases.
-
-The [test/integration.spec.js](./test/integration.spec.js) file simply loops over folders that match interpreters _by name_ and execute in parallel all tests.
-
-#### Manual Test
-
-To **test manually** an integration test, simply `npm run server` and reach the _html_ file created for that particular test.
-
-As example, reaching http://localhost:8080/test/integration/interpreter/micropython/fetch.html would log in the console and show expectations on the page and this can be easily tested via multiple browsers by simply reaching the very same integration test.
+We have hence moved and renamed _core_ as [polyscript](https://github.com/pyscript/polyscript/#readme) which is the base module to build up a better _PyScript Next_ without confusing our users or ourselves while talking about these two distinct projects.
diff --git a/pyscript.core/cjs/package.json b/pyscript.core/cjs/package.json
deleted file mode 100644
index 729ac4d9..00000000
--- a/pyscript.core/cjs/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{"type":"commonjs"}
diff --git a/pyscript.core/dev.cjs b/pyscript.core/dev.cjs
deleted file mode 100644
index 04fd1919..00000000
--- a/pyscript.core/dev.cjs
+++ /dev/null
@@ -1,33 +0,0 @@
-let queue = Promise.resolve();
-
-const { exec } = require("node:child_process");
-
-const build = (fileName) => {
- if (fileName) console.log(fileName, "changed");
- else console.log("building without optimizations");
- queue = queue.then(
- () =>
- new Promise((resolve, reject) => {
- exec(
- "npm run rollup:xworker && npm run rollup:core && npm run rollup:pyscript",
- { cwd: __dirname, env: { ...process.env, NO_MIN: true } },
- (error) => {
- if (error) reject(error);
- else
- resolve(
- console.log(fileName || "", "build completed"),
- );
- },
- );
- }),
- );
-};
-
-const options = {
- ignored: /\/(?:__template|interpreters|xworker)\.[mc]?js$/,
- persistent: true,
-};
-
-require("chokidar").watch("./esm", options).on("change", build);
-
-build();
diff --git a/pyscript.core/docs/README.md b/pyscript.core/docs/README.md
deleted file mode 100644
index 5dac0182..00000000
--- a/pyscript.core/docs/README.md
+++ /dev/null
@@ -1,475 +0,0 @@
-# PyScript Core Documentation
-
- * [Terminology](#terminology) - what we mean by "_term_" in this document
- * [Bootstrapping core](#bootstrapping-core) - how to enable PyScript Next in your page
- * [How Scripts Work](#how-scripts-work) - how `
-
-
-
-
-
-
-```
-
-ℹ️ - Please note we decided on purpose to not use the generic programming language name instead of its interpreter project name to avoid being too exclusive for alternative projects that would like to target that very same Programming Language (i.e. note *pyodide* & *micropython* not using *python* indeed as interpreter name).
-
-Custom values for the `type` attribute can also be created which alias (and potential build on top of) existing interpreter types. We include `
-
-
-
-```
-
-When it comes to the `property` or `field` attached to a `
-
-
-
-```
-
-ℹ️ - Please note that if no `target` attribute is specified, the *script* will automatically create a "_companion element_" when the `target` property/field is accessed for the very first time:
-
-```html
-
-
-```
-
-
-
-
-
- Env
-
-
-ℹ️ - This is an **advanced feature** that is worth describing but usually it is not needed for most common use cases.
-
-Mostly due its terseness that plays nicely as attribute's suffix, among its commonly understood meaning, we consider an *env* an identifier that guarantee the used *interpreter* would always be the same and no other interpreters, even if they point at very same project, could interfere with globals, behavior, or what's not.
-
-In few words, every single *env* would spawn a new interpreter dedicated to such env, and global variables defined elsewhere will not affect this "_environment_" and vice-versa, an *env* cannot dictate what will happen to other interpreters.
-
-```html
-
-
-
-
-
-
-```
-
-ℹ️ - Please note if the interpreter takes 1 second to bootstrap, multiple *environments* will take *that* second multiplied by the number of different environments, which is why this feature is considered for **advanced** use cases only and it should be discouraged as generic practice.
-
-
-
-
-
-## Bootstrapping core
-
-In order to have anything working at all in our pages, we need to at least bootstrap *@pyscript/core* functionalities, otherwise all examples and scripts mentioned in this document would just sit there ... sadly ignored by every browser:
-
-```html
-
-
-
-
-
-
-
-
-
-
-```
-
-As *core* exposes some utility/API, using the following method would also work:
-
-```html
-
-```
-
-Please keep reading this document to understand how to use those utilities or how to have other *Pogramming Languages* enabled in your page via `
-```
-
-Not only this is helpful to crawl the surrounding *DOM* or *HTML*, every script will also have a `target` property that will point either to the element reachable through the `target` attribute, or it lazily creates once a companion element that will be appended right after the currently executing *script*.
-
-Please read the [Terminology](#terminology) **target** dedicated details to know more.
-
-
-
-
-
- XWorker
-
-
-With or without access to the `document`, every (*non experimental*) interpreter will have defined, either at the global level or after an import (i.e.`from xworker import XWorker` in *Python* case), a reference to the `XWorker` "_class_" (it's just a *function*!), which goal is to enable off-loading heavy operations on a worker, without blocking the main / UI thread (the current page) and allowing such worker to even reach the `document` or anything else available on the very same main / UI thread.
-
-```html
-
-```
-
-Please read the [XWorker](#xworker) dedicated section to know more.
-
-
-
-
-
-## How Events Work
-
-The event should contain the *interpreter* or *custom type* prefix, followed by the *event* type it'd like to handle.
-
-```html
-
-
-```
-
-Differently from *Web* inline events, there's no code evaluation at all within the attribute: it's just a globally available name that will receive the current event and nothing else.
-
-#### The type-env attribute
-
-Just as the `env` attribute on a `
-
-
-
-
-```
-
-As mentioned before, this will work with `py-env` too, or any custom type defined out there.
-
-
-## XWorker
-
-Whenever computing relatively expensive stuff, such as a *matplot* image, or literally anything else that would take more than let's say 100ms to answer, running your *interpreter* of choice within a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is likely desirable, so that the main / UI thread won't block users' actions, listeners, or any other computation going on in these days highly dynamic pages.
-
-`@pyscript/core` adds a functionality called `XWorker` to all of the interpreters it offers, which works in each language the way `Worker` does in JavaScript.
-
-In each Interpreter, `XWorker` is either global reference or an import (i.e.`from xworker import XWorker` in *Python* case) module's utility, with a counter `xworker` (lower case) global reference, or an import (i.e.`from xworker import xworker` in *Python* case) module's utility, within the worker code.
-
-In short, the `XWorker` utility is to help, without much thinking, to run any desired interpreter out of a *Worker*, enabling extra features on the *worker*'s code side.
-
-
-### Enabling XWorker
-
-We use the latest Web technologies to allow fast, non-blocking, yet synchronous like, operations from any non-experimental interpreter's worker, and the standard requires some special header to enable such technologies and, most importantly, the [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).
-
-There is an exhaustive [section](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements) around this topic but the *TL;DR* version is:
-
- * to protect your page from undesired attacks, the `Cross-Origin-Opener-Policy` header should be present with the `same-origin` value
- * to protect other sites from your pages' code, the `Cross-Origin-Embedder-Policy` header should be present with either the `credentialless` value (Chrome and Firefox browsers) or the `require-corp` one (Safari + other browsers)
- * when the `Cross-Origin-Embedder-Policy` header is set with the `require-corp` value, the `Cross-Origin-Resource-Policy` header should also be available with [one of these options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy): `same-site`, `same-origin` or `cross-origin`
-
-There are **alternative ways** to enable these headers for your site or local host, and [this script](https://github.com/gzuidhof/coi-serviceworker#readme) is just one of these, one that works with most free-hosting websites too.
-
-
-### XWorker options
-
-Before showing any example, it's important to understand how the offered API differs from Web standard *workers*:
-
-| name | example | behavior |
-| :-------- | :------------------------------------------------------- | :--------|
-| async | `XWorker('./file.py', async=True)` | The worker code is evaluated via `runAsync` utility where, if the *interpreter* allows it, top level *await* would be possible, among other *PL* specific asynchronous features. |
-| config | `XWorker('./file.py', config='./cfg.toml')` | The worker will load and parse the *JSON* or *TOML* file to configure itself. Please see [currently supported config values](https://docs.pyscript.net/latest/reference/elements/py-config.html#supported-configuration-values) as this is currently based on `` features. |
-| type | `XWorker('./file.py', type='pyodide')` | Define the *interpreter* to use with this worker which is, by default, the same one used within the running code. Please read the [Terminology](#terminology) **interpreter** dedicated details to know more. |
-| version | `XWorker('./file.py', type='pyodide', version='0.23.2')` | Allow the usage of a specific version where, if numeric, must be available through the project *CDN* used by *core* but if specified as fully qualified *URL*, allows usage of any interpreter's version: `",\n}\n\n\n# these are set by _set_version_info\n__version__ = None\nversion_info = None\n\n\ndef _set_version_info(version_from_interpreter: str):\n """Sets the __version__ and version_info properties from provided JSON data\n Args:\n version_from_interpreter (str): A "dotted" representation of the version:\n YYYY.MM.m(m).releaselevel\n Year, Month, and Minor should be integers; releaselevel can be any string\n """\n global __version__\n global version_info\n\n __version__ = version_from_interpreter\n\n version_parts = version_from_interpreter.split(".")\n year = int(version_parts[0])\n month = int(version_parts[1])\n minor = int(version_parts[2])\n if len(version_parts) > 3:\n releaselevel = version_parts[3]\n else:\n releaselevel = ""\n\n VersionInfo = namedtuple("version_info", ("year", "month", "minor", "releaselevel"))\n version_info = VersionInfo(year, month, minor, releaselevel)\n\n # we ALSO set PyScript.__version__ and version_info for backwards\n # compatibility. Should be killed eventually.\n PyScript.__version__ = __version__\n PyScript.version_info = version_info\n\n\nclass HTML:\n """\n Wrap a string so that display() can render it as plain HTML\n """\n\n def __init__(self, html):\n self._html = html\n\n def _repr_html_(self):\n return self._html\n\n\ndef eval_formatter(obj, print_method):\n """\n Evaluates a formatter method.\n """\n if print_method == "__repr__":\n return repr(obj)\n elif hasattr(obj, print_method):\n if print_method == "savefig":\n buf = io.BytesIO()\n obj.savefig(buf, format="png")\n buf.seek(0)\n return base64.b64encode(buf.read()).decode("utf-8")\n return getattr(obj, print_method)()\n elif print_method == "_repr_mimebundle_":\n return {}, {}\n return None\n\n\ndef format_mime(obj):\n """\n Formats object using _repr_x_ methods.\n """\n if isinstance(obj, str):\n return html.escape(obj), "text/plain"\n\n mimebundle = eval_formatter(obj, "_repr_mimebundle_")\n if isinstance(mimebundle, tuple):\n format_dict, _ = mimebundle\n else:\n format_dict = mimebundle\n\n output, not_available = None, []\n for method, mime_type in reversed(MIME_METHODS.items()):\n if mime_type in format_dict:\n output = format_dict[mime_type]\n else:\n output = eval_formatter(obj, method)\n\n if output is None:\n continue\n elif mime_type not in MIME_RENDERERS:\n not_available.append(mime_type)\n continue\n break\n if output is None:\n if not_available:\n js.console.warn(\n f"Rendered object requested unavailable MIME renderers: {not_available}"\n )\n output = repr(output)\n mime_type = "text/plain"\n elif isinstance(output, tuple):\n output, meta = output\n else:\n meta = {}\n return MIME_RENDERERS[mime_type](output, meta), mime_type\n\n\ndef run_until_complete(f):\n _ = loop.run_until_complete(f)\n\n\ndef write(element_id, value, append=False, exec_id=0):\n """Writes value to the element with id "element_id"""\n Element(element_id).write(value=value, append=append)\n js.console.warn(\n dedent(\n """PyScript Deprecation Warning: PyScript.write is\n marked as deprecated and will be removed sometime soon. Please, use\n Element().write instead."""\n )\n )\n\n\ndef set_current_display_target(target_id):\n get_current_display_target._id = target_id\n\n\ndef get_current_display_target():\n return get_current_display_target._id\n\n\nget_current_display_target._id = None\n\n\ndef display(*values, target=None, append=True):\n default_target = get_current_display_target()\n if default_target is None and target is None:\n raise Exception(\n "Implicit target not allowed here. Please use display(..., target=...)"\n )\n if target is not None:\n for v in values:\n Element(target).write(v, append=append)\n else:\n for v in values:\n Element(default_target).write(v, append=append)\n\n\nclass Element:\n def __init__(self, element_id, element=None):\n self._id = element_id\n self._element = element\n\n @property\n def id(self):\n return self._id\n\n @property\n def element(self):\n """Return the dom element"""\n if not self._element:\n self._element = js.document.querySelector(f"#{self._id}")\n return self._element\n\n @property\n def value(self):\n return self.element.value\n\n @property\n def innerHtml(self):\n return self.element.innerHTML\n\n def write(self, value, append=False):\n html, mime_type = format_mime(value)\n if html == "\\n":\n return\n\n if append:\n child = js.document.createElement("div")\n self.element.appendChild(child)\n\n if append and self.element.children:\n out_element = self.element.children[-1]\n else:\n out_element = self.element\n\n if mime_type in ("application/javascript", "text/html"):\n script_element = js.document.createRange().createContextualFragment(html)\n out_element.appendChild(script_element)\n else:\n out_element.innerHTML = html\n\n def clear(self):\n if hasattr(self.element, "value"):\n self.element.value = ""\n else:\n self.write("", append=False)\n\n def select(self, query, from_content=False):\n el = self.element\n\n if from_content:\n el = el.content\n\n _el = el.querySelector(query)\n if _el:\n return Element(_el.id, _el)\n else:\n js.console.warn(f"WARNING: can\'t find element matching query {query}")\n\n def clone(self, new_id=None, to=None):\n if new_id is None:\n new_id = self.element.id\n\n clone = self.element.cloneNode(True)\n clone.id = new_id\n\n if to:\n to.element.appendChild(clone)\n # Inject it into the DOM\n to.element.after(clone)\n else:\n # Inject it into the DOM\n self.element.after(clone)\n\n return Element(clone.id, clone)\n\n def remove_class(self, classname):\n if isinstance(classname, list):\n for cl in classname:\n self.remove_class(cl)\n else:\n self.element.classList.remove(classname)\n\n def add_class(self, classname):\n if isinstance(classname, list):\n for cl in classname:\n self.element.classList.add(cl)\n else:\n self.element.classList.add(classname)\n\n\ndef add_classes(element, class_list):\n for klass in class_list.split(" "):\n element.classList.add(klass)\n\n\ndef create(what, id_=None, classes=""):\n element = js.document.createElement(what)\n if id_:\n element.id = id_\n add_classes(element, classes)\n return Element(id_, element)\n\n\nclass PyWidgetTheme:\n def __init__(self, main_style_classes):\n self.main_style_classes = main_style_classes\n\n def theme_it(self, widget):\n for klass in self.main_style_classes.split(" "):\n widget.classList.add(klass)\n\n\nclass PyItemTemplate(Element):\n label_fields = None\n\n def __init__(self, data, labels=None, state_key=None, parent=None):\n self.data = data\n\n self.register_parent(parent)\n\n if not labels:\n labels = list(self.data.keys())\n self.labels = labels\n\n self.state_key = state_key\n\n super().__init__(self._id)\n\n def register_parent(self, parent):\n self._parent = parent\n if parent:\n self._id = f"{self._parent._id}-c-{len(self._parent._children)}"\n self.data["id"] = self._id\n else:\n self._id = None\n\n def create(self):\n new_child = create("div", self._id, "py-li-element")\n new_child._element.innerHTML = dedent(\n f"""\n \n """\n )\n return new_child\n\n def on_click(self, evt):\n pass\n\n def pre_append(self):\n pass\n\n def post_append(self):\n self.element.click = self.on_click\n self.element.onclick = self.on_click\n\n self._post_append()\n\n def _post_append(self):\n pass\n\n def strike(self, value, extra=None):\n if value:\n self.add_class("line-through")\n else:\n self.remove_class("line-through")\n\n def render_content(self):\n return " - ".join([self.data[f] for f in self.labels])\n\n\nclass PyListTemplate:\n theme = PyWidgetTheme("py-li-element")\n item_class = PyItemTemplate\n\n def __init__(self, parent):\n self.parent = parent\n self._children = []\n self._id = self.parent.id\n\n @property\n def children(self):\n return self._children\n\n @property\n def data(self):\n return [c.data for c in self._children]\n\n def render_children(self):\n binds = {}\n for i, c in enumerate(self._children):\n txt = c.element.innerHTML\n rnd = str(time.time()).replace(".", "")[-5:]\n new_id = f"{c.element.id}-{i}-{rnd}"\n binds[new_id] = c.element.id\n txt = txt.replace(">", f" id=\'{new_id}\'>")\n print(txt)\n\n def foo(evt):\n evtEl = evt.srcElement\n srcEl = Element(binds[evtEl.id])\n srcEl.element.onclick()\n evtEl.classList = srcEl.element.classList\n\n for new_id in binds:\n Element(new_id).element.onclick = foo\n\n def connect(self):\n self.md = main_div = js.document.createElement("div")\n main_div.id = self._id + "-list-tasks-container"\n\n if self.theme:\n self.theme.theme_it(main_div)\n\n self.parent.appendChild(main_div)\n\n def add(self, *args, **kws):\n if not isinstance(args[0], self.item_class):\n child = self.item_class(*args, **kws)\n else:\n child = args[0]\n child.register_parent(self)\n return self._add(child)\n\n def _add(self, child_elem):\n self.pre_child_append(child_elem)\n child_elem.pre_append()\n self._children.append(child_elem)\n self.md.appendChild(child_elem.create().element)\n child_elem.post_append()\n self.child_appended(child_elem)\n return child_elem\n\n def pre_child_append(self, child):\n pass\n\n def child_appended(self, child):\n """Overwrite me to define logic"""\n pass\n\n\nclass TopLevelAsyncFinder(ast.NodeVisitor):\n def is_source_top_level_await(self, source):\n self.async_found = False\n node = ast.parse(source)\n self.generic_visit(node)\n return self.async_found\n\n def visit_Await(self, node):\n self.async_found = True\n\n def visit_AsyncFor(self, node):\n self.async_found = True\n\n def visit_AsyncWith(self, node):\n self.async_found = True\n\n def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef):\n pass # Do not visit children of async function defs\n\n\ndef uses_top_level_await(source: str) -> bool:\n return TopLevelAsyncFinder().is_source_top_level_await(source)\n\n\nclass Plugin:\n def __init__(self, name=None):\n if not name:\n name = self.__class__.__name__\n\n self.name = name\n self._custom_elements = []\n self.app = None\n\n def init(self, app):\n self.app = app\n\n def register_custom_element(self, tag):\n """\n Decorator to register a new custom element as part of a Plugin and associate\n tag to it. Internally, it delegates the registration to the PyScript internal\n [JS] plugin manager, who actually creates the JS custom element that can be\n attached to the page and instantiate an instance of the class passing the custom\n element to the plugin constructor.\n\n Exammple:\n >> plugin = Plugin("PyTutorial")\n >> @plugin.register_custom_element("py-tutor")\n >> class PyTutor:\n >> def __init__(self, element):\n >> self.element = element\n """\n # TODO: Ideally would be better to use the logger.\n js.console.info(f"Defining new custom element {tag}")\n\n def wrapper(class_):\n # TODO: this is very pyodide specific but will have to do\n # until we have JS interface that works across interpreters\n define_custom_element(tag, create_proxy(class_)) # noqa: F821\n\n self._custom_elements.append(tag)\n return create_proxy(wrapper)\n\n\nclass DeprecatedGlobal:\n """\n Proxy for globals which are deprecated.\n\n The intendend usage is as follows:\n\n # in the global namespace\n Element = pyscript.DeprecatedGlobal(\'Element\', pyscript.Element, "...")\n console = pyscript.DeprecatedGlobal(\'console\', js.console, "...")\n ...\n\n The proxy forwards __getattr__ and __call__ to the underlying object, and\n emit a warning on the first usage.\n\n This way users see a warning only if they actually access the top-level\n name.\n """\n\n def __init__(self, name, obj, message):\n self.__name = name\n self.__obj = obj\n self.__message = message\n self.__warning_already_shown = False\n\n def __repr__(self):\n return f""\n\n def _show_warning(self, message):\n """\n NOTE: this is overridden by unit tests\n """\n # this showWarning is implemented in js and injected into this\n # namespace by main.ts\n showWarning(message, "html") # noqa: F821\n\n def _show_warning_maybe(self):\n if self.__warning_already_shown:\n return\n self._show_warning(self.__message)\n self.__warning_already_shown = True\n\n def __getattr__(self, attr):\n self._show_warning_maybe()\n return getattr(self.__obj, attr)\n\n def __call__(self, *args, **kwargs):\n self._show_warning_maybe()\n return self.__obj(*args, **kwargs)\n\n def __iter__(self):\n self._show_warning_maybe()\n return iter(self.__obj)\n\n def __getitem__(self, key):\n self._show_warning_maybe()\n return self.__obj[key]\n\n def __setitem__(self, key, value):\n self._show_warning_maybe()\n self.__obj[key] = value\n\n\nclass PyScript:\n """\n This class is deprecated since 2022.12.1.\n\n All its old functionalities are available as module-level functions. This\n class should be killed eventually.\n """\n\n loop = loop\n\n @staticmethod\n def run_until_complete(f):\n run_until_complete(f)\n\n @staticmethod\n def write(element_id, value, append=False, exec_id=0):\n write(element_id, value, append, exec_id)\n\n\ndef _install_deprecated_globals_2022_12_1(ns):\n """\n Install into the given namespace all the globals which have been\n deprecated since the 2022.12.1 release. Eventually they should be killed.\n """\n\n def deprecate(name, obj, instead):\n message = f"Direct usage of {name} is deprecated. " + instead\n ns[name] = DeprecatedGlobal(name, obj, message)\n\n # function/classes defined in pyscript.py ===> pyscript.XXX\n pyscript_names = [\n "PyItemTemplate",\n "PyListTemplate",\n "PyWidgetTheme",\n "add_classes",\n "create",\n "loop",\n ]\n for name in pyscript_names:\n deprecate(\n name, globals()[name], f"Please use pyscript.{name} instead."\n )\n\n # stdlib modules ===> import XXX\n stdlib_names = [\n "asyncio",\n "base64",\n "io",\n "sys",\n "time",\n "datetime",\n "pyodide",\n "micropip",\n ]\n for name in stdlib_names:\n obj = __import__(name)\n deprecate(name, obj, f"Please use import {name} instead.")\n\n # special case\n deprecate(\n "dedent", dedent, "Please use from textwrap import dedent instead."\n )\n\n # these are names that used to leak in the globals but they are just\n # implementation details. People should not use them.\n private_names = [\n "eval_formatter",\n "format_mime",\n "identity",\n "render_image",\n "MIME_RENDERERS",\n "MIME_METHODS",\n ]\n for name in private_names:\n obj = globals()[name]\n message = (\n f"{name} is deprecated. "\n "This is a private implementation detail of pyscript. "\n "You should not use it."\n )\n ns[name] = DeprecatedGlobal(name, obj, message)\n\n # these names are available as js.XXX\n for name in ["document", "console"]:\n obj = getattr(js, name)\n deprecate(name, obj, f"Please use js.{name} instead.")\n\n # PyScript is special, use a different message\n message = (\n "The PyScript object is deprecated. "\n "Please use pyscript instead."\n )\n ns["PyScript"] = DeprecatedGlobal("PyScript", PyScript, message)\n';
-
- const logger = getLogger("pyscript/main");
- /* High-level overview of the lifecycle of a PyScript App:
-
- 1. pyscript.js is loaded by the browser. PyScriptApp().main() is called
-
- 2. loadConfig(): search for py-config and compute the config for the app
-
- 3. (it used to be "show the splashscreen", but now it's a plugin)
-
- 4. loadInterpreter(): start downloading the actual interpreter (e.g. pyodide.js)
-
- --- wait until (4) has finished ---
-
- 5. now the pyodide src is available. Initialize the engine
-
- 6. setup the environment, install packages
-
- 6.5: call the Plugin.afterSetup() hook
-
- 7. connect the py-script web component. This causes the execution of all the
- user scripts
-
- 8. initialize the rest of web components such as py-button, py-repl, etc.
-
- More concretely:
-
- - Points 1-4 are implemented sequentially in PyScriptApp.main().
-
- - PyScriptApp.loadInterpreter adds a
-
-
-
-
-