1010import operator
1111import os
1212import tarfile
13+ from typing import Dict
1314from typing import List
1415from typing import NamedTuple
1516from typing import Sequence
17+ from typing import Union
1618from zipfile import ZipFile
1719
18- import packaging .requirements
1920import packaging .utils
20- import packaging .version
2121import requests
2222from packageurl import PackageURL
2323from 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
2427from resolvelib import AbstractProvider
2528from resolvelib import Resolver
2629from resolvelib .reporters import BaseReporter
2730
31+ from _packagedcode .models import DependentPackage
32+ from _packagedcode .pypi import BasePypiHandler
2833from _packagedcode .pypi import PipRequirementsFileHandler
2934from _packagedcode .pypi import PypiWheelHandler
3035from _packagedcode .pypi import PythonSetupPyHandler
3136from _packagedcode .pypi import SetupCfgHandler
3237from python_inspector import utils_pypi
38+ from python_inspector .utils_pypi import Environment
39+ from python_inspector .utils_pypi import PypiSimpleRepository
3340
3441
3542class 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
541584def 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