Fix `is_pinned` property of `Requirement` (#81812)

Previously, requirement version specs starting with `!=` were
incorrectly considered as pinned release requests because the
comparison was being made against a one-char string while the
operator is two-char. This patch changes the check to test against `!`
which is enough to detect this case.
pull/84689/head
🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) 10 months ago committed by GitHub
parent 333ee8d010
commit cdb1ce000a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,8 @@
---
bugfixes:
- >-
``ansible-galaxy`` — the collection dependency resolver now treats
version specifiers starting with ``!=`` as unpinned.
...

@ -578,10 +578,9 @@ class _ComputedReqKindsMixin:
See https://github.com/ansible/ansible/pull/81606 for extra context.
"""
version_string = self.ver[0]
return version_string.isdigit() or not (
version_string == '*' or
version_string.startswith(('<', '>', '!='))
version_spec_start_char = self.ver[0]
return version_spec_start_char.isdigit() or not (
version_spec_start_char.startswith(('<', '>', '!', '*'))
)
@property

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2023, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""Tests for depresolver dataclass objects."""
from __future__ import annotations
import pytest
from ansible.galaxy.dependency_resolution.dataclasses import Requirement
NO_LEADING_WHITESPACES = pytest.mark.xfail(
reason='Does not yet support leading whitespaces',
strict=True,
)
@pytest.mark.parametrize(
('collection_version_spec', 'expected_is_pinned_outcome'),
(
('1.2.3-dev4', True),
(' 1.2.3-dev4', True),
('=1.2.3', True),
('= 1.2.3', True),
(' = 1.2.3', True),
(' =1.2.3', True),
('==1.2.3', True),
('== 1.2.3', True),
(' == 1.2.3', True),
(' ==1.2.3', True),
('!=1.0.0', False),
('!= 1.0.0', False),
pytest.param(' != 1.0.0', False, marks=NO_LEADING_WHITESPACES),
pytest.param(' !=1.0.0', False, marks=NO_LEADING_WHITESPACES),
('>1.0.0', False),
('> 1.0.0', False),
pytest.param(' > 1.0.0', False, marks=NO_LEADING_WHITESPACES),
pytest.param(' >1.0.0', False, marks=NO_LEADING_WHITESPACES),
('>=1.0.0', False),
('>= 1.0.0', False),
pytest.param(' >= 1.0.0', False, marks=NO_LEADING_WHITESPACES),
pytest.param(' >=1.0.0', False, marks=NO_LEADING_WHITESPACES),
('<1.0.0', False),
('< 1.0.0', False),
pytest.param(' < 1.0.0', False, marks=NO_LEADING_WHITESPACES),
pytest.param(' <1.0.0', False, marks=NO_LEADING_WHITESPACES),
('*', False),
('* ', False),
pytest.param(' * ', False, marks=NO_LEADING_WHITESPACES),
pytest.param(' *', False, marks=NO_LEADING_WHITESPACES),
('=1.2.3,!=1.2.3rc5', True),
),
)
def test_requirement_is_pinned_logic(
collection_version_spec: str,
expected_is_pinned_outcome: bool,
) -> None:
"""Test how Requirement's is_pinned property detects pinned spec."""
assert Requirement(
'namespace.collection', collection_version_spec,
None, None, None,
).is_pinned is expected_is_pinned_outcome
Loading…
Cancel
Save