@@ -253,6 +253,59 @@ def remove_extras(identifier: str) -> str:
253253 return name
254254
255255
256+ def get_reqs_from_requirements_file_in_sdist (sdist_location : str , files : str ) -> List [Requirement ]:
257+ """
258+ Return a list of parsed requirements from the ``sdist_location`` sdist location
259+ """
260+ if contain_string (string = "requirements.txt" , files = files ):
261+ requirement_location = os .path .join (
262+ sdist_location ,
263+ "requirements.txt" ,
264+ )
265+ yield from get_requirements_from_distribution (
266+ handler = PipRequirementsFileHandler ,
267+ location = requirement_location ,
268+ )
269+
270+
271+ def get_reqs_insecurely (setup_py_location ):
272+ """
273+ Return a list of Requirement(s) from ``setup_py_location`` setup.py file location
274+ """
275+ yield from parse_reqs_from_setup_py_insecurely (setup_py = setup_py_location )
276+
277+
278+ def get_requirements_from_python_manifest (
279+ sdist_location : str , setup_py_location : str , files : List , analyze_setup_py_insecurely : bool
280+ ) -> List [Requirement ]:
281+ """
282+ Return a list of parsed requirements from the ``sdist_location`` sdist location
283+ """
284+ # Look in requirements file if and only if thy are refered in setup.py or setup.cfg
285+ # And no deps have been yielded by requirements file.
286+ requirements = list (
287+ get_reqs_from_requirements_file_in_sdist (
288+ files = files ,
289+ sdist_location = sdist_location ,
290+ )
291+ )
292+ if requirements :
293+ yield from requirements
294+
295+ elif contain_string (string = "_require" , files = [setup_py_location ]):
296+ if analyze_setup_py_insecurely :
297+ yield from get_reqs_insecurely (
298+ setup_py_location = setup_py_location ,
299+ )
300+
301+ else :
302+ # We should not raise exception here as we may have a setup.py that does not
303+ # have any dependencies. We should not fail in this case.
304+ raise Exception (
305+ f"Unable to collect setup.py dependencies securely: { setup_py_location } "
306+ )
307+
308+
256309DEFAULT_ENVIRONMENT = utils_pypi .Environment .from_pyver_and_os (
257310 python_version = "38" , operating_system = "linux"
258311)
@@ -376,12 +429,12 @@ def get_requirements_for_package_from_pypi_simple(
376429 if wheels :
377430 for wheel in wheels :
378431 wheel_location = os .path .join (utils_pypi .CACHE_THIRDPARTY_DIR , wheel )
379- deps = get_requirements_from_distribution (
432+ requirements = get_requirements_from_distribution (
380433 handler = PypiWheelHandler ,
381434 location = wheel_location ,
382435 )
383- if deps :
384- yield from deps
436+ if requirements :
437+ yield from requirements
385438 # We are only looking at the first wheel and not other wheels
386439 break
387440
@@ -391,11 +444,36 @@ def get_requirements_for_package_from_pypi_simple(
391444 )
392445 if not sdist_location :
393446 return
394- yield from get_setup_dependencies (
395- location = sdist_location ,
396- analyze_setup_py_insecurely = self .analyze_setup_py_insecurely ,
447+
448+ setup_py_location = os .path .join (
449+ sdist_location ,
450+ "setup.py" ,
451+ )
452+ setup_cfg_location = os .path .join (
453+ sdist_location ,
454+ "setup.cfg" ,
397455 )
398456
457+ requirements = list (
458+ get_setup_requirements (
459+ sdist_location = sdist_location ,
460+ setup_py_location = setup_py_location ,
461+ setup_cfg_location = setup_cfg_location ,
462+ )
463+ )
464+ if requirements :
465+ yield from requirements
466+ else :
467+ # Look in requirements file if and only if thy are refered in setup.py or setup.cfg
468+ # And no deps have been yielded by requirements file
469+
470+ yield from get_requirements_from_python_manifest (
471+ sdist_location = sdist_location ,
472+ setup_py_location = setup_py_location ,
473+ files = [setup_cfg_location , setup_py_location ],
474+ analyze_setup_py_insecurely = self .analyze_setup_py_insecurely ,
475+ )
476+
399477 def get_requirements_for_package_from_pypi_json_api (
400478 self , purl : PackageURL
401479 ) -> List [Requirement ]:
@@ -654,7 +732,7 @@ def get_package_list(results):
654732 return list (sorted (packages ))
655733
656734
657- def get_setup_dependencies ( location , analyze_setup_py_insecurely = False , use_requirements = True ):
735+ def get_setup_requirements ( sdist_location : str , setup_py_location : str , setup_cfg_location : str ):
658736 """
659737 Yield Requirement(s) from Pypi in the ``location`` directory that contains
660738 a setup.py and/or a setup.cfg and optionally a requirements.txt file if
@@ -663,17 +741,8 @@ def get_setup_dependencies(location, analyze_setup_py_insecurely=False, use_requ
663741 ``analyze_setup_py_insecurely`` is True.
664742 """
665743
666- setup_py_location = os .path .join (
667- location ,
668- "setup.py" ,
669- )
670- setup_cfg_location = os .path .join (
671- location ,
672- "setup.cfg" ,
673- )
674-
675744 if not os .path .exists (setup_py_location ) and not os .path .exists (setup_cfg_location ):
676- raise Exception (f"No setup.py or setup.cfg found in pypi sdist { location } " )
745+ raise Exception (f"No setup.py or setup.cfg found in pypi sdist { sdist_location } " )
677746
678747 # Some commonon packages like flask may have some dependencies in setup.cfg
679748 # and some dependencies in setup.py. We are going to check both.
@@ -682,43 +751,9 @@ def get_setup_dependencies(location, analyze_setup_py_insecurely=False, use_requ
682751 SetupCfgHandler : setup_cfg_location ,
683752 }
684753
685- # Set to True if we found any dependencies in setup.py or setup.cfg
686- has_deps = False
687-
688754 for handler , location in location_by_sdist_parser .items ():
689- deps = get_requirements_from_distribution (
755+ reqs = get_requirements_from_distribution (
690756 handler = handler ,
691757 location = location ,
692758 )
693- if deps :
694- has_deps = True
695- yield from deps
696-
697- if (
698- use_requirements
699- and not has_deps
700- and contain_string (string = "requirements.txt" , files = [setup_py_location , setup_cfg_location ])
701- ):
702- # Look in requirements file if and only if thy are refered in setup.py or setup.cfg
703- # And no deps have been yielded by requirements file.
704- requirement_location = os .path .join (
705- location ,
706- "requirements.txt" ,
707- )
708- deps = get_requirements_from_distribution (
709- handler = PipRequirementsFileHandler ,
710- location = requirement_location ,
711- )
712- if deps :
713- has_deps = True
714- yield from deps
715-
716- if not has_deps and contain_string (
717- string = "_require" , files = [setup_py_location , setup_cfg_location ]
718- ):
719- if analyze_setup_py_insecurely :
720- yield from parse_reqs_from_setup_py_insecurely (setup_py = setup_py_location )
721- else :
722- # We should not raise exception here as we may have a setup.py that does not
723- # have any dependencies. We should not fail in this case.
724- print (f"Unable to collect setup.py dependencies securely: { setup_py_location } " )
759+ yield from reqs
0 commit comments