From 38ba1ad763f52bb3d012c5720f333071f1f035c4 Mon Sep 17 00:00:00 2001 From: Andre Miras Date: Tue, 28 Apr 2020 22:52:24 +0200 Subject: [PATCH] Fixes python build with macOS venv Running the freshly compiled python binary from another Python process (e.g. sh module or os.system()) may get wrongly detected as if it was ran directly from the venv. This happens when `pyvenv.cfg` is present (e.g. venv/pyvenv.cfg). It makes `sysconfig.is_python_build()` returns `False` instead of `True` since it's using the compiled interpreter (e.g. ./build-dir/python). https://docs.python.org/3/library/sysconfig.html#sysconfig.is_python_build https://github.com/python/cpython/blob/v3.8.2/Lib/sysconfig.py#L127 This is because the `sys._home` attribute is used during the detection. The issue was first seen in macOS venv which generates the `pyvenv.cfg`. To compare both behaviours, try the following within and without a venv: ```python import os os.system("./build-dir/python -E -c 'import sysconfig; print(sysconfig._sys_home)'") ``` One would return `/usr/local/bin` and the other `None` Refs: - https://github.com/kivy/kivy-ios/issues/401 - https://github.com/kivy/python-for-android/pull/2063 --- .travis.yml | 2 +- Makefile | 8 -------- pythonforandroid/recipes/hostpython3/__init__.py | 5 +++++ .../hostpython3/patches/pyconfig_detection.patch | 13 +++++++++++++ pythonforandroid/recipes/python3/__init__.py | 4 +++- .../python3/patches/pyconfig_detection.patch | 13 +++++++++++++ 6 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 pythonforandroid/recipes/hostpython3/patches/pyconfig_detection.patch create mode 100644 pythonforandroid/recipes/python3/patches/pyconfig_detection.patch diff --git a/.travis.yml b/.travis.yml index 04e49e59c0..bb411bf5dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ jobs: # installs java 1.8, android's SDK/NDK and p4a - make -f ci/makefiles/osx.mk - export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home - script: make testapps-no-venv/armeabi-v7a + script: make testapps/armeabi-v7a - <<: *testapps name: Rebuild updated recipes script: travis_wait 30 make docker/run/make/rebuild_updated_recipes diff --git a/Makefile b/Makefile index ef0c503eb9..df7cdac17b 100644 --- a/Makefile +++ b/Makefile @@ -47,14 +47,6 @@ testapps/%: virtualenv python setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \ --arch=$($@_APP_ARCH) -testapps-no-venv/%: - pip3 install Cython==0.28.6 - pip3 install -e . - $(eval $@_APP_ARCH := $(shell basename $*)) - cd testapps/on_device_unit_tests/ && \ - python3 setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \ - --arch=$($@_APP_ARCH) - clean: find . -type d -name "__pycache__" -exec rm -r {} + find . -type d -name "*.egg-info" -exec rm -r {} + diff --git a/pythonforandroid/recipes/hostpython3/__init__.py b/pythonforandroid/recipes/hostpython3/__init__.py index 651fb019aa..f1838283da 100644 --- a/pythonforandroid/recipes/hostpython3/__init__.py +++ b/pythonforandroid/recipes/hostpython3/__init__.py @@ -4,6 +4,7 @@ from os.path import exists, join, isfile from pythonforandroid.logger import shprint +from pythonforandroid.patching import is_version_lt from pythonforandroid.recipe import Recipe from pythonforandroid.util import ( BuildInterruptingException, @@ -35,6 +36,10 @@ class Hostpython3Recipe(Recipe): '''The default url to download our host python recipe. This url will change depending on the python version set in attribute :attr:`version`.''' + patches = ( + ('patches/pyconfig_detection.patch', is_version_lt("3.8.3")), + ) + @property def _exe_name(self): ''' diff --git a/pythonforandroid/recipes/hostpython3/patches/pyconfig_detection.patch b/pythonforandroid/recipes/hostpython3/patches/pyconfig_detection.patch new file mode 100644 index 0000000000..087ab586ad --- /dev/null +++ b/pythonforandroid/recipes/hostpython3/patches/pyconfig_detection.patch @@ -0,0 +1,13 @@ +diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py +--- Python-3.8.2/Lib/site.py 2020-04-28 12:48:38.000000000 -0700 ++++ Python-3.8.2-new/Lib/site.py 2020-04-28 12:52:46.000000000 -0700 +@@ -487,7 +487,8 @@ + if key == 'include-system-site-packages': + system_site = value.lower() + elif key == 'home': +- sys._home = value ++ # this is breaking pyconfig.h path detection with venv ++ print('Ignoring "sys._home = value" override') + + sys.prefix = sys.exec_prefix = site_prefix + diff --git a/pythonforandroid/recipes/python3/__init__.py b/pythonforandroid/recipes/python3/__init__.py index 2da78f59ac..569afc2d26 100644 --- a/pythonforandroid/recipes/python3/__init__.py +++ b/pythonforandroid/recipes/python3/__init__.py @@ -8,7 +8,7 @@ from shutil import copy2 from pythonforandroid.logger import info, warning, shprint -from pythonforandroid.patching import version_starts_with +from pythonforandroid.patching import version_starts_with, is_version_lt from pythonforandroid.recipe import Recipe, TargetPythonRecipe from pythonforandroid.util import ( current_directory, @@ -55,6 +55,8 @@ class Python3Recipe(TargetPythonRecipe): name = 'python3' patches = [ + ('patches/pyconfig_detection.patch', is_version_lt("3.8.3")), + # Python 3.7.1 ('patches/py3.7.1_fix-ctypes-util-find-library.patch', version_starts_with("3.7")), ('patches/py3.7.1_fix-zlib-version.patch', version_starts_with("3.7")), diff --git a/pythonforandroid/recipes/python3/patches/pyconfig_detection.patch b/pythonforandroid/recipes/python3/patches/pyconfig_detection.patch new file mode 100644 index 0000000000..087ab586ad --- /dev/null +++ b/pythonforandroid/recipes/python3/patches/pyconfig_detection.patch @@ -0,0 +1,13 @@ +diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py +--- Python-3.8.2/Lib/site.py 2020-04-28 12:48:38.000000000 -0700 ++++ Python-3.8.2-new/Lib/site.py 2020-04-28 12:52:46.000000000 -0700 +@@ -487,7 +487,8 @@ + if key == 'include-system-site-packages': + system_site = value.lower() + elif key == 'home': +- sys._home = value ++ # this is breaking pyconfig.h path detection with venv ++ print('Ignoring "sys._home = value" override') + + sys.prefix = sys.exec_prefix = site_prefix +