-
Notifications
You must be signed in to change notification settings - Fork 2k
toolchain: auto resolve deps
#3271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
T-Dynamos
wants to merge
1
commit into
kivy:develop
Choose a base branch
from
T-Dynamos:minor-fixes
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+214
−14
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,19 +2,24 @@ | |
| import copy | ||
| import glob | ||
| import os | ||
| import json | ||
| import tempfile | ||
| from os import environ | ||
| from os.path import ( | ||
| abspath, join, realpath, dirname, expanduser, exists | ||
| abspath, join, realpath, dirname, expanduser, exists, basename | ||
| ) | ||
| import re | ||
| import shutil | ||
| import subprocess | ||
|
|
||
| import sh | ||
|
|
||
| from packaging.utils import parse_wheel_filename | ||
| from packaging.requirements import Requirement | ||
|
|
||
| from pythonforandroid.androidndk import AndroidNDK | ||
| from pythonforandroid.archs import ArchARM, ArchARMv7_a, ArchAarch_64, Archx86, Archx86_64 | ||
| from pythonforandroid.logger import (info, warning, info_notify, info_main, shprint) | ||
| from pythonforandroid.logger import (info, warning, info_notify, info_main, shprint, Out_Style, Out_Fore) | ||
| from pythonforandroid.pythonpackage import get_package_name | ||
| from pythonforandroid.recipe import CythonRecipe, Recipe | ||
| from pythonforandroid.recommendations import ( | ||
|
|
@@ -90,6 +95,8 @@ class Context: | |
|
|
||
| recipe_build_order = None # Will hold the list of all built recipes | ||
|
|
||
| python_modules = None # Will hold resolved pure python packages | ||
|
|
||
| symlink_bootstrap_files = False # If True, will symlink instead of copying during build | ||
|
|
||
| java_build_tool = 'auto' | ||
|
|
@@ -444,6 +451,12 @@ def has_package(self, name, arch=None): | |
| # Failed to look up any meaningful name. | ||
| return False | ||
|
|
||
| # normalize name to remove version tags | ||
| try: | ||
| name = Requirement(name).name | ||
| except Exception: | ||
| pass | ||
|
|
||
| # Try to look up recipe by name: | ||
| try: | ||
| recipe = Recipe.get_recipe(name, self) | ||
|
|
@@ -649,6 +662,107 @@ def run_setuppy_install(ctx, project_dir, env=None, arch=None): | |
| os.remove("._tmp_p4a_recipe_constraints.txt") | ||
|
|
||
|
|
||
| def is_wheel_platform_independent(whl_name): | ||
| name, version, build, tags = parse_wheel_filename(whl_name) | ||
| return all(tag.platform == "any" for tag in tags) | ||
|
|
||
|
|
||
| def process_python_modules(ctx, modules): | ||
| """Use pip --dry-run to resolve dependencies and filter for pure-Python packages | ||
| """ | ||
| modules = list(modules) | ||
| build_order = list(ctx.recipe_build_order) | ||
|
|
||
| _requirement_names = [] | ||
| processed_modules = [] | ||
|
|
||
| for module in modules+build_order: | ||
| try: | ||
| # we need to normalize names | ||
| # eg Requests>=2.0 becomes requests | ||
| _requirement_names.append(Requirement(module).name) | ||
| except Exception: | ||
| # name parsing failed; skip processing this module via pip | ||
| processed_modules.append(module) | ||
| if module in modules: | ||
| modules.remove(module) | ||
|
|
||
| if len(processed_modules) > 0: | ||
| warning(f'Ignored by module resolver : {processed_modules}') | ||
|
|
||
| # preserve the original module list | ||
| processed_modules.extend(modules) | ||
|
|
||
| if len(modules) == 0: | ||
| return modules | ||
|
|
||
| # temp file for pip report | ||
| fd, path = tempfile.mkstemp() | ||
| os.close(fd) | ||
|
|
||
| # setup hostpython recipe | ||
| host_recipe = Recipe.get_recipe("hostpython3", ctx) | ||
|
|
||
| env = environ.copy() | ||
| _python_path = host_recipe.get_path_to_python() | ||
| libdir = glob.glob(join(_python_path, "build", "lib*")) | ||
| env['PYTHONPATH'] = host_recipe.site_dir + ":" + join( | ||
| _python_path, "Modules") + ":" + (libdir[0] if libdir else "") | ||
|
|
||
| shprint( | ||
| host_recipe.pip, 'install', *modules, | ||
| '--dry-run', '--break-system-packages', '--ignore-installed', | ||
| '--report', path, '-q', _env=env | ||
| ) | ||
|
|
||
| with open(path, "r") as f: | ||
| report = json.load(f) | ||
|
|
||
| os.remove(path) | ||
|
|
||
| info('Extra resolved pure python dependencies :') | ||
|
|
||
| ignored_str = " (ignored)" | ||
| # did we find any non pure python package? | ||
| any_not_pure_python = False | ||
|
|
||
| # just for style | ||
| info(" ") | ||
| for module in report["install"]: | ||
|
|
||
| mname = module["metadata"]["name"] | ||
| mver = module["metadata"]["version"] | ||
| filename = basename(module["download_info"]["url"]) | ||
| pure_python = True | ||
|
|
||
| if (filename.endswith(".whl") and not is_wheel_platform_independent(filename)): | ||
| any_not_pure_python = True | ||
| pure_python = False | ||
|
|
||
| # does this module matches any recipe name? | ||
| if mname.lower() in _requirement_names: | ||
| continue | ||
|
|
||
| color = Out_Fore.GREEN if pure_python else Out_Fore.RED | ||
| ignored = "" if pure_python else ignored_str | ||
|
|
||
| info( | ||
| f" {color}{mname}{Out_Fore.WHITE} : " | ||
| f"{Out_Style.BRIGHT}{mver}{Out_Style.RESET_ALL}" | ||
| f"{ignored}" | ||
| ) | ||
|
|
||
| if pure_python: | ||
| processed_modules.append(f"{mname}=={mver}") | ||
| info(" ") | ||
|
|
||
| if any_not_pure_python: | ||
| warning("Some packages were ignored because they are not pure Python.") | ||
| warning("To install the ignored packages, explicitly list them in your requirements file.") | ||
|
|
||
| return processed_modules | ||
|
|
||
|
|
||
| def run_pymodules_install(ctx, arch, modules, project_dir=None, | ||
| ignore_setup_py=False): | ||
| """ This function will take care of all non-recipe things, by: | ||
|
|
@@ -663,6 +777,10 @@ def run_pymodules_install(ctx, arch, modules, project_dir=None, | |
|
|
||
| info('*** PYTHON PACKAGE / PROJECT INSTALL STAGE FOR ARCH: {} ***'.format(arch)) | ||
|
|
||
| # don't run process_python_modules in tests | ||
| if ctx.recipe_build_order.__class__.__name__ != "Mock": | ||
| modules = process_python_modules(ctx, modules) | ||
|
Comment on lines
+781
to
+782
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we're better off updating the tests to maybe mock process_python_modules so it just returns modules as is or something like that than having a test bypass in the code itself |
||
|
|
||
| modules = [m for m in modules if ctx.not_has_package(m, arch)] | ||
|
|
||
| # We change current working directory later, so this has to be an absolute | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| diff '--color=auto' -uNr cpython-3.14.0/Lib/ensurepip/__init__.py cpython-3.14.0.mod/Lib/ensurepip/__init__.py | ||
| --- cpython-3.14.0/Lib/ensurepip/__init__.py 2025-10-07 15:04:52.000000000 +0530 | ||
| +++ cpython-3.14.0.mod/Lib/ensurepip/__init__.py 2025-12-20 18:18:13.884914683 +0530 | ||
| @@ -69,7 +69,15 @@ | ||
| code = f""" | ||
| import runpy | ||
| import sys | ||
| -sys.path = {additional_paths or []} + sys.path | ||
| + | ||
| +# tell ensurepip to ignore site-packages | ||
| + | ||
| +paths = [] | ||
| +for path in sys.path: | ||
| + if "site-packages" not in path: | ||
| + paths.append(path) | ||
| + | ||
| +sys.path = {additional_paths or []} + paths | ||
| sys.argv[1:] = {args} | ||
| runpy.run_module("pip", run_name="__main__", alter_sys=True) | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
pythonforandroid/recipes/python3/patches/3.14_fix_remote_debug.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| diff '--color=auto' -uNr cpython-3.14.2/Modules/_remote_debugging_module.c cpython-3.14.2.mod/Modules/_remote_debugging_module.c | ||
| --- cpython-3.14.2/Modules/_remote_debugging_module.c 2025-12-05 22:19:16.000000000 +0530 | ||
| +++ cpython-3.14.2.mod/Modules/_remote_debugging_module.c 2025-12-13 20:22:44.011497868 +0530 | ||
| @@ -812,7 +812,9 @@ | ||
| PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process."); | ||
| _PyErr_ChainExceptions1(exc); | ||
| } | ||
| -#elif defined(__linux__) | ||
| + | ||
| +// https://github.com/python/cpython/commit/1963e701001839389cfb1b11d803b0743f4705d7 | ||
| +#elif defined(__linux__) && HAVE_PROCESS_VM_READV | ||
| // On Linux, search for asyncio debug in executable or DLL | ||
| address = search_linux_map_for_section(handle, "AsyncioDebug", "_asyncio.cpython"); | ||
| if (address == 0) { | ||
| diff '--color=auto' -uNr cpython-3.14.2/Python/remote_debug.h cpython-3.14.2.mod/Python/remote_debug.h | ||
| --- cpython-3.14.2/Python/remote_debug.h 2025-12-05 22:19:16.000000000 +0530 | ||
| +++ cpython-3.14.2.mod/Python/remote_debug.h 2025-12-13 20:23:27.917518543 +0530 | ||
| @@ -881,7 +881,9 @@ | ||
| handle->pid); | ||
| _PyErr_ChainExceptions1(exc); | ||
| } | ||
| -#elif defined(__linux__) | ||
| + | ||
| +// https://github.com/python/cpython/commit/1963e701001839389cfb1b11d803b0743f4705d7 | ||
| +#elif defined(__linux__) && HAVE_PROCESS_VM_READV | ||
| // On Linux, search for 'python' in executable or DLL | ||
| address = search_linux_map_for_section(handle, "PyRuntime", "python"); | ||
| if (address == 0) { |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we handle any error gracefully here?
Like returning modules untouched.
We should probably still log the error for debugging, but not breaking the process if automatic module resolution doesn't work