diff --git a/src/python_inspector/dependencies.py b/src/python_inspector/dependencies.py index 0c491304..d16d64fb 100644 --- a/src/python_inspector/dependencies.py +++ b/src/python_inspector/dependencies.py @@ -54,7 +54,12 @@ def get_extra_data_from_requirements(requirements_file="requirements.txt") -> It def is_requirement_pinned(requirement: Requirement) -> bool: specifiers = requirement.specifier - return specifiers and len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="} + if len(specifiers) != 1: + return False + specifier = next(iter(specifiers)) + return specifier.operator == "===" or ( + specifier.operator == "==" and not specifier.version.endswith(".*") + ) def get_dependency(specifier) -> DependentPackage: diff --git a/tests/test_requirement_pins.py b/tests/test_requirement_pins.py new file mode 100644 index 00000000..1d76de8e --- /dev/null +++ b/tests/test_requirement_pins.py @@ -0,0 +1,30 @@ +# Copyright (c) nexB Inc. and others. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# See https://github.com/aboutcode-org/python-inspector for support or download. + +import pytest + +from packvers.requirements import Requirement +from python_inspector.dependencies import get_dependency +from python_inspector.dependencies import is_requirement_pinned + + +@pytest.mark.parametrize( + "text,expected", + [ + ("demo", False), + ("demo==1.2.*", False), + ("demo>=1", False), + ("demo==1.2", True), + ("demo===1.2", True), + ("demo===1.2.*", True), + ], +) +def test_requirement_pins(text, expected): + assert is_requirement_pinned(Requirement(text)) is expected + + +def test_wildcard_dependency_has_no_exact_version(): + dependency = get_dependency("demo==1.2.*") + assert dependency.purl == "pkg:pypi/demo" + assert dependency.is_resolved is False