Skip to content

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

@yves-surrel

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
    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