Skip to content
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

python: update to 3.13 #3082

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
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
95 changes: 95 additions & 0 deletions pythonforandroid/artifact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import zipfile
import json
import os
import subprocess


class ArtifactName:

platform = "android"

def __init__(self, recipe, arch):
self.recipe = recipe
self._arch = arch

@property
def stage(self):
return "master"
result = subprocess.check_output(
["git", "branch", "--show-current"],
stderr=subprocess.PIPE,
universal_newlines=True,
)
return result.strip()

@property
def kind(self):
return "lib"

@property
def arch(self):
return self._arch.arch

@property
def native_api_level(self):
return str(self.recipe.ctx.ndk_api)

@property
def file_props(self):
return [
self.stage,
self.kind,
self.recipe.name,
self.arch,
self.platform + self.native_api_level,
self.recipe.version,
]

@property
def filename(self):
return "_".join(self.file_props) + ".zip"


def build_artifact(
save_path,
recipe,
arch,
lib_dependencies=[],
files_dependencies=[],
install_instructions=[],
):
# Parse artifact name
artifact_name = ArtifactName(recipe, arch)
zip_path = os.path.join(save_path, artifact_name.filename)

# Contents of zip file
metadata_folder = "metadata/"
data_folder = "data/"
prop_file = os.path.join(metadata_folder, "properties.json")
install_file = os.path.join(metadata_folder, "install.json")

properties = {
"stage": artifact_name.stage,
"name": recipe.name,
"arch": artifact_name.arch,
"native_api_level": artifact_name.native_api_level,
"kind": artifact_name.kind,
"version": recipe.version,
"release_version": recipe.version,
"lib_dependencies": lib_dependencies,
"files_dependencies": files_dependencies,
}

with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
zipf.writestr(metadata_folder, "")
zipf.writestr(data_folder, "")

for file_name in lib_dependencies + files_dependencies:
with open(file_name, "rb") as file:
file_name_ = os.path.join(data_folder + os.path.basename(file_name))
zipf.writestr(file_name_, file.read())
file.close()

zipf.writestr(prop_file, json.dumps(properties))
zipf.writestr(install_file, json.dumps(install_instructions))
zipf.close()
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ protected static ArrayList<String> getLibraries(File libsDir) {
libsList.add("python3.9");
libsList.add("python3.10");
libsList.add("python3.11");
libsList.add("python3.12");
libsList.add("python3.13");
libsList.add("main");
return libsList;
}
Expand All @@ -75,7 +77,7 @@ public static void loadLibraries(File filesDir, File libsDir) {
// load, and it has failed, give a more
// general error
Log.v(TAG, "Library loading error: " + e.getMessage());
if (lib.startsWith("python3.11") && !foundPython) {
if (lib.startsWith("python3.13") && !foundPython) {
throw new RuntimeException("Could not load any libpythonXXX.so");
} else if (lib.startsWith("python")) {
continue;
Expand Down
18 changes: 14 additions & 4 deletions pythonforandroid/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class Context:

java_build_tool = 'auto'

save_prebuilt = False

@property
def packages_path(self):
'''Where packages are downloaded before being unpacked'''
Expand Down Expand Up @@ -147,11 +149,17 @@ def setup_dirs(self, storage_dir):
'specify a path with --storage-dir')
self.build_dir = join(self.storage_dir, 'build')
self.dist_dir = join(self.storage_dir, 'dists')
self.prebuilt_dir = join(self.storage_dir, 'output')
self.ensure_dirs()

def ensure_dirs(self):
ensure_dir(self.storage_dir)
ensure_dir(self.build_dir)
ensure_dir(self.dist_dir)

if self.save_prebuilt:
ensure_dir(self.prebuilt_dir)

ensure_dir(join(self.build_dir, 'bootstrap_builds'))
ensure_dir(join(self.build_dir, 'other_builds'))

Expand Down Expand Up @@ -219,8 +227,6 @@ def prepare_build_environment(self,

'''

self.ensure_dirs()

if self._build_env_prepared:
return

Expand Down Expand Up @@ -672,6 +678,7 @@ def run_pymodules_install(ctx, arch, modules, project_dir=None,
# Bail out if no python deps and no setup.py to process:
if not modules and (
ignore_setup_py or
project_dir is None or
not project_has_setup_py(project_dir)
):
info('No Python modules and no setup.py to process, skipping')
Expand All @@ -687,7 +694,8 @@ def run_pymodules_install(ctx, arch, modules, project_dir=None,
"If this fails, it may mean that the module has compiled "
"components and needs a recipe."
)
if project_has_setup_py(project_dir) and not ignore_setup_py:
if project_dir is not None and \
project_has_setup_py(project_dir) and not ignore_setup_py:
info(
"Will process project install, if it fails then the "
"project may not be compatible for Android install."
Expand Down Expand Up @@ -759,7 +767,9 @@ def run_pymodules_install(ctx, arch, modules, project_dir=None,
_env=copy.copy(env))

# Afterwards, run setup.py if present:
if project_has_setup_py(project_dir) and not ignore_setup_py:
if project_dir is not None and (
project_has_setup_py(project_dir) and not ignore_setup_py
):
run_setuppy_install(ctx, project_dir, env, arch)
elif not ignore_setup_py:
info("No setup.py found in project directory: " + str(project_dir))
Expand Down
6 changes: 3 additions & 3 deletions pythonforandroid/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def obvious_conflict_checker(ctx, name_tuples, blacklist=None):
return None


def get_recipe_order_and_bootstrap(ctx, names, bs=None, blacklist=None):
def get_recipe_order_and_bootstrap(ctx, names, bs=None, blacklist=None, should_log = False):
# Get set of recipe/dependency names, clean up and add bootstrap deps:
names = set(names)
if bs is not None and bs.recipe_depends:
Expand Down Expand Up @@ -311,7 +311,7 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None, blacklist=None):
for order in orders:
info(' {}'.format(order))
info('Using the first of these: {}'.format(chosen_order))
else:
elif should_log:
info('Found a single valid recipe set: {}'.format(chosen_order))

if bs is None:
Expand All @@ -322,7 +322,7 @@ def get_recipe_order_and_bootstrap(ctx, names, bs=None, blacklist=None):
"Could not find any compatible bootstrap!"
)
recipes, python_modules, bs = get_recipe_order_and_bootstrap(
ctx, chosen_order, bs=bs, blacklist=blacklist
ctx, chosen_order, bs=bs, blacklist=blacklist, should_log=True
)
else:
# check if each requirement has a recipe
Expand Down
7 changes: 4 additions & 3 deletions pythonforandroid/pythonpackage.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,10 +556,11 @@ def _extract_info_from_package(dependency,

# Get build requirements from pyproject.toml if requested:
requirements = []
pyproject_toml_path = os.path.join(output_folder, 'pyproject.toml')
if os.path.exists(pyproject_toml_path) and include_build_requirements:
if os.path.exists(os.path.join(output_folder,
'pyproject.toml')
) and include_build_requirements:
# Read build system from pyproject.toml file: (PEP518)
with open(pyproject_toml_path) as f:
with open(os.path.join(output_folder, 'pyproject.toml')) as f:
build_sys = toml.load(f)['build-system']
if "requires" in build_sys:
requirements += build_sys["requires"]
Expand Down
Loading
Loading