Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 13 additions & 19 deletions .github/actions/setup-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,31 @@ description:
runs:
using: composite
steps:
# For the default Python version, the micro version should be different to the
# one used by the runtime, because that's required by the integration tests
# `requires_python` and `marker_python_version`. For all other versions, we let
# the GitHub runner pick a micro version, which will be faster because it's
# locally cached.
- uses: actions/[email protected]
with:
# This should include all major.minor versions supported by the runtime, plus
# OLD_PYTHON_VERSION from test_gradle_plugin.
python-version: |
3.7
3.10
3.11
3.12
3.13
allow-prereleases: true

- name: Get default Python version
id: python-default
shell: bash
run: |
version="3.10"
version=$(target/list-versions.py --default)
(
echo "full-version=${version}.11"
if [ $RUNNER_OS = Windows ]; then
echo "command=py -$version"
else
echo "command=python$version"
fi
) >> $GITHUB_OUTPUT

- uses: actions/[email protected]
with:
# This should include all major.minor versions supported by the runtime, plus
# OLD_PYTHON_VERSION from test_gradle_plugin.
python-version: |
3.7
${{ steps.python-default.outputs.full-version }}
3.11
3.12
3.13
allow-prereleases: true

outputs:
python-default:
description: Command to run the default Python version
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: CI
on:
pull_request:
push:
branches: [master]

Expand All @@ -12,7 +13,6 @@ defaults:
shell: bash

jobs:

product:
runs-on: ubuntu-22.04
steps:
Expand Down Expand Up @@ -137,6 +137,7 @@ jobs:
path: maven

