Skip to content
Merged
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
57 changes: 54 additions & 3 deletions src/python_inspector/resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,36 @@ def get_dependencies(self, candidate):
return list(self._iter_dependencies(candidate))


def get_wheel_download_urls(purl, repos, environment, python_version):
"""
Return a list of download urls for the given purl.
"""
for repo in repos:
for wheel in utils_pypi.get_supported_and_valid_wheels(
repo=repo,
name=purl.name,
version=purl.version,
environment=environment,
python_version=python_version,
):
yield wheel.download_url


def get_sdist_download_url(purl, repos, python_version):
"""
Return a list of download urls for the given purl.
"""
for repo in repos:
sdist = utils_pypi.get_valid_sdist(
repo=repo,
name=purl.name,
version=purl.version,
python_version=python_version,
)
if sdist:
return sdist.download_url


def get_all_srcs(mapping, graph):
"""
Return a list of all sources in the graph.
Expand Down Expand Up @@ -412,7 +442,7 @@ def dfs(mapping, graph, src):
)


def format_resolution(results, as_tree=False):
def format_resolution(results, environment, repos, as_tree=False):
"""
Return a formatted resolution either as a tree or parent/children.
"""
Expand All @@ -437,7 +467,28 @@ def format_resolution(results, as_tree=False):
)
dependencies.append(str(dep_purl))
dependencies.sort()
parent_children = dict(package=str(parent_purl), dependencies=dependencies)
python_version = get_python_version_from_env_tag(
python_version=environment.python_version
)
wheel_urls = list(
get_wheel_download_urls(
purl=parent_purl,
repos=repos,
environment=environment,
python_version=python_version,
)
)
sdist_url = get_sdist_download_url(
purl=parent_purl,
repos=repos,
python_version=python_version,
)
parent_children = dict(
package=str(parent_purl),
dependencies=dependencies,
wheel_urls=list(dict.fromkeys(wheel_urls)),
sdist_url=sdist_url,
)
as_parent_children.append(parent_children)
as_parent_children.sort(key=lambda d: d["package"])
return as_parent_children
Expand Down Expand Up @@ -477,5 +528,5 @@ def get_resolved_dependencies(
reporter=BaseReporter(),
)
results = resolver.resolve(requirements=requirements, max_rounds=max_rounds)
results = format_resolution(results, as_tree=as_tree)
results = format_resolution(results, as_tree=as_tree, environment=environment, repos=repos)
return results
93 changes: 62 additions & 31 deletions src/python_inspector/utils_pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,28 +219,17 @@ def download_wheel(
repos = DEFAULT_PYPI_REPOS

fetched_wheel_filenames = []

for repo in repos:
package = repo.get_package_version(name=name, version=version)
if not package:
if TRACE_DEEP:
print(f" download_wheel: No package in {repo.index_url} for {name}=={version}")
continue
supported_wheels = list(package.get_supported_wheels(environment=environment))
if not supported_wheels:
supported_and_valid_wheels = get_supported_and_valid_wheels(
repo, name, version, environment, python_version
)
if not supported_and_valid_wheels:
if TRACE_DEEP:
print(
f" download_wheel: No supported wheel for {name}=={version}: {environment} "
f" download_wheel: No supported and valid wheel for {name}=={version}: {environment} "
)
continue

for wheel in supported_wheels:
if not valid_distribution(wheel, python_version):
continue
if TRACE_DEEP:
print(
f" download_wheel: Getting wheel from index (or cache): {wheel.download_url}"
)
for wheel in supported_and_valid_wheels:
fetched_wheel_filename = wheel.download(
dest_dir=dest_dir,
verbose=verbose,
Expand All @@ -251,10 +240,62 @@ def download_wheel(
if fetched_wheel_filenames:
# do not futher fetch from other repos if we find in first, typically PyPI
break

return fetched_wheel_filenames


def get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION):
package = repo.get_package_version(name=name, version=version)
if not package:
if TRACE_DEEP:
print(
print(f" get_valid_sdist: No package in {repo.index_url} for {name}=={version}")
)
return
sdist = package.sdist
if not sdist:
if TRACE_DEEP:
print(f" get_valid_sdist: No sdist for {name}=={version}")
return
if not valid_distribution(sdist, python_version):
return
if TRACE_DEEP:
print(f" get_valid_sdist: Getting sdist from index (or cache): {sdist.download_url}")
return sdist


def get_supported_and_valid_wheels(
repo, name, version, environment, python_version=DEFAULT_PYTHON_VERSION
) -> List:
"""
Return a list of wheels matching the ``environment`` Environment constraints.
"""
package = repo.get_package_version(name=name, version=version)
if not package:
if TRACE_DEEP:
print(
f" get_supported_and_valid_wheels: No package in {repo.index_url} for {name}=={version}"
)
return []
supported_wheels = list(package.get_supported_wheels(environment=environment))
if not supported_wheels:
if TRACE_DEEP:
print(
f" get_supported_and_valid_wheels: No supported wheel for {name}=={version}: {environment}"
)
return []
wheels = []
for wheel in supported_wheels:
if not valid_distribution(wheel, python_version):
continue
if TRACE_DEEP:
print(
f""" get_supported_and_valid_wheels: Getting wheel from index (or cache):
{wheel.download_url}"""
)
wheels.append(wheel)
return wheels


def valid_distribution(distribution, python_version):
"""
Return True if distribution is a valid distribution for the given Python version.
Expand Down Expand Up @@ -289,22 +330,12 @@ def download_sdist(
fetched_sdist_filename = None

for repo in repos:
package = repo.get_package_version(name=name, version=version)

if not package:
if TRACE_DEEP:
print(f" download_sdist: No package in {repo.index_url} for {name}=={version}")
continue
sdist = package.sdist
sdist = get_valid_sdist(repo, name, version, python_version=DEFAULT_PYTHON_VERSION)
if not sdist:
if TRACE_DEEP:
print(f" download_sdist: No sdist for {name}=={version}")
print(f" download_sdist: No valid sdist for {name}=={version}")
continue
if not valid_distribution(sdist, python_version):
continue
if TRACE_DEEP:
print(f" download_sdist: Getting sdist from index (or cache): {sdist.download_url}")
fetched_sdist_filename = package.sdist.download(
fetched_sdist_filename = sdist.download(
dest_dir=dest_dir,
verbose=verbose,
echo_func=echo_func,
Expand Down
4 changes: 3 additions & 1 deletion tests/data/default-url-expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
"resolved_dependencies": [
{
"package": "pkg:pypi/zipp@3.8.0",
"dependencies": []
"dependencies": [],
"wheel_urls": [],
"sdist_url": null
}
]
}
Loading