@pyscript/core 0.1.22 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/core.css +1 -1
  2. package/dist/core.js +2 -2
  3. package/dist/core.js.map +1 -1
  4. package/dist/error-e4fe78fd.js +2 -0
  5. package/dist/error-e4fe78fd.js.map +1 -0
  6. package/package.json +2 -2
  7. package/src/core.css +3 -1
  8. package/src/core.js +170 -161
  9. package/src/plugins/error.js +2 -2
  10. package/src/stdlib/pyscript/__init__.py +10 -1
  11. package/src/stdlib/pyscript/display.py +7 -0
  12. package/src/stdlib/pyscript/util.py +3 -4
  13. package/src/stdlib/pyscript.js +3 -3
  14. package/dist/error-87e0706c.js +0 -2
  15. package/dist/error-87e0706c.js.map +0 -1
  16. package/tests/integration/__init__.py +0 -0
  17. package/tests/integration/conftest.py +0 -184
  18. package/tests/integration/support.py +0 -1038
  19. package/tests/integration/test_00_support.py +0 -495
  20. package/tests/integration/test_01_basic.py +0 -353
  21. package/tests/integration/test_02_display.py +0 -452
  22. package/tests/integration/test_03_element.py +0 -303
  23. package/tests/integration/test_assets/line_plot.png +0 -0
  24. package/tests/integration/test_assets/tripcolor.png +0 -0
  25. package/tests/integration/test_async.py +0 -197
  26. package/tests/integration/test_event_handling.py +0 -193
  27. package/tests/integration/test_importmap.py +0 -66
  28. package/tests/integration/test_interpreter.py +0 -98
  29. package/tests/integration/test_plugins.py +0 -419
  30. package/tests/integration/test_py_config.py +0 -294
  31. package/tests/integration/test_py_repl.py +0 -663
  32. package/tests/integration/test_py_terminal.py +0 -270
  33. package/tests/integration/test_runtime_attributes.py +0 -64
  34. package/tests/integration/test_script_type.py +0 -121
  35. package/tests/integration/test_shadow_root.py +0 -33
  36. package/tests/integration/test_splashscreen.py +0 -124
  37. package/tests/integration/test_stdio_handling.py +0 -370
  38. package/tests/integration/test_style.py +0 -47
  39. package/tests/integration/test_warnings_and_banners.py +0 -32
  40. package/tests/integration/test_zz_examples.py +0 -419
  41. package/tests/integration/test_zzz_docs_snippets.py +0 -305
