8000 use emscripten virtual FS directly to load paths (#870) · lowgrind/pyscript@0cfe20c · GitHub
[go: up one dir, main page]

Skip to content

Commit 0cfe20c

Browse files
use emscripten virtual FS directly to load paths (pyscript#870)
* use emscripten virtual FS directly to load paths * use more low level APIs * use await instead of then * remove try...catch from loadFromFile since it's being handled externally * add test for an invalid path * test checks for error shown to the user too * add comment about a missing case
1 parent c352b50 commit 0cfe20c

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

pyscriptjs/src/pyodide.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,11 @@ export class PyodideRuntime extends Runtime {
9191

9292
async loadFromFile(path: string): Promise<void> {
9393
const filename = getLastPath(path);
94-
await this.run(
95-
`
96-
from pyodide.http import pyfetch
97-
from js import console
98-
99-
try:
100-
response = await pyfetch("${path}")
101-
except Exception as err:
102-
console.warn("PyScript: Access to local files (using 'paths:' in py-config) is not available when directly opening a HTML file; you must use a webserver to serve the additional files. See https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062 on starting a simple webserver with Python.")
103-
raise(err)
104-
content = await response.bytes()
105-
with open("${filename}", "wb") as f:
106-
f.write(content)
107-
`,
108-
);
94+
const response = await fetch(path);
95+
const buffer = await response.arrayBuffer();
96+
const data = new Uint8Array(buffer);
97+
const stream = this.interpreter.FS.open(filename, 'w');
98+
this.interpreter.FS.write(stream, data, 0, data.length, 0);
99+
this.interpreter.FS.close(stream);
109100
}
110101
}

pyscriptjs/src/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ export function showError(msg: string): void {
6464

6565
export function handleFetchError(e: Error, singleFile: string) {
6666
//Should we still export full error contents to console?
67-
console.warn(`Caught an error in loadPaths:\r\n ${e.toString()}`);
67+
// XXX: What happens if I make a typo? i.e. a web server is being used but a file
68+
// that doesn't exist is being accessed. We should cover this case as well.
69+
console.warn(`Caught an error in fetchPaths:\r\n ${e.toString()}`);
6870
let errorContent: string;
69-
if (e.message.includes('TypeError: Failed to fetch')) {
71+
if (e.message.includes('Failed to fetch')) {
7072
errorContent = `<p>PyScript: Access to local files
7173
(using "Paths:" in &lt;py-config&gt;)
7274
is not available when directly opening a HTML file;

pyscriptjs/tests/integration/test_01_basic.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ def test_paths(self):
7575
"hello from B",
7676
]
7777

78+
def test_paths_that_do_not_exist(self):
79+
self.pyscript_run(
80+
"""
81+
<py-config>
82+
paths = ["./f.py"]
83+
</py-config>
84+
"""
85+
)
86+
assert self.console.error.lines == ["Failed to load resource: net::ERR_FAILED"]
87+
assert self.console.warning.lines == [
88+
"Caught an error in fetchPaths:\r\n TypeError: Failed to fetch"
89+
]
90+
91+
errorContent = """PyScript: Access to local files
92+
(using "Paths:" in &lt;py-config&gt;)
93+
is not available when directly opening a HTML file;
94+
you must use a webserver to serve the additional files."""
95+
96+
inner_html = self.page.locator(".py-error").inner_html()
97+
assert errorContent in inner_html
98+
7899
def test_packages(self):
79100
self.pyscript_run(
80101
"""

0 commit comments

Comments
 (0)
0