use emscripten virtual FS directly to load paths (#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
This commit is contained in:
Madhur Tandon
2022-10-21 18:43:03 +05:30
committed by GitHub
parent c352b502c4
commit 0cfe20ca65
3 changed files with 31 additions and 17 deletions

View File

@@ -91,20 +91,11 @@ export class PyodideRuntime extends Runtime {
async loadFromFile(path: string): Promise<void> {
const filename = getLastPath(path);
await this.run(
`
from pyodide.http import pyfetch
from js import console
try:
response = await pyfetch("${path}")
except Exception as err:
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.")
raise(err)
content = await response.bytes()
with open("${filename}", "wb") as f:
f.write(content)
`,
);
const response = await fetch(path);
const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer);
const stream = this.interpreter.FS.open(filename, 'w');
this.interpreter.FS.write(stream, data, 0, data.length, 0);
this.interpreter.FS.close(stream);
}
}

View File

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