diff --git a/src/python_inspector/resolution.py b/src/python_inspector/resolution.py index 14529dea..fb67aa94 100644 --- a/src/python_inspector/resolution.py +++ b/src/python_inspector/resolution.py @@ -313,6 +313,7 @@ def get_resolved_dependencies( environment: utils_pypi.Environment = None, repos: Sequence[utils_pypi.PypiSimpleRepository] = tuple(), as_tree: bool = False, + max_rounds: int = 200000, ): """ Return resolved dependencies of a ``requirements`` list of Requirement for @@ -326,6 +327,6 @@ def get_resolved_dependencies( provider=PythonInputProvider(environment=environment, repos=repos), reporter=BaseReporter(), ) - results = resolver.resolve(requirements=requirements) + results = resolver.resolve(requirements=requirements, max_rounds=max_rounds) results = format_resolution(results, as_tree=as_tree) return results diff --git a/src/python_inspector/resolve_cli.py b/src/python_inspector/resolve_cli.py index b2c527a8..502c844c 100644 --- a/src/python_inspector/resolve_cli.py +++ b/src/python_inspector/resolve_cli.py @@ -101,6 +101,13 @@ help="Write output as pretty-printed JSON to FILE. " "Use the special '-' file name to print results on screen/stdout.", ) +@click.option( + "--max-rounds", + "max_rounds", + type=int, + default=200000, + help="Increase the max rounds whenever the resolution is too deep", +) @click.option( "--use-cached-index", is_flag=True, @@ -128,6 +135,7 @@ def resolve_dependencies( operating_system, index_urls, json_output, + max_rounds, use_cached_index=False, use_pypi_json_api=False, debug=TRACE, @@ -220,6 +228,7 @@ def resolve_dependencies( environment=environment, repos=repos, as_tree=False, + max_rounds=max_rounds, ) cli_options = [f"--requirement {rf}" for rf in requirement_files] @@ -256,7 +265,7 @@ def resolve_dependencies( click.secho("done!") -def resolve(direct_dependencies, environment, repos=tuple(), as_tree=False): +def resolve(direct_dependencies, environment, repos=tuple(), as_tree=False, max_rounds=200000): """ Resolve dependencies given a ``direct_dependencies`` list of DependentPackage and return a tuple of (initial_requirements, @@ -273,6 +282,7 @@ def resolve(direct_dependencies, environment, repos=tuple(), as_tree=False): environment=environment, repos=repos, as_tree=as_tree, + max_rounds=max_rounds, ) initial_requirements = [d.to_dict() for d in direct_dependencies] diff --git a/tests/test_cli.py b/tests/test_cli.py index 65c056f8..753fa5b1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -74,6 +74,26 @@ def test_cli_with_multiple_index_url_and_tilde_req(): ) +@pytest.mark.online +def test_cli_with_multiple_index_url_and_tilde_req_with_max_rounds(): + expected_file = test_env.get_test_loc("tilde_req-expected.json", must_exist=False) + specifier = "zipp~=3.8.0" + extra_options = [ + "--index-url", + "https://pypi.org/simple", + "--index-url", + "https://thirdparty.aboutcode.org/pypi/simple/", + "--max-rounds", + "100", + ] + check_specs_resolution( + specifier=specifier, + expected_file=expected_file, + extra_options=extra_options, + regen=REGEN_TEST_FIXTURES, + ) + + @pytest.mark.online def test_cli_with_multiple_index_url_and_tilde_req_and_netrc_file_without_matching_url(): expected_file = test_env.get_test_loc("tilde_req-expected.json", must_exist=False) diff --git a/tests/test_resolution.py b/tests/test_resolution.py index c8e8b94e..6b014072 100644 --- a/tests/test_resolution.py +++ b/tests/test_resolution.py @@ -82,7 +82,7 @@ def test_get_resolved_dependencies_with_flask_and_python_36(): assert as_list == [ "pkg:pypi/click@8.1.3", "pkg:pypi/flask@2.1.2", - "pkg:pypi/importlib-metadata@4.11.4", + "pkg:pypi/importlib-metadata@4.12.0", "pkg:pypi/itsdangerous@2.1.2", "pkg:pypi/jinja2@3.1.2", "pkg:pypi/markupsafe@2.0.1", @@ -107,7 +107,7 @@ def test_get_resolved_dependencies_with_tilde_requirement_using_json_api(): assert as_list == [ "pkg:pypi/click@8.1.3", "pkg:pypi/flask@2.1.2", - "pkg:pypi/importlib-metadata@4.11.4", + "pkg:pypi/importlib-metadata@4.12.0", "pkg:pypi/itsdangerous@2.1.2", "pkg:pypi/jinja2@3.1.2", "pkg:pypi/markupsafe@2.1.1",