Skip to content

0.28.0: micropip lockFileURL failing when provided #5736

@WebReflection

Description

@WebReflection

🐛 Bug

We've discussed this in Discord but I haven't seen any bug around it so here it is.

To Reproduce

This page tries to store the micropip.freeze() result somewhere and reuse it for any other reload of the page.

As soon as that frozen cache is used as valid URL, an error about TypeError: _emscripten_stack_get_current is not a function is shown:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="module">
        // add ?clear to your test page to drop the entry
        if (location.search === '?clear') {
            localStorage.removeItem("test");
            location.href = location.href.slice(0, -6);
            throw new Error('reloading anyway');
        }

        import { loadPyodide } from "https://cdn.jsdelivr.net/pyodide/v0.28.0/full/pyodide.mjs";

        let timeout = 0;
        addEventListener('error', () => {
            clearTimeout(timeout);
            document.body.append('ERROR');
        });

        const json = localStorage.getItem("test");
        const options = {
            // not specific to the package, anyone fails
            packages: ["numpy"],
        };

        if (json) {
            options.lockFileURL = URL.createObjectURL(new Blob(
                [json],
                { type: 'application/json' },
            ));
        }

        const pyodide = await loadPyodide(options);

        if (json) {
            // irrelevant for the bug, just for correctness/example
            URL.revokeObjectURL(options.lockFileURL);
        }
        else {
            await pyodide.loadPackage('micropip');
            const micropip = pyodide.pyimport('micropip');
            await micropip.install(options.packages, { keep_going: true });
            const frozen = micropip.freeze();
            localStorage.setItem("test", frozen);
            micropip.destroy();
            // first time it's fine, next time refresh
            // and you'll see a weird error
        }

        timeout = setTimeout(() => {
            document.body.append('ALL GOOD - REFRESH');
        }, 1000);
    </script>
</head>
</html>

Expected behavior

We use IndexedDB instead but the outcome is the same, what supposed to be a way to ensure faster bootstrap became "harakiri" because without any caching attempt things just work and things worked up to 0.28.0 release, but nothing in the BREAKING CHANGES suggests we're doing something really wrong and the error is a bit cryptic because it doesn't provide any follow-up action or detail about what's actually wrong in the process.

Environment

  • Pyodide Version: 0.28.0
  • Browser version: latest
  • Any other relevant information: @hoodmane knows about it and I think he started already some sort of investigation around it.

Additional context

Pinging @ntoll if interested as this is making our project (PyScript) unable to adopt latest/greatest features of this lovely runtime.

Thanks for having a look 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions