From 4f594b15bf75c75fa87f36cb1e685ee714cbbd3a Mon Sep 17 00:00:00 2001 From: Maxime Barbier Date: Mon, 28 Sep 2026 14:36:23 +0200 Subject: [PATCH] recipe.py: fix sync-upstream merge regression in PythonRecipe install The sync-upstream merge (55feaec4) had a 257-line conflict on this file that got resolved by keeping this fork's old pre-sync code instead of adopting upstream's: PythonRecipe.install_python_package(), install_hostpython_package() and install_hostpython_prerequisites() were installing via `setup.py install` instead of upstream's `pip install .`, hostpython_prerequisites defaulted to [] instead of ['setuptools'], and the HTTP_PROXY/HTTPS_PROXY passthrough in get_recipe_env() was dropped entirely. Restored upstream's code for all of the above verbatim, keeping this fork's two genuine additions on top: RustCompiledComponentsRecipe's per-target CC_/AR_ env vars, and MesonRecipe.ensure_args()'s guard against mutating the inherited class-level extra_build_args list. Also add --no-deps to both `pip install .` calls: without it, pip resolves *this package's own* declared PyPI dependencies too, even when one of them already has its own Android recipe (e.g. kivymd declaring pycairo, which p4a builds itself) -- redundant with p4a's own dependency graph (depends/python_depends) at best, and a real build failure at worst when PyPI has no prebuilt wheel for it (as found rebuilding AVA with this fix: pycairo's sdist needs a working meson host toolchain that isn't set up for this kind of incidental, non-recipe host build). Verified with a full clean rebuild of AVA (many recipes exercise PythonRecipe/CythonRecipe/CompiledComponentsPythonRecipe: wikipedia, srt, kivymd, cymem, blis, murmurhash, preshed, srsly, thinc, spacy, MarkupSafe...) -- BUILD SUCCESSFUL, APK produced. Co-Authored-By: Claude Sonnet 5 --- pythonforandroid/recipe.py | 45 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 67d3a66c3..785b9e455 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -534,6 +534,11 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True): if arch is None: arch = self.filtered_archs[0] env = arch.get_env(with_flags_in_cc=with_flags_in_cc) + + for proxy_key in ['HTTP_PROXY', 'http_proxy', 'HTTPS_PROXY', 'https_proxy']: + if proxy_key in environ: + env[proxy_key] = environ[proxy_key] + return env def prebuild_arch(self, arch): @@ -877,7 +882,7 @@ class PythonRecipe(Recipe): on python2 or python3 which can break the dependency graph ''' - hostpython_prerequisites = [] + hostpython_prerequisites = ['setuptools'] '''List of hostpython packages required to build a recipe''' _host_recipe = None @@ -1012,21 +1017,20 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True): info('Installing {} into site-packages'.format(self.name)) - hostpython = sh.Command(self.hostpython_location) hpenv = env.copy() with current_directory(self.get_build_dir(arch.arch)): - - if isfile("setup.py"): - shprint(hostpython, 'setup.py', 'install', '-O2', - '--root={}'.format(self.ctx.get_python_install_dir(arch.arch)), - '--install-lib=.', - _env=hpenv, *self.setup_extra_args) - - # If asked, also install in the hostpython build dir - if self.install_in_hostpython: - self.install_hostpython_package(arch) - else: - warning("`PythonRecipe.install_python_package` called without `setup.py` file!") + # --no-deps: p4a's own recipe graph (depends/python_depends) is what + # resolves this recipe's dependencies. Without it, pip additionally + # resolves *this package's own* declared dependencies against PyPI, + # even when one of them already has its own Android recipe (e.g. + # kivymd declaring pycairo, which p4a builds itself) -- redundant at + # best, and a real failure when PyPI has no prebuilt wheel for it and + # building it here, for the host, isn't set up to succeed. + shprint(self._host_recipe.pip, 'install', '.', + '--compile', '--no-deps', '--target', + self.ctx.get_python_install_dir(arch.arch), + _env=hpenv, *self.setup_extra_args + ) def get_hostrecipe_env(self, arch=None): env = environ.copy() @@ -1040,9 +1044,9 @@ def hostpython_site_dir(self): def install_hostpython_package(self, arch): env = self.get_hostrecipe_env(arch) - real_hostpython = sh.Command(self.real_hostpython_location) - shprint(real_hostpython, 'setup.py', 'install', '-O2', - '--install-lib=Lib/site-packages', + # See install_python_package() for why --no-deps. + shprint(self._host_recipe.pip, 'install', '.', + '--compile', '--no-deps', '--root={}'.format(self._host_recipe.site_root), _env=env, *self.setup_extra_args) @@ -1066,8 +1070,7 @@ def install_hostpython_prerequisites(self, packages=None, force_upgrade=True): if force_upgrade: pip_options.append("--upgrade") pip_env = self.get_hostrecipe_env() - pip_env["HOME"] = "/tmp" - shprint(sh.Command(self.real_hostpython_location), "-m", "pip", *pip_options, _env=pip_env) + shprint(self._host_recipe.pip, *pip_options, _env=pip_env) def restore_hostpython_prerequisites(self, packages): _packages = [] @@ -1084,7 +1087,7 @@ class CompiledComponentsPythonRecipe(PythonRecipe): def build_arch(self, arch): '''Build any cython components, then install the Python module by - calling setup.py install with the target Python dir. + calling pip install with the target Python dir. ''' Recipe.build_arch(self, arch) self.install_hostpython_prerequisites() @@ -1133,7 +1136,7 @@ class CythonRecipe(PythonRecipe): def build_arch(self, arch): '''Build any cython components, then install the Python module by - calling setup.py install with the target Python dir. + calling pip install with the target Python dir. ''' self.install_hostpython_prerequisites() Recipe.build_arch(self, arch)