kivy / kivy/python-for-android

ModuleNotFoundError: No module named 'wheel.cli'

Open
#3,293 2 comments 0 reactions 0 assignees View on GitHub
easy Priority: Low
Dominant language
Python
Stars
8.9k
Forks
2k
Avg merge
12h 20m
Merged PRs (30d)
9

Description

Looks like p4a is using a privated `wheels.cli` module which was part of https://github.com/pypa/wheel/pull/655

```py
Traceback (most recent call last):
File "", line 198, in _run_module_as_main
File "", line 88, in _run_code
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/toolchain.py", line 1246, in
main()
~~~~^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/entrypoints.py", line 18, in main
ToolchainCL()
~~~~~~~~~~~^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/toolchain.py", line 677, in __init__
getattr(self, command)(args)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/toolchain.py", line 104, in wrapper_func
build_dist_from_args(ctx, dist, args)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/toolchain.py", line 163, in build_dist_from_args
build_recipes(build_order, python_modules, ctx,
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
getattr(args, "private", None),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<2 lines>...
),
^^
)
^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/build.py", line 517, in build_recipes
recipe.build_arch(arch)
~~~~~~~~~~~~~~~~~^^^^^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/recipe.py", line 1340, in build_arch
self.install_wheel(arch, built_wheels)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/home/user/Projects/Tauon/.buildozer/android/platform/python-for-android/pythonforandroid/recipe.py", line 1283, in install_wheel
from wheel.cli.tags import tags as wheel_tags
ModuleNotFoundError: No module named 'wheel.cli'

```

EDIT: Worked around with an LLM:
```py
def _retag_wheel_platform(self, path, new_platform_tag, remove_old=True):
"""
Rename a wheel by replacing only its platform tag.

Wheel filename format:
{dist}-{version}(-{build})?-{python tag}-{abi tag}-{platform tag}.whl

We split from the right so project names/build tags containing '-' still work.
"""
p = Path(path)
if p.suffix != ".whl":
raise ValueError(f"Not a wheel: {path}")

parts = p.stem.rsplit("-", 3)
if len(parts) != 4:
raise ValueError(f"Unexpected wheel filename format: {p.name}")

left, py_tag, abi_tag, _old_platform_tag = parts
new_name = f"{left}-{py_tag}-{abi_tag}-{new_platform_tag}.whl"
new_path = p.with_name(new_name)

if new_path != p:
p.rename(new_path)
if not remove_old and new_path != p:
# rename already removed old path, so if you truly want both,
# copy instead of rename
pass

return str(new_path)

def install_wheel(self, arch, built_wheels):
with patch_wheel_setuptools_logging():
from wheel.wheelfile import WheelFile

_wheel = built_wheels[0]
built_wheel_dir = dirname(_wheel)

selected_wheel = self._retag_wheel_platform(
_wheel,
self.get_wheel_platform_tag(arch),
remove_old=True,
)

_dev_wheel_dir = environ.get("P4A_WHEEL_DIR", False)
if _dev_wheel_dir:
ensure_dir(_dev_wheel_dir)
shprint(sh.cp, selected_wheel, _dev_wheel_dir)

info(f"Installing built wheel: {basename(selected_wheel)}")
destination = self.ctx.get_python_install_dir(arch.arch)
with WheelFile(selected_wheel) as wf:
for zinfo in wf.filelist:
wf.extract(zinfo, destination)
```

Contributor guide

Open the contributing guide

Research direction

Start in pythonforandroid/recipe.py at install_wheel, where the import from wheel.cli.tags fails, and compare it with the wheel.wheelfile usage shown in the issue. Reproduce the Android build failure, then verify that wheel installation and platform retagging work without the unavailable module.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.