pyodide / pyodide-build

Tool for building packages targeting Pyodide
Mozilla Public License 2.0
5 stars 8 forks source link

Running via `pipx`/`uvx` isn't working fully #54

Open agriyakhetarpal opened 6 days ago

agriyakhetarpal commented 6 days ago

Description

We do support a [project.entry-points."pipx.run"] entry point, but it apparently doesn't work that well right now. I guess this is coming from our layered CLI.

Steps to reproduce

The pipx run pyodide build command picks up the Pyodide sdist on PyPI:

Tap to show logs
``` PIP STDOUT ---------- Collecting pyodide Using cached pyodide-0.0.2.tar.gz (19 kB) Installing build dependencies: started Installing build dependencies: finished with status 'done' Getting requirements to build wheel: started Getting requirements to build wheel: finished with status 'error' PIP STDERR ---------- error: subprocess-exited-with-error × Getting requirements to build wheel did not run successfully. │ exit code: 1 ╰─> [21 lines of output] Traceback (most recent call last): File "/Users/agriyakhetarpal/.local/pipx/shared/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in main() File "/Users/agriyakhetarpal/.local/pipx/shared/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main json_out['return_val'] = hook(**hook_input['kwargs']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/agriyakhetarpal/.local/pipx/shared/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 118, in get_requires_for_build_wheel return hook(config_settings) ^^^^^^^^^^^^^^^^^^^^^ File "/private/var/folders/b3/2bq1m1_50bs4c7305j8vxcqr0000gn/T/pip-build-env-dvq85nnc/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 333, in get_requires_for_build_wheel return self._get_build_requires(config_settings, requirements=[]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/private/var/folders/b3/2bq1m1_50bs4c7305j8vxcqr0000gn/T/pip-build-env-dvq85nnc/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 303, in _get_build_requires self.run_setup() File "/private/var/folders/b3/2bq1m1_50bs4c7305j8vxcqr0000gn/T/pip-build-env-dvq85nnc/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 521, in run_setup super().run_setup(setup_script=setup_script) File "/private/var/folders/b3/2bq1m1_50bs4c7305j8vxcqr0000gn/T/pip-build-env-dvq85nnc/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 319, in run_setup exec(code, locals()) File "", line 7, in ValueError: Pyodide is a Python distribution that runs in the browser or Node.js. It cannot be installed from PyPi. See https://github.com/pyodide/pyodide for how to use Pyodide. [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. error: subprocess-exited-with-error × Getting requirements to build wheel did not run successfully. │ exit code: 1 ╰─> See above for output. note: This error originates from a subprocess, and is likely not a problem with pip. ```

If I run pipx run --spec pyodide-build pyodide --help (or pyodide xbuildenv --help or pyodide build --help, I get this trace:

Tap to show logs ``` ❯ pipx run --spec pyodide-build pyodide --help Traceback (most recent call last): File "", line 3, in File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_cli/app.py", line 84, in main register_plugins() File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_cli/app.py", line 54, in register_plugins plugins = {ep.name: (ep.load(), ep) for ep in eps} ^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/metadata/__init__.py", line 205, in load module = import_module(match.group('module')) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.6/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/__init__.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1387, in _gcd_import File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "", line 995, in exec_module File "", line 488, in _call_with_frames_removed File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_build/cli/build.py", line 20, in from pyodide_build.out_of_tree import build File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_build/out_of_tree/build.py", line 6, in from pyodide_build import build_env, common, pypabuild File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_build/pypabuild.py", line 18, in from pyodide_build import _f2c_fixes, common, pywasmcross File "/Users/agriyakhetarpal/.local/pipx/.cache/f0f4ae1546472e0/lib/python3.12/site-packages/pyodide_build/pywasmcross.py", line 16, in from __main__ import __file__ as INVOKED_PATH_STR ImportError: cannot import name '__file__' from '__main__' (unknown location). Did you mean: '__name__'? ```

which is coming from the fact that from __main__ import __file__ as INVOKED_PATH_STR won't work and we might need to replace this with something like sys.argv[0] to replicate (I've seen this error with pipx before).

If I run

❯ python -m pyodide build                        
/Users/agriyakhetarpal/Desktop/agriya-pyodide-build/.venv/bin/python: No module named pyodide
❯ python -m "pyodide build"
/Users/agriyakhetarpal/Desktop/agriya-pyodide-build/.venv/bin/python: No module named pyodide build
❯ python -m "pyodide-build"
/Users/agriyakhetarpal/Desktop/agriya-pyodide-build/.venv/bin/python: No module named pyodide-build

they don't work either, because we use pyodide-cli as a dependency to provide our CLI logic.

and pipx install pyodide-build doesn't work until we add --include-deps so that it installs pyodide-cli:

Tap to show logs


``` ❯ pipx install pyodide-build Note: Dependent package 'pyodide-cli' contains 1 apps - pyodide Note: Dependent package 'markdown-it-py' contains 1 apps - markdown-it Note: Dependent package 'pygments' contains 1 apps - pygmentize Note: Dependent package 'typer' contains 1 apps - typer Note: Dependent package 'wheel' contains 1 apps - wheel Note: Dependent package 'build' contains 1 apps - pyproject-build Note: Dependent package 'cmake' contains 3 apps - cmake - cpack - ctest Note: Dependent package 'charset-normalizer' contains 1 apps - normalizer Note: Dependent package 'unearth' contains 1 apps - unearth Note: Dependent package 'httpx' contains 1 apps - httpx Note: Dependent package 'virtualenv' contains 1 apps - virtualenv No apps associated with package pyodide-build. Try again with '--include-deps' to include apps of dependent packages, which are listed above. If you are attempting to install a library, pipx should not be used. Consider using pip or a similar tool instead. ```

and newer tools like uvx don't seem to work either, such as uvx --from pyodide-build --with pyodide-cli pyodide (which reports an unsatisfiable requirement at the installation step). I haven't checked if there is a feature that lets us add [tool.uvx.run] in pyproject.toml so far.

Expected behaviour

We should be able to, at least, run pipx run pyodide build, similar to pipx run build. I think it might be possible to make this all work by letting go of https://github.com/pyodide/pyodide-cli/ completely without any breaking changes (since no one else besides us is probably using the [project.entry-points."pyodide.cli"] entry point, but I'll let others decide on what should be done and whether this effort in specific is justifiable or if we should look for other ways to make pipx/uvx work.

ryanking13 commented 6 days ago

Thanks for opening the issue. I think pipx run --spec pyodide-build pyodide isn't that bad as it is pretty common to have a package name and CLI name different IMO. But we'll need to fix

ImportError: cannot import name '__file__' from '__main__' (unknown location). Did you mean: '__name__'?

anyways.