Repository: pyscript/pyscript
File: pyscript.core/esm/interpreter/_utils.js (JavaScript)

Code before:
 */
export const clean = (code) =>
    code.replace(/^[^\r\n]+$/, (line) => line.trim());

// REQUIRES INTEGRATION TEST
/* c8 ignore start */
export const io = new WeakMap();
export const stdio = (init) => {
    const context = init || console;
    const localIO = {
        stderr: (context.stderr || console.error).bind(context),
        stdout: (context.stdout || console.log).bind(context),
    };
    return {
        stderr: (...args) => localIO.stderr(...args),
        stdout: (...args) => localIO.stdout(...args),
        async get(engine) {
            const interpreter = await engine;
            io.set(interpreter, localIO);
            return interpreter;
        },
    };
};

// This should be the only helper needed for all Emscripten based FS exports
export const writeFile = (FS, path, buffer) => {
    const { parentPath, name } = FS.analyzePath(path, true);
    FS.mkdirTree(parentPath);
    return FS.writeFile([parentPath, name].join("/"), new Uint8Array(buffer), {
        canOwn: true,
    });
};
/* c8 ignore stop */

// This is instead a fallback for Lua or others
export const writeFileShim = (FS, path, buffer) => {
    mkdirTree(FS, dirname(path));
    path = resolve(FS, path);
    return FS.writeFile(path, new Uint8Array(buffer), { canOwn: true });
};

const dirname = (path) => {
    const tree = path.split("/");
    tree.pop();
    return tree.join("/");
};

const mkdirTree = (FS, path) => {
    const current = [];
    for (const branch of path.split("/")) {
        current.push(branch);

Review comment (suggestion):
The error I get comes from `writeFile()` rather than `writeFileShim()`. I think something like this works reliably:

```js
export const writeFile = ({ FS, PATH, PATH_FS }, path, buffer) => {
    const abspath = PATH_FS.resolve(path);
    FS.mkdirTree(PATH.dirname(abspath));
    return FS.writeFile(abspath, new Uint8Array(buffer), {
        canOwn: true,
    });
};
```

`PATH_FS` is not exported by pyodide, but it can be used via something like

```js
export const writeFile = (pyodide, path, buffer) => {
    const { FS, PATH } = pyodide;
    const PATH_FS = pyodide._module["PATH_FS"];
    writeFileUtil({ FS, PATH, PATH_FS }, path, buffer);
}
```

Code after:
 */
export const clean = (code) =>
    code.replace(/^[^\r\n]+$/, (line) => line.trim());

// REQUIRES INTEGRATION TEST
/* c8 ignore start */
export const io = new WeakMap();
export const stdio = (init) => {
    const context = init || console;
    const localIO = {
        stderr: (context.stderr || console.error).bind(context),
        stdout: (context.stdout || console.log).bind(context),
    };
    return {
        stderr: (...args) => localIO.stderr(...args),
        stdout: (...args) => localIO.stdout(...args),
        async get(engine) {
            const interpreter = await engine;
            io.set(interpreter, localIO);
            return interpreter;
        },
    };
};

// This should be the only helper needed for all Emscripten based FS exports
export const writeFile = ({ FS, PATH, PATH_FS }, path, buffer) => {
    const absPath = PATH_FS.resolve(path);
    FS.mkdirTree(PATH.dirname(absPath));
    return FS.writeFile(absPath, new Uint8Array(buffer), {
        canOwn: true,
    });
};
/* c8 ignore stop */

// This is instead a fallback for Lua or others
export const writeFileShim = (FS, path, buffer) => {
    mkdirTree(FS, dirname(path));
    path = resolve(FS, path);
    return FS.writeFile(path, new Uint8Array(buffer), { canOwn: true });
};

const dirname = (path) => {
    const tree = path.split("/");
    tree.pop();
    return tree.join("/");
};

const mkdirTree = (FS, path) => {
    const current = [];
    for (const branch of path.split("/")) {
        if (branch === ".") continue;