Skip to content

Commit 26dfac2

Browse files
authored
Merge pull request #1852 from JonasT/fix_pythonpackage_wheel_buildreqs
pythonpackage can't return build requirements for wheels, make it return an error if attempted
2 parents efc6d9b + 7be6ff0 commit 26dfac2

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

pythonforandroid/pythonpackage.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ def extract_metainfo_files_from_package(
9797
if not os.path.exists(output_folder) or os.path.isfile(output_folder):
9898
raise ValueError("output folder needs to be existing folder")
9999

100+
if debug:
101+
print("extract_metainfo_files_from_package: extracting for " +
102+
"package: " + str(package))
103+
100104
# A temp folder for making a package copy in case it's a local folder,
101105
# because extracting metadata might modify files
102106
# (creating sdists/wheels...)
@@ -418,6 +422,7 @@ def _extract_metainfo_files_from_package_unsafe(
418422
try:
419423
build_requires = []
420424
metadata_path = None
425+
421426
if path_type != "wheel":
422427
# We need to process this first to get the metadata.
423428

@@ -447,7 +452,9 @@ def _extract_metainfo_files_from_package_unsafe(
447452
metadata = None
448453
with env:
449454
hooks = Pep517HookCaller(path, backend)
450-
env.pip_install([transform_dep_for_pip(req) for req in build_requires])
455+
env.pip_install(
456+
[transform_dep_for_pip(req) for req in build_requires]
457+
)
451458
reqs = hooks.get_requires_for_build_wheel({})
452459
env.pip_install([transform_dep_for_pip(req) for req in reqs])
453460
try:
@@ -466,6 +473,15 @@ def _extract_metainfo_files_from_package_unsafe(
466473
"METADATA"
467474
)
468475

476+
# Store type of metadata source. Can be "wheel", "source" for source
477+
# distribution, and others get_package_as_folder() may support
478+
# in the future.
479+
with open(os.path.join(output_path, "metadata_source"), "w") as f:
480+
try:
481+
f.write(path_type)
482+
except TypeError: # in python 2 path_type may be str/bytes:
483+
f.write(path_type.decode("utf-8", "replace"))
484+
469485
# Copy the metadata file:
470486
shutil.copyfile(metadata_path, os.path.join(output_path, "METADATA"))
471487
finally:
@@ -518,12 +534,23 @@ def _extract_info_from_package(dependency,
518534
- name
519535
- dependencies (a list of dependencies)
520536
"""
537+
if debug:
538+
print("_extract_info_from_package called with "
539+
"extract_type={} include_build_requirements={}".format(
540+
extract_type, include_build_requirements,
541+
))
521542
output_folder = tempfile.mkdtemp(prefix="pythonpackage-metafolder-")
522543
try:
523544
extract_metainfo_files_from_package(
524545
dependency, output_folder, debug=debug
525546
)
526547

548+
# Extract the type of data source we used to get the metadata:
549+
with open(os.path.join(output_folder,
550+
"metadata_source"), "r") as f:
551+
metadata_source_type = f.read().strip()
552+
553+
# Extract main METADATA file:
527554
with open(os.path.join(output_folder, "METADATA"),
528555
"r", encoding="utf-8"
529556
) as f:
@@ -539,14 +566,34 @@ def _extract_info_from_package(dependency,
539566
raise ValueError("failed to obtain package name")
540567
return name
541568
elif extract_type == "dependencies":
569+
# First, make sure we don't attempt to return build requirements
570+
# for wheels since they usually come without pyproject.toml
571+
# and we haven't implemented another way to get them:
572+
if include_build_requirements and \
573+
metadata_source_type == "wheel":
574+
if debug:
575+
print("_extract_info_from_package: was called "
576+
"with include_build_requirements=True on "
577+
"package obtained as wheel, raising error...")
578+
raise NotImplementedError(
579+
"fetching build requirements for "
580+
"wheels is not implemented"
581+
)
582+
583+
# Get build requirements from pyproject.toml if requested:
542584
requirements = []
543585
if os.path.exists(os.path.join(output_folder,
544586
'pyproject.toml')
545587
) and include_build_requirements:
588+
# Read build system from pyproject.toml file: (PEP518)
546589
with open(os.path.join(output_folder, 'pyproject.toml')) as f:
547590
build_sys = pytoml.load(f)['build-system']
548591
if "requires" in build_sys:
549592
requirements += build_sys["requires"]
593+
elif include_build_requirements:
594+
# For legacy packages with no pyproject.toml, we have to
595+
# add setuptools as default build system.
596+
requirements.append("setuptools")
550597

551598
# Add requirements from metadata:
552599
requirements += [

tests/test_pythonpackage_basic.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ def fake_metadata_extract(dep_name, output_folder, debug=False):
4343
4444
Lorem Ipsum"""
4545
))
46+
with open(os.path.join(output_folder, "metadata_source"), "w") as f:
47+
f.write(u"wheel") # since we have no pyproject.toml
4648

4749

4850
def test__extract_info_from_package():
@@ -87,9 +89,25 @@ def test_get_dep_names_of_package():
8789
dep_names = get_dep_names_of_package("python-for-android")
8890
assert "colorama" in dep_names
8991
assert "setuptools" not in dep_names
90-
dep_names = get_dep_names_of_package("python-for-android",
91-
include_build_requirements=True)
92-
assert "setuptools" in dep_names
92+
try:
93+
dep_names = get_dep_names_of_package(
94+
"python-for-android", include_build_requirements=True,
95+
verbose=True,
96+
)
97+
except NotImplementedError as e:
98+
# If python-for-android was fetched as wheel then build requirements
99+
# cannot be obtained (since that is not implemented for wheels).
100+
# Check for the correct error message:
101+
assert "wheel" in str(e)
102+
# (And yes it would be better to do a local test with something
103+
# that is guaranteed to be a wheel and not remote on pypi,
104+
# but that might require setting up a full local pypiserver.
105+
# Not worth the test complexity for now, but if anyone has an
106+
# idea in the future feel free to replace this subtest.)
107+
else:
108+
# We managed to obtain build requirements!
109+
# Check setuptools is in here:
110+
assert "setuptools" in dep_names
93111

94112
# TEST 2 from local folder:
95113
assert "colorama" in get_dep_names_of_package(local_repo_folder())

0 commit comments

Comments
 (0)