* Apply prettier to css, js, html, md, ts, and yml
As a followup I will add prettier to the .pre-commit config.
This patch is 100% generated by prettier.
I used a forked version of prettier that understands the
py-script tag.
See https://github.com/hoodmane/pyscript-prettier-precommit
for more info.
* Apply old pre-commit
* Revert some problems
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Revert some changes
* More changes
* Fix pre-commit
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* 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
* Add beforePyScriptExec, afterPyScriptExec lifecycle hooks
* Add stdiodirector plugin for `output`, `stderr` attributes of py-script tag
* Add docs on `output` and `stderr` attributes of py-script tag
* Tests
* Removed output deprecation warning for `output` attribute
* Add createSingularWarning(), with createDeprecationWarning as alias
* Show deprecation banner
* Add test for deprecation warning
* Remove deprecated elements
* Add entry in changelog
* Update test_style
* Remove random color rule
* Add PR link to changelog
* Add runtime.invalidate_module_path_cache() to clear importlib's cache of modules
* Clear cache after [[fetch]], after plugin files download, after plugins setup, and prior to py-script tag execution.
This PR move codes from main.ts into two new plugins:
- splashscreen (formerly known as py-loader)
- importmap
The old setting config.autoclose_loader is still supported but deprecated; the new setting is config.splashscreen.autoclose.
Moreover, it does a small refactoring around UserError: now UserErrors are correctly caught even if they are raised from within afterRuntimeLoad.
This PR does two things:
1. introduce the first minimal version of a Plugin system. Plugins are subclasses of the Plugin class, and pyscript will call the relevant methods/hooks at the right time. Currently, I have added only the minimal sets of hooks which were needed for this PR.
2. Implement <py-terminal> as a plugin.
* implement proposal
* update docs and replace py-env
* more docs
* suggested proposal
* update docs
* add to_file parameter
* remove comment from Makefile
* suggested improvements
* move tests from basic to py_config
* retain leading slash from the first path
Major highlights:
1. Merge&simplify base.ts and pyrepl.ts; kill base.ts
2. improve and extente the py-repl integration tests
3. Reorder the code in pyrepl.ts. This part of the PR doesn't change much of the concrete logic: it's just a sequence of renaming variables, moving code around, group code into functions, killing code which is no longer needed. But the end result is much better and nicer to read, IMHO.
Minor highlights:
1. py-repl now uses the new logic in pyexec.ts to run the code
2. after PR Add display impl, rm outputManage, print and console.log default to browser console #749 py-repl no longer displayed the result of the last evaluated expression (e.g. if you typed 42 and run it, it displayed nothing). This PR re-introduces this behavior, which is what you would expect by a REPL.
3. improve the pytest --dev option: now it implies --no-fake-server so that sourcemaps works automatically
4. improve the names of the CSS classes to be more consistent
5. kill pyrepl.test.ts: the old tests didn't check anything useful, this style of unit test doesn't really add much value if you have good integration tests (which now we have) and trying to revive them was not worth the hassle
Yet another refactoring to untangle the old mess.
Highlights:
base.ts, pyscript.ts and pyrepl.ts were a tangled mess of code, in which each of them interacted with the others in non-obvious ways. Now PyScript is no longer a subclass of BaseEvalElement and it is much simpler. I removed code for handling the attributes std-out and std-err because they are no longer needed with the new display() logic.
The logic for executing python code is now in pyexec.ts: so we are decoupling the process of "finding" the python code (handled by the py-script web component) and the logic to actually execute it. This has many advantages, including the fact that it will be more easily usable by other components (e.g. pyrepl). Also, note that it's called pyexec and not pyeval: in the vast majority of cases in Python you have statements to execute, and almost never expressions to evaluate.
I killed the last remaining global store, scriptQueue tada. As a bonus effect, now we automatically do the correct thing when a <py-script> tag is dynamically added to the DOM (I added a test for it). I did not remove svelte from packages.json, because I don't fully understand the implications: there are various options which mention svelte in rollup.js and tsconfig.json, so it's probably better to kill it in its own PR.
pyexec.ts is also responsible of handling the default target for display() and correct handling/visualization of exceptions. I fixed/improved/added display/output tests in the process.
I also found a problem though, see issue #878, so I improved the test and marked it as xfail.
I removed BaseEvalElement as the superclass of most components. Now the only class which inherits from it is PyRepl. In a follow-up PR, I plan to merge them into a single class and do more cleanup.
During the refactoring, I killed guidGenerator: now instead of generating random py-* IDs which are very hard to read for humans, we generated py-internal-X IDs, where X is 0, 1, 2, 3, etc. This makes writing tests and debugging much easier.
I improved a lot our test machinery: it turns out that PR #829 broke the ability to use/view sourcemaps inside the playwright browser (at least on my machine).
For some reason chromium is unable to find sourcemaps if you use playwrights internal routing. So I reintroduced the http_server fixture which was removed by that PR, and added a pytest option --no-fake-server to use it instead, useful for debugging. By default we are still using the fakeserver though (which is faster and parallelizable).
Similarly, I added --dev which implies --headed and also automatically open chrome dev tools.
As the title stays, the main goal of the branch is to kill the infamous runtimeLoaded global store and all the complications, problems and bugs caused by the fact that in many places we needed to ensure/wait that the global runtime was properly set before being able to execute code.
The core idea is that runtime is never a global object and that it's passed around explicitly, which means that when a function receives it, it is guaranteed to be initialized&ready.
This caused a bit of complications in pybutton.ts, pyinputbox.ts and pyrepl.ts, because they indirectly want to call runtime.run from connectedCallback, which is the only place where we cannot explicitly pass the runtime because it's automatically called by the browser.
But also, it is also a sign of a bad design, because it were entirely possible that connectedCallback was called before the runtime was ready, which probably caused many bugs, see e.g. #673 and #747.
The solution to is use dependency injection and create the class later on: so instead of having a global PyButton class which relies on a global runtime (whose state is uncertain) we have a make_PyButton function which takes a runtime and make a PyButton class which is tied to that specific runtime (whose state is certainly ready, because we call make_PyButton only when we know that the runtime is ready).
Similar for PyInputBox and PyRepl.
Other highlights: thanks to this, I could kill the also infamous runAfterRuntimeInitialized and a couple of smelly lines which used setTimeout to "wait" for the runtime.
While I was at it, I also called a lot of other stores which were completely unused and where probably leftovers from a past universe.
This is a follow-up of PR #806 and it's a big step forward towards solving issue #763.
The basic idea is that at this stage I want to streamline the execution logic
and make it as linear and easy to read/understand as possible. The diff is
relatively big, but for the most part is just "shuffling code around".
Svelte stores:
the idea is to eventually kill of them, so that we can remove the dependency
on svelte but also to avoid relying on so much global state, which makes
things more complicated and error-prone (e.g., we have several issues related
to using runtime when it's not ready yet).
I killed addInitializer, addPostInitializer and the corresponding svelte
stores tada. They are no longer needed since the relevant code is called
directly from main.ts.
I started to kill the usage of the runtimeLoaded svelte store: instead of
relying on a global variable, I want to arrive at the point in which the
runtime is passed as a parameter in all places where it's needed: pyscript.ts
is now free of global state, but I couldn't kill it yet because it's used
heavily by base.ts and pyrepl.ts. I will do it in another PR.
Other misc changes:
I added sanity checks (and corresponding tests!) which complain if you specify
0 or multiple runtimes. Currently we support having one and only one, so there
is no point to pretend otherwise
I modified the messages displayed by the loader, to be more informative from
the user point of view.
This PR is the first step to improve and rationalize the life-cycle of a pyscript app along the lines of what I described in #763 .
It is not a complete solution, more PRs will follow.
Highlights:
- py-config is no longer a web component: the old code relied on PyConfig.connectedCallback to do some logic, but then if no <py-config> tag was present, we had to introduce a dummy one with the sole goal of activating the callback. Now the logic is much more linear.
- the new pyconfig.ts only contains the code which is needed to parse the config; I also moved some relevant code from utils.ts because it didn't really belong to it
- the old PyConfig class did much more than dealing with the config: in particular, it contained the code to initialize the env and the runtime. Now this logic has been moved directly into main.ts, inside the new PyScriptApp class. I plan to refactor the initialization code in further PRs
- the current code relies too much on global state and global variables, they are everywhere. This PR is a first step to solve the problem by introducing a PyScriptApp class, which will hold all the mutable state of the page. Currently only config is stored there, but eventually I will migrate more state to it, until we will have only one global singleton, globalApp
- thanks to what I described above, I could kill the appConfig svelte store: one less store to kill :).
* TOML Error Cases
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* remove traceback
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* any is a ts feature
* full eslint
* format and disable eslint for toml.js
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <madhurtandon23@gmail.com>
* Minimium viable py-config default schema
* Add packages and paths to default
* Add in default for plugins
* Remove tests for values no longer in the default config
* Add unit tests for pyloader and pytitle
* Add more unit tests for pyrepl, pybox and pyinputbox
* Add more tests for pyscript and pyconfig
* White space
* Fix d3 tests and improve more examples test
* Update matplotlib test
* Add numpy to dependencies
* Address Madhur comments
* Update test name
* add toml support for configs with fast-toml
* fix package-lock.json and pin pyodide to 0.21.2
* use browser version of fast-toml
* disable eslint and add credits
* fix jest issues
* use type attribute for py-config
* refactor py-config to use toml
* switch from toml to json and add unit tests
* fix test for py-config
* fix integration test
* use flat structure for JSON
* allow merging configs
* replace arrays instead of concatenating them
* remove extra keys from inline config of integration test
* simplify array replacement logic
* allow config from src to be partial as well
* add comments to unit tests
* add unit test for setting config from both inline and src
* handle parse errors + validate config supplied
* separate functions for src and inline
* suggested improvements
* show error message in red on parser error
* fix eslint
* use resolveJsonModule as true
* use default config defined as a variable without import
* remove disable eslint comment
* remove import for covfefe.json as well
* metadata injection
* add support for schema + extra keys
* use schema_version
This PR tries to improve and rationalize what we log. Key points:
- introduce `logger.ts`: each file/component is encouraged to use the logger instead of writing directly to `console.*`
* the logger automatically prepend a prefix like `[py-config]`, `[py-env]` which make it easier to understand where a certain message is printed from
* it provide a central place where to add more features in the future. E.g., I can imagine having a config setting to completely silence the logs (not implemented yet)
- use the new loggers everywhere
- write to `.info()` instead of `.log()`. The idea is to keep `console.log` free, so that for the users it's easier to tell apart their own messages and the pyscript ones
- generally improve what we log. This is an endless exercise, but I tried to print more things which are useful to understand what's going on and in which order the various things are executed, and remove prints which were clearly debugging leftovers
* add integration test for py-config
* fix bug
* fix test
* remove indexURL altogether
* make jest happy
* fix create_proxy import
* check that py-config loads an older version
* add unit test
* suggested changes
* don't use /tmp because of bandit
* PyodideRuntime should be one of the runtimes
* subsume interpreter into runtime API
* fix eslint
* add comments
* move initializers, postInitializers, scriptsQueue, etc. to initialize() of Runtime Super Class
* modify comment for initialize
* small renaming
* change id to default
* fix pyscript.py import
* try adding tests
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add inlineDynamicImports option
* Make jest happy about ESM modules
* Attempt to make jest happy about pyodide
* point to version in accordance with node module being used
* fix base.ts
* fix tests
* fix indexURL path determination
* edit pyodide.asm.js as a part of setup process
* load runtime beforeAll tests
* add test for loading a package
* use only runPythonAsync underneath for pyodide
* import PyodideInterface type directly from pyodide
* add some comments
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
* install test dependencies
* change config for tests
* fix linter failing tests
* add basic test file
* add custom element registration to test
* update dependencies
* add jest config file
* fix test calls on makefile and minor fix on test
* update local npm version
* clean testm file