Skip to content

Commit 7be6ff0

Browse files
author
Jonas Thiem
committed
pythonpackage can't return build requirements for wheels.
Make sure the pythonpackage functions return an error when someone attempts to do so anyway
1 parent e409aeb commit 7be6ff0

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)