@@ -1,294 +0,0 @@
1
- import os
2
- import tarfile
3
- import tempfile
4
- from pathlib import Path
5
-
6
- import pytest
7
- import requests
8
-
9
- from .support import PyScriptTest, with_execution_thread
10
-
11
- PYODIDE_VERSION = "0.23.4"
12
-
13
-
14
- @pytest.fixture
15
- def pyodide_tar(request):
16
- """
17
- Fixture which returns a local copy of pyodide. It uses pytest-cache to
18
- avoid re-downloading it between runs.
19
- """
20
- URL = (
21
- f"https://github.com/pyodide/pyodide/releases/download/{PYODIDE_VERSION}/"
22
- f"pyodide-core-{PYODIDE_VERSION}.tar.bz2"
23
- )
24
- tar_name = Path(URL).name
25
-
26
- val = request.config.cache.get(tar_name, None)
27
- if val is None:
28
- response = requests.get(URL, stream=True)
29
- TMP_DIR = tempfile.mkdtemp()
30
- TMP_TAR_LOCATION = os.path.join(TMP_DIR, tar_name)
31
- with open(TMP_TAR_LOCATION, "wb") as f:
32
- f.write(response.raw.read())
33
- val = TMP_TAR_LOCATION
34
- request.config.cache.set(tar_name, val)
35
- return val
36
-
37
-
38
- def unzip(location, extract_to="."):
39
- file = tarfile.open(name=location, mode="r:bz2")
40
- file.extractall(path=extract_to)
41
-
42
-
43
- # Disable the main/worker dual testing, for two reasons:
44
- #
45
- # 1. the <py-config> logic happens before we start the worker, so there is
46
- # no point in running these tests twice
47
- #
48
- # 2. the logic to inject execution_thread into <py-config> works only with
49
- # plain <py-config> tags, but here we want to test all weird combinations
50
- # of config
51
- @with_execution_thread(None)
52
- class TestConfig(PyScriptTest):
53
- def test_py_config_inline(self):
54
- self.pyscript_run(
55
- """
56
- <py-config>
57
- name = "foobar"
58
- </py-config>
59
-
60
- <py-script async>
61
- from pyscript import window, document
62
- promise = await document.currentScript._pyodide.promise
63
- window.console.log("config name:", promise.config.name)
64
- </py-script>
65
- """
66
- )
67
- assert self.console.log.lines[-1] == "config name: foobar"
68
-
69
- def test_py_config_external(self):
70
- pyconfig_toml = """
71
- name = "app with external config"
72
- """
73
- self.writefile("pyconfig.toml", pyconfig_toml)
74
- self.pyscript_run(
75
- """
76
- <py-config src="pyconfig.toml"></py-config>
77
-
78
- <py-script async>
79
- from pyscript import window, document
80
- promise = await document.currentScript._pyodide.promise
81
- window.console.log("config name:", promise.config.name)
82
- </py-script>
83
- """
84
- )
85
- assert self.console.log.lines[-1] == "config name: app with external config"
86
-
87
- # The default pyodide version is newer than
88
- # the one we are loading below (after downloading locally)
89
- # which is 0.22.0
90
-
91
- # The test checks if loading a different interpreter is possible
92
- # and that too from a locally downloaded file without needing
93
- # the use of explicit `indexURL` calculation.
94
- def test_interpreter_config(self, pyodide_tar):
95
- unzip(pyodide_tar, extract_to=self.tmpdir)
96
- self.pyscript_run(
97
- """
98
- <py-config type="json">
99
- {
100
- "interpreters": [{
101
- "src": "/pyodide/pyodide.js",
102
- "name": "my-own-pyodide",
103
- "lang": "python"
104
- }]
105
- }
106
- </py-config>
107
-
108
- <py-script>
109
- import sys, js
110
- pyodide_version = sys.modules["pyodide"].__version__
111
- js.console.log("version", pyodide_version)
112
- </py-script>
113
- """,
114
- )
115
-
116
- assert self.console.log.lines[-1] == f"version {PYODIDE_VERSION}"
117
-
118
- @pytest.mark.skip("FIXME: We need to restore the banner.")
119
- def test_invalid_json_config(self):
120
- # we need wait_for_pyscript=False because we bail out very soon,
121
- # before being able to write 'PyScript page fully initialized'
122
- self.pyscript_run(
123
- """
124
- <py-config type="json">
125
- [[
126
- </py-config>
127
- """,
128
- wait_for_pyscript=False,
129
- )
130
- banner = self.page.wait_for_selector(".py-error")
131
- assert "SyntaxError: Unexpected end of JSON input" in self.console.error.text
132
- expected = (
133
- "(PY1000): The config supplied: [[ is an invalid JSON and cannot be "
134
- "parsed: SyntaxError: Unexpected end of JSON input"
135
- )
136
- assert banner.inner_text() == expected
137
-
138
- @pytest.mark.skip("FIXME: We need to restore the banner.")
139
- def test_invalid_toml_config(self):
140
- # we need wait_for_pyscript=False because we bail out very soon,
141
- # before being able to write 'PyScript page fully initialized'
142
- self.pyscript_run(
143
- """
144
- <py-config>
145
- [[
146
- </py-config>
147
- """,
148
- wait_for_pyscript=False,
149
- )
150
- banner = self.page.wait_for_selector(".py-error")
151
- assert "SyntaxError: Expected DoubleQuote" in self.console.error.text
152
- expected = (
153
- "(PY1000): The config supplied: [[ is an invalid TOML and cannot be parsed: "
154
- "SyntaxError: Expected DoubleQuote, Whitespace, or [a-z], [A-Z], "
155
- '[0-9], "-", "_" but "\\n" found.'
156
- )
157
- assert banner.inner_text() == expected
158
-
159
- @pytest.mark.skip("FIXME: We need to restore the banner.")
160
- def test_multiple_py_config(self):
161
- self.pyscript_run(
162
- """
163
- <py-config>
164
- name = "foobar"
165
- </py-config>
166
-
167
- <py-config>
168
- this is ignored and won't even be parsed
169
- </py-config>
170
-
171
- <py-script>
172
- import js
173
- config = js.pyscript_get_config()
174
- js.console.log("config name:", config.name)
175
- </py-script>
176
- """
177
- )
178
- banner = self.page.wait_for_selector(".py-warning")
179
- expected = (
180
- "Multiple <py-config> tags detected. Only the first "
181
- "is going to be parsed, all the others will be ignored"
182
- )
183
- assert banner.text_content() == expected
184
-
185
- @pytest.mark.skip("FIXME: We need to restore the banner.")
186
- def test_no_interpreter(self):
187
- snippet = """
188
- <py-config type="json">
189
- {
190
- "interpreters": []
191
- }
192
- </py-config>
193
- """
194
- self.pyscript_run(snippet, wait_for_pyscript=False)
195
- div = self.page.wait_for_selector(".py-error")
196
- assert (
197
- div.text_content() == "(PY1000): Fatal error: config.interpreter is empty"
198
- )
199
-
200
- @pytest.mark.skip("FIXME: We need to restore the banner.")
201
- def test_multiple_interpreter(self):
202
- snippet = """
203
- <py-config type="json">
204
- {
205
- "interpreters": [
206
- {
207
- "src": "https://cdn.jsdelivr.net/pyodide/v0.23.2/full/pyodide.js",
208
- "name": "pyodide-0.23.2",
209
- "lang": "python"
210
- },
211
- {
212
- "src": "http://...",
213
- "name": "this will be ignored",
214
- "lang": "this as well"
215
- }
216
- ]
217
- }
218
- </py-config>
219
-
220
- <py-script>
221
- import js
222
- js.console.log("hello world");
223
- </py-script>
224
- """
225
- self.pyscript_run(snippet)
226
- banner = self.page.wait_for_selector(".py-warning")
227
- expected = (
228
- "Multiple interpreters are not supported yet.Only the first will be used"
229
- )
230
- assert banner.text_content() == expected
231
- assert self.console.log.lines[-1] == "hello world"
232
-
233
- def test_paths(self):
234
- self.writefile("a.py", "x = 'hello from A'")
235
- self.writefile("b.py", "x = 'hello from B'")
236
- self.pyscript_run(
237
- """
238
- <py-config>
239
- [[fetch]]
240
- files = ["./a.py", "./b.py"]
241
- </py-config>
242
-
243
- <py-script>
244
- import js
245
- import a, b
246
- js.console.log(a.x)
247
- js.console.log(b.x)
248
- </py-script>
249
- """
250
- )
251
- assert self.console.log.lines[-2:] == [
252
- "hello from A",
253
- "hello from B",
254
- ]
255
-
256
- @pytest.mark.skip("FIXME: We need to restore the banner.")
257
- def test_paths_that_do_not_exist(self):
258
- self.pyscript_run(
259
- """
260
- <py-config>
261
- [[fetch]]
262
- files = ["./f.py"]
263
- </py-config>
264
- """,
265
- wait_for_pyscript=False,
266
- )
267
-
268
- expected = "(PY0404): Fetching from URL ./f.py failed with " "error 404"
269
-
270
- inner_html = self.page.locator(".py-error").inner_html()
271
-
272
- assert expected in inner_html
273
- assert expected in self.console.error.lines[-1]
274
-
275
- def test_paths_from_packages(self):
276
- self.writefile("utils/__init__.py", "")
277
- self.writefile("utils/a.py", "x = 'hello from A'")
278
- self.pyscript_run(
279
- """
280
- <py-config>
281
- [[fetch]]
282
- from = "utils"
283
- to_folder = "pkg"
284
- files = ["__init__.py", "a.py"]
285
- </py-config>
286
-
287
- <py-script>
288
- import js
289
- from pkg.a import x
290
- js.console.log(x)
291
- </py-script>
292
- """
293
- )
294
- assert self.console.log.lines[-1] == "hello from A"