- name: Get keystore
if: github.event_name != 'pull_request'
env:
CHAQUO_JKS: ${{ secrets.CHAQUO_JKS }}
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ public class Common {

public static final String DEFAULT_PYTHON_VERSION = "3.10";

// Wheel tags (PEP 425).
public static final String PYTHON_IMPLEMENTATION = "cp"; // CPython

public static List<String> supportedAbis(String pythonVersion) {
if (!PYTHON_VERSIONS_SHORT.contains(pythonVersion)) {
throw new IllegalArgumentException(
Expand Down
19 changes: 0 additions & 19 deletions product/gradle-plugin/src/main/kotlin/PythonTasks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -227,25 +227,6 @@ internal class TaskBuilder(
args("--min-api-level", variant.minSdkVersion.apiLevel)
args(reqsArgs)
args("--")
args("--disable-pip-version-check")

// If the user passes a custom index url, disable our repository as
// well as the default one.
if (!listOf("--index-url", "-i").any {
it in python.pip.options
}) {
args("--extra-index-url", "https://chaquo.com/pypi-13.1")
}

// Pass the full Python version, but without any pre-release segment.
args("--implementation", Common.PYTHON_IMPLEMENTATION)
args("--python-version",
"""\d+\.\d+\.\d+""".toRegex()
.find(pythonVersionInfo(python).key)!!.value)
args("--abi",
Common.PYTHON_IMPLEMENTATION + python.version!!.replace(".", ""))

args("--no-compile")
args(python.pip.options)
}
inputs.property("args", args)
Expand Down
33 changes: 24 additions & 9 deletions product/gradle-plugin/src/main/python/chaquopy/pip_install.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import argparse
from base64 import urlsafe_b64encode
from collections import namedtuple
import email.parser
from fnmatch import fnmatch
Expand All @@ -15,7 +16,6 @@
from pip._internal.utils.misc import rmtree
from pip._vendor.distlib.database import DistributionPath
from pip._vendor.retrying import retry
from wheel.util import urlsafe_b64encode # Not the same as the version in base64.

from .util import CommandError

Expand Down Expand Up @@ -105,12 +105,24 @@ def pip_install(self, abi, reqs):

# Warning: `pip install --target` is very simple-minded: see
# https://github.com/pypa/pip/issues/4625#issuecomment-375977073.
cmdline = ([sys.executable,
"-m", "pip", "install",
"--isolated", # Disables environment variables.
"--target", abi_dir,
"--platform", self.platform_tag(abi)] +
self.pip_options + reqs)
cmdline = [
sys.executable, "-m", "pip", "install",
"--disable-pip-version-check",
"--use-pep517", # TODO: remove after updating to pip 25.3.
"--no-compile", # Compilation is handled in PythonTasks.kt.
"--isolated", # Disable environment variables.
"--target", abi_dir,
"--platform", self.platform_tag(abi)
] + (
# If the user passes a custom index url, disable our repository as well
# as the default one.
["--extra-index-url", "https://chaquo.com/pypi-13.1"]
if not any(opt in self.pip_options for opt in ["--index-url", "-i"])
else []
) + (
self.pip_options + reqs
)

logger.debug("Running {}".format(cmdline))
subprocess.check_call(cmdline)
except subprocess.CalledProcessError as e:
Expand Down Expand Up @@ -272,8 +284,11 @@ def file_matches_record(filename, hash_str, size):
return False
hash_algo, hash_expected = hash_str.split("=")
with open(filename, "rb") as f:
hash_actual = (urlsafe_b64encode(hashlib.new(hash_algo, f.read()).digest())
.decode("ASCII"))
hash_actual = (
urlsafe_b64encode(hashlib.new(hash_algo, f.read()).digest())
.decode("ASCII")
.rstrip("=")
)
return hash_actual == hash_expected


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ def __init__(self):
shutil.copy(join(dirname(pip_location), "../chaquopy_monkey.py"),
self._site_dir)
from pip._vendor.packaging import markers
if markers.python_version_info:
if markers.android_platform:
# We're not a recursive PEP517 pip instance.
fp.write(textwrap.dedent(
'''
import chaquopy_monkey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,17 @@ def check_dist_restriction(options, check_target=False):
not options.ignore_dependencies
)

# Chaquopy: make environment markers simulate Android.
if options.platform:
from pip._vendor.packaging import markers
markers.android_platform = options.platform

# Installations or downloads using dist restrictions must not combine
# source distributions and dist-specific wheels, as they are not
# guaranteed to be locally compatible.
#
# Chaquopy: added False to disable this restriction. It's safe for us to run source
# distributions, because chaquopy_monkey ensures they fail immediately if they
# Chaquopy: added False to disable this restriction. It's safe for us to run
# source distributions, as long as we ensure they fail immediately if they
# try to build anything native.
if False and dist_restriction_set and sdist_dependencies_allowed:
raise CommandError(
Expand Down Expand Up @@ -554,10 +559,6 @@ def _handle_python_version(option, opt_str, value, parser):

parser.values.python_version = version_info

# Chaquopy: make environment markers use the correct Python version.
from pip._vendor.packaging import markers
markers.python_version_info = version_info


python_version = partial(
Option,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,23 +531,6 @@ def _sort_key(self, candidate):
)
if self._prefer_binary:
binary_preference = 1

# Chaquopy: prefer older native wheels over sdists. We can't simply use
# --prefer-binary, because there are some pure-Python packages on PyPI which have
# wheels for old versions (sometimes years old) but only sdists for newer ones.
#
# Older native wheels must also be preferred over newer pure-Python wheels. For
# example, soundfile is a pure-Python package, but we've released it as a native
# wheel in order to add a requirement on libsndfile.
#
# Even if we didn't have any packages like this, consider a stuation with native
# 1.5, pure 1.6 and sdist 1.7. If pure 1.6 is preferred over native 1.5, and native
# 1.5 is preferred over sdist 1.7, then for the ordering to be consistent, pure 1.6
# must be preferred over sdist 1.7, which was exactly the situation we wanted to
# avoid.
if wheel.plats != ["any"]:
binary_preference = 2 # Override --prefer-binary if the user specified it.

pri = -(wheel.support_index_min(valid_tags))
if wheel.build_tag is not None:
match = re.match(r'^(\d+)(.*)$', wheel.build_tag)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def make_setuptools_shim_args(
from pip._vendor.packaging import markers
chaquopy_monkey = (
"import chaquopy_monkey; chaquopy_monkey.disable_native()"
if markers.python_version_info # We're not a recursive PEP517 pip instance.
if markers.android_platform # We're not a recursive PEP517 pip instance.
else "pass"
)
args.extend(['-c', _SETUPTOOLS_SHIM.format(setup_py_path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def format_full_version(info):

# Chaquopy: when installing for the target platform, this variable is set in
# cli/cmdoptions.py.
python_version_info = None
android_platform = None

def default_environment():
# type: () -> Dict[str, str]
Expand All @@ -290,19 +290,34 @@ def default_environment():

# Chaquopy: in the top-level pip instance (as opposed to a recursive PEP517 instance),
# we should use markers of the target platform.
if python_version_info:
if android_platform:
import re
api_level, abi = re.fullmatch(r"android_(\d+)_(.+)", android_platform).groups()
machine = {
"x86_64": "x86_64",
"x86": "i686",
"arm64_v8a": "aarch64",
"armeabi_v7a": "armv7l",
}[abi]

# For consistency with pip running on Termux, match the value returned when
# actually running on Android.
sys_platform = "linux" if sys.version_info < (3, 13) else "android"

# The Android Python major.minor version is guaranteed to be the same as the
# copy of Python running pip, and the micro version is unlikely to matter.
return {
"implementation_name": "cpython",
"implementation_version": ".".join(str(x) for x in python_version_info),
"implementation_version": platform.python_version(),
"os_name": "posix",
"platform_machine": "", # Not needed yet.
"platform_release": "",
"platform_system": "Linux",
"platform_version": "",
"python_full_version": ".".join(str(x) for x in python_version_info),
"platform_machine": machine,
"platform_release": "", # Non-trivial to determine from the API level.
"platform_system": sys_platform.capitalize(),
"platform_version": "", # Non-trivial to determine from the API level.
"python_full_version": platform.python_version(),
"platform_python_implementation": "CPython",
"python_version": ".".join(str(x) for x in python_version_info[:2]),
"sys_platform": "linux",
"python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys_platform,
}

return {
Expand Down

This file was deleted.

This file was deleted.

Loading