Skip to content

run_pymodules_install can reuse stale build/venv and fail with mixed pip/resolvelib state #3339

Description

@yves-surrel

Summary

In python-for-android v2026.05.09, the pure-Python module install stage creates the temporary build virtual environment with:

shprint(host_python, '-m', 'venv', 'venv')

If build/venv already exists from a previous failed or interrupted run, it can contain a stale or mixed pip installation. p4a then runs:

source venv/bin/activate && pip install -U pip

In my case, this failed with:

ImportError: cannot import name 'RequirementInformation'
from 'pip._vendor.resolvelib.structs'

Changing the venv creation line to use --clear fixed the problem:

- shprint(host_python, '-m', 'venv', 'venv')
+ shprint(host_python, '-m', 'venv', '--clear', 'venv')

Environment

  • macOS: Tahoe 26.5
  • Host machine: Apple Silicon MacBook Air M5
  • python-for-android: v2026.05.09
  • p4a commit/tag: 58d21141, tag v2026.05.09
  • Host Python: Python 3.11 from a Conda environment
  • Android NDK: r28c
  • Android API: 33
  • Android min API / ndk-api: 24

Reduced reproduction

This was reproduced with a minimal pure-Python dependency, without my application, custom recipes, matplotlib, traits, pyzmq, or a Jupyter stack.

Command used:

cd /Users/yves/buildozer/.buildozer/android/platform/python-for-android

PYTHONPATH="$PWD" \
/Users/yves/miniforge3/envs/buildozer-p4a/bin/python -m pythonforandroid.toolchain create \
  --dist_name=mwe \
  --bootstrap=sdl2 \
  --requirements=android,python3==3.11.6,hostpython3==3.11.6,python-dateutil \
  --arch=arm64-v8a \
  --storage-dir=/Users/yves/buildozer/.buildozer/android/platform/build-armeabi-v7a_arm64-v8a \
  --ndk-api=24 \
  --ignore-setup-py \
  --debug

Note: this command reused an existing p4a storage directory to reproduce the failure quickly. The important point is that the p4a requirements were reduced to android,python3==3.11.6,hostpython3==3.11.6,python-dateutil.

Relevant failing log excerpt:

[INFO]:    # Installing pure Python modules
[INFO]:    *** PYTHON PACKAGE / PROJECT INSTALL STAGE FOR ARCH: arm64-v8a ***
[DEBUG]:   -> running pip3 install python-dateutil six --dry-run --break-system-packages --ignore-installed --disable-pip-version-check --only-binary=:all: --report ... -q --platform=android_24_arm64_v8a --platform=android_24_aarch64 --python-version 3.11.6
[INFO]:    Extra resolved pure python dependencies :
[INFO]:
[INFO]:      python-dateutil : 2.9.0.post0
[INFO]:
[INFO]:    The requirements (python-dateutil, six, https://files.pythonhosted.org/.../python_dateutil-2.9.0.post0-py2.py3-none-any.whl) don't have recipes, attempting to install them with pip
[INFO]:    If this fails, it may mean that the module has compiled components and needs a recipe.
[INFO]:    -> directory context .../build-armeabi-v7a_arm64-v8a/build
[DEBUG]:   -> running python -m venv venv
[INFO]:    Upgrade pip to latest version
[DEBUG]:   -> running bash -c source venv/bin/activate && pip install -U pip
...
ImportError: cannot import name 'RequirementInformation'
from 'pip._vendor.resolvelib.structs'

Full log attached: p4a_mwe_failing_python_dateutil.log.

Diagnosis

The generated build/venv appeared to contain a mixed pip state. In one inspection, the active pip package was 23.2.1, while the same venv also contained pip-26.1.1.dist-info.

Example diagnostic output:

pip 23.2.1 from .../build/venv/lib/python3.11/site-packages/pip
pip-23.2.1.dist-info
pip-26.1.1.dist-info

At that point, pip's vendored resolvelib files were inconsistent, causing:

ImportError: cannot import name 'RequirementInformation'
from 'pip._vendor.resolvelib.structs'

Manually removing the pip* directories from the venv, reinstalling pip with ensurepip, and then running pip install -U pip produced a coherent pip installation. After that, installing the pure-Python packages worked.

Proposed fix

Create the temporary p4a venv with --clear:

diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py
--- a/pythonforandroid/build.py
+++ b/pythonforandroid/build.py
@@ -868,7 +868,7 @@
     host_python = sh.Command(ctx.hostpython)
     with current_directory(join(ctx.build_dir)):
-        shprint(host_python, '-m', 'venv', 'venv')
+        shprint(host_python, '-m', 'venv', '--clear', 'venv')

This prevents stale or partially upgraded pip files from surviving between failed p4a runs.

An alternative fix would be to explicitly delete ctx.build_dir/venv before recreating it.

p4a_mwe_failing_python_dateutil.log

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: HighAfter critical issues are fixed, these should be dealt with before any further issues.easy

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions