Skip to content

Commit 5283c33

Browse files
committed
Add typing
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 2e63581 commit 5283c33

1 file changed

Lines changed: 76 additions & 33 deletions

File tree

src/python_inspector/resolution.py

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,33 @@
1010
import operator
1111
import os
1212
import tarfile
13+
from typing import Dict
1314
from typing import List
1415
from typing import NamedTuple
1516
from typing import Sequence
17+
from typing import Union
1618
from zipfile import ZipFile
1719

18-
import packaging.requirements
1920
import packaging.utils
20-
import packaging.version
2121
import requests
2222
from packageurl import PackageURL
2323
from packaging.requirements import Requirement
24+
from packaging.version import LegacyVersion
25+
from packaging.version import Version
26+
from packaging.version import parse as parse_version
2427
from resolvelib import AbstractProvider
2528
from resolvelib import Resolver
2629
from resolvelib.reporters import BaseReporter
2730

31+
from _packagedcode.models import DependentPackage
32+
from _packagedcode.pypi import BasePypiHandler
2833
from _packagedcode.pypi import PipRequirementsFileHandler
2934
from _packagedcode.pypi import PypiWheelHandler
3035
from _packagedcode.pypi import PythonSetupPyHandler
3136
from _packagedcode.pypi import SetupCfgHandler
3237
from python_inspector import utils_pypi
38+
from python_inspector.utils_pypi import Environment
39+
from python_inspector.utils_pypi import PypiSimpleRepository
3340

3441

3542
class Candidate(NamedTuple):
@@ -42,7 +49,7 @@ class Candidate(NamedTuple):
4249
extras: str
4350

4451

45-
def get_response(url):
52+
def get_response(url: str):
4653
"""
4754
Return a response for the given url.
4855
"""
@@ -52,7 +59,7 @@ def get_response(url):
5259
return None
5360

5461

55-
def get_requirements_from_distribution(handler, location):
62+
def get_requirements_from_distribution(handler: BasePypiHandler, location: str):
5663
"""
5764
Return a list of requirements from a distribution.
5865
"""
@@ -63,7 +70,7 @@ def get_requirements_from_distribution(handler, location):
6370
return list(get_requirements_from_dependencies(dependencies=deps[0].dependencies))
6471

6572

66-
def is_requirements_file_in_setup_files(setup_files):
73+
def is_requirements_file_in_setup_files(setup_files: List[str]):
6774
"""
6875
Return True if the given ``requirements.txt`` is in the given ``setup_files``.
6976
"""
@@ -76,7 +83,12 @@ def is_requirements_file_in_setup_files(setup_files):
7683
return False
7784

7885

79-
def is_valid_version(parsed_version, requirements, identifier, bad_versions):
86+
def is_valid_version(
87+
parsed_version: Union[LegacyVersion, Version],
88+
requirements: Dict,
89+
identifier: str,
90+
bad_versions: List[Version],
91+
):
8092
"""
8193
Return True if the parsed_version is valid for the given identifier.
8294
"""
@@ -99,7 +111,9 @@ def get_python_version_from_env_tag(python_version: str):
99111
return python_version
100112

101113

102-
def fetch_and_extract_sdist(repos, candidate, python_version):
114+
def fetch_and_extract_sdist(
115+
repos: List[PypiSimpleRepository], candidate: Candidate, python_version: str
116+
):
103117
"""
104118
Fetch and extract the source distribution (sdist) for the ``candidate`` Candidate
105119
from the `repos` list of PyPiRepository
@@ -139,7 +153,7 @@ def fetch_and_extract_sdist(repos, candidate, python_version):
139153
return os.path.join(utils_pypi.CACHE_THIRDPARTY_DIR, "extracted_sdists", sdist_file, sdist_file)
140154

141155

142-
def get_requirements_from_dependencies(dependencies):
156+
def get_requirements_from_dependencies(dependencies: List[DependentPackage]):
143157
"""
144158
Generate parsed requirements for the given ``dependencies``.
145159
"""
@@ -153,10 +167,10 @@ def get_requirements_from_dependencies(dependencies):
153167
# skip the requirement starting with -- like
154168
# --editable, --requirement
155169
if not dep.extracted_requirement.startswith("-"):
156-
yield packaging.requirements.Requirement(str(dep.extracted_requirement))
170+
yield Requirement(str(dep.extracted_requirement))
157171

158172

159-
def remove_extras(identifier):
173+
def remove_extras(identifier: str):
160174
"""
161175
Return the identifier without extras.
162176
>>> assert remove_extras("foo[bar]") == "foo"
@@ -173,7 +187,7 @@ def __init__(self, environment=None, repos=tuple()):
173187
self.dependencies_by_purl = {}
174188
self.wheel_or_sdist_by_package = {}
175189

176-
def identify(self, requirement_or_candidate):
190+
def identify(self, requirement_or_candidate: Union[Candidate, Requirement]):
177191
"""Given a requirement, return an identifier for it. Overridden."""
178192
name = packaging.utils.canonicalize_name(requirement_or_candidate.name)
179193
if requirement_or_candidate.extras:
@@ -194,7 +208,9 @@ def get_preference(
194208
transitive = all(p is not None for _, p in information[identifier])
195209
return transitive, identifier
196210

197-
def get_versions_for_package(self, name, repo=None):
211+
def get_versions_for_package(
212+
self, name: str, repo: Union[List[PypiSimpleRepository], None] = None
213+
):
198214
"""
199215
Return a list of versions for a package.
200216
"""
@@ -203,13 +219,13 @@ def get_versions_for_package(self, name, repo=None):
203219
else:
204220
return self.get_versions_for_package_from_pypi_json_api(name)
205221

206-
def get_versions_for_package_from_repo(self, name, repo):
222+
def get_versions_for_package_from_repo(self, name: str, repo: PypiSimpleRepository):
207223
"""
208224
Return a list of versions for a package name from a repo
209225
"""
210226
versions = []
211227
for version, package in repo.get_package_versions(name).items():
212-
python_version = packaging.version.parse(
228+
python_version = parse_version(
213229
get_python_version_from_env_tag(python_version=self.environment.python_version)
214230
)
215231
wheels = list(package.get_supported_wheels(environment=self.environment))
@@ -225,7 +241,7 @@ def get_versions_for_package_from_repo(self, name, repo):
225241
versions.append(version)
226242
return versions
227243

228-
def get_versions_for_package_from_pypi_json_api(self, name):
244+
def get_versions_for_package_from_pypi_json_api(self, name: str):
229245
"""
230246
Return a list of versions for a package name from the PyPI.org JSON API
231247
"""
@@ -239,7 +255,7 @@ def get_versions_for_package_from_pypi_json_api(self, name):
239255
versions = self.versions_by_package[name]
240256
return versions
241257

242-
def get_requirements_for_package(self, purl, candidate):
258+
def get_requirements_for_package(self, purl: PackageURL, candidate: Candidate):
243259
"""
244260
Yield requirements for a package.
245261
"""
@@ -248,11 +264,11 @@ def get_requirements_for_package(self, purl, candidate):
248264
else:
249265
return self.get_requirements_for_package_from_pypi_json_api(purl)
250266

251-
def get_requirements_for_package_from_pypi_simple(self, candidate):
267+
def get_requirements_for_package_from_pypi_simple(self, candidate: Candidate):
252268
"""
253269
Return requirements for a package from the simple repositories.
254270
"""
255-
python_version = packaging.version.parse(
271+
python_version = parse_version(
256272
get_python_version_from_env_tag(python_version=self.environment.python_version)
257273
)
258274

@@ -321,7 +337,7 @@ def get_requirements_for_package_from_pypi_simple(self, candidate):
321337
if deps:
322338
yield from deps
323339

324-
def get_requirements_for_package_from_pypi_json_api(self, purl):
340+
def get_requirements_for_package_from_pypi_json_api(self, purl: PackageURL):
325341
"""
326342
Return requirements for a package from the PyPI.org JSON API
327343
"""
@@ -335,14 +351,22 @@ def get_requirements_for_package_from_pypi_json_api(self, purl):
335351
requires_dist = info.get("requires_dist") or []
336352
self.dependencies_by_purl[str(purl)] = requires_dist
337353
for dependency in self.dependencies_by_purl[str(purl)]:
338-
yield packaging.requirements.Requirement(dependency)
354+
yield Requirement(dependency)
339355

340-
def get_candidates(self, all_versions, requirements, identifier, bad_versions, name, extras):
356+
def get_candidates(
357+
self,
358+
all_versions: List[str],
359+
requirements: List[Requirement],
360+
identifier: str,
361+
bad_versions: List[str],
362+
name: str,
363+
extras: Dict,
364+
):
341365
"""
342366
Generate candidates for the given identifier. Overridden.
343367
"""
344368
for version in all_versions:
345-
parsed_version = packaging.version.parse(version)
369+
parsed_version = parse_version(version)
346370
if not is_valid_version(
347371
parsed_version=parsed_version,
348372
requirements=requirements,
@@ -352,7 +376,12 @@ def get_candidates(self, all_versions, requirements, identifier, bad_versions, n
352376
continue
353377
yield Candidate(name=name, version=parsed_version, extras=extras)
354378

355-
def _iter_matches(self, identifier, requirements, incompatibilities):
379+
def _iter_matches(
380+
self,
381+
identifier: str,
382+
requirements: List[Requirement],
383+
incompatibilities: Dict,
384+
):
356385
"""
357386
Yield candidates for the given identifier, requirements and incompatibilities
358387
"""
@@ -371,7 +400,12 @@ def _iter_matches(self, identifier, requirements, incompatibilities):
371400
all_versions, requirements, identifier, bad_versions, name, extras
372401
)
373402

374-
def find_matches(self, identifier, requirements, incompatibilities):
403+
def find_matches(
404+
self,
405+
identifier: str,
406+
requirements: List[Requirement],
407+
incompatibilities: Dict,
408+
):
375409
"""Find all possible candidates that satisfy given constraints. Overridden."""
376410
candidates = sorted(
377411
self._iter_matches(identifier, requirements, incompatibilities),
@@ -380,19 +414,19 @@ def find_matches(self, identifier, requirements, incompatibilities):
380414
)
381415
return candidates
382416

383-
def is_satisfied_by(self, requirement, candidate):
417+
def is_satisfied_by(self, requirement: Requirement, candidate: Candidate):
384418
"""Whether the given requirement can be satisfied by a candidate. Overridden."""
385419
return candidate.version in requirement.specifier
386420

387-
def _iter_dependencies(self, candidate):
421+
def _iter_dependencies(self, candidate: Candidate):
388422
"""
389423
Yield dependencies for the given candidate.
390424
"""
391425
name = packaging.utils.canonicalize_name(candidate.name)
392426
# TODO: handle extras https://github.com/nexB/python-inspector/issues/10
393427
if candidate.extras:
394428
r = f"{name}=={candidate.version}"
395-
yield packaging.requirements.Requirement(r)
429+
yield Requirement(r)
396430

397431
purl = PackageURL(
398432
type="pypi",
@@ -416,12 +450,17 @@ def _iter_dependencies(self, candidate):
416450
):
417451
yield r
418452

419-
def get_dependencies(self, candidate):
453+
def get_dependencies(self, candidate: Candidate):
420454
"""Get dependencies of a candidate. Overridden."""
421455
return list(self._iter_dependencies(candidate))
422456

423457

424-
def get_wheel_download_urls(purl, repos, environment, python_version):
458+
def get_wheel_download_urls(
459+
purl: PackageURL,
460+
repos: List[PypiSimpleRepository],
461+
environment: Environment,
462+
python_version: str,
463+
):
425464
"""
426465
Return a list of download urls for the given purl.
427466
"""
@@ -436,7 +475,9 @@ def get_wheel_download_urls(purl, repos, environment, python_version):
436475
yield wheel.download_url
437476

438477

439-
def get_sdist_download_url(purl, repos, python_version):
478+
def get_sdist_download_url(
479+
purl: PackageURL, repos: List[PypiSimpleRepository], python_version: str
480+
):
440481
"""
441482
Return a list of download urls for the given purl.
442483
"""
@@ -479,7 +520,9 @@ def dfs(mapping, graph, src):
479520
)
480521

481522

482-
def format_resolution(results, environment, repos, as_tree=False):
523+
def format_resolution(
524+
results, environment: Environment, repos: List[PypiSimpleRepository], as_tree=False
525+
):
483526
"""
484527
Return a formatted resolution either as a tree or parent/children.
485528
"""
@@ -540,8 +583,8 @@ def format_resolution(results, environment, repos, as_tree=False):
540583

541584
def get_resolved_dependencies(
542585
requirements: List[Requirement],
543-
environment: utils_pypi.Environment = None,
544-
repos: Sequence[utils_pypi.PypiSimpleRepository] = tuple(),
586+
environment: Environment = None,
587+
repos: Sequence[PypiSimpleRepository] = tuple(),
545588
as_tree: bool = False,
546589
max_rounds: int = 200000,
547590
):

0 commit comments

Comments
 (0)