lib.version.Dependency.__version_boundaries(): Expand non-full specs

Full version dependency specs ("= 1.2.3-4" or "= VERSION-REVISION") don't
need expansion, they pin the wanted version with an = fine exactly.

__version_boundary has that the wrong way around, fix that.

Also fix the is_full and version_boundaries() docstrings, which still
describe the old behavior.

Tests written by AI.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1
Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-09-15 19:57:47 +02:00
commit a5885283d0
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61
3 changed files with 15 additions and 20 deletions

View file

@ -70,7 +70,7 @@ class Dependency: # export
specified = self.__parsed_spec[1]
if specified is None:
return []
if not expanded or not specified.version.is_full:
if not expanded or specified.version.is_full:
return (specified, )
ret: list[Boundary] = []
match specified.op:
@ -132,7 +132,7 @@ class Dependency: # export
def version_boundaries(self, expanded: bool = False) -> Sequence[Boundary]:
"""The parsed version boundary, or the range it spans when
expanded is True and it pins a full version.
expanded is True and it does not pin a full version.
"""
return self.__version_boundaries(expanded)

View file

@ -141,9 +141,8 @@ class Version: # export
def is_full(self) -> bool:
"""True if the spec pins a complete version: the
VERSION-REVISION macro, or a literal of the form
MAJOR.MINOR.MICRO-REVISION. Only full versions have the
exclusive upper bound (next_binary_incompatible) that range
expansion relies on.
MAJOR.MINOR.MICRO-REVISION. Range expansion leaves full
versions exact and expands the non-full specs.
"""
if self.__spec == 'VERSION-REVISION':
return True

View file

@ -109,32 +109,28 @@ assert d.constraint_str() == 'foo = 1.2.3'
assert d.constraint_str() == 'foo = 1.2.3'
assert calls == ['foo']
# as_range expands full boundaries into a revision range
# as_range expands a non-full boundary into the range it spans
d = Dependency('foo = VERSION-REVISION', app.get_version)
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3-45 foo < 1.2.4'
assert d.constraint_str(as_range = True) == 'foo = 1.2.3-45'
d = Dependency('foo >= VERSION-REVISION', app.get_version)
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3-45 foo < 1.2.4'
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3-45'
d = Dependency('foo > 1.0.0-259', app.get_version)
assert d.constraint_str(as_range = True) == 'foo > 1.0.0-259 foo < 1.0.1'
# A raw render keeps the macro, with the computed bound alongside it
assert d.constraint_str(as_range = True) == 'foo > 1.0.0-259'
# A raw render keeps the macro as written
d = Dependency('foo = VERSION-REVISION', app.get_version)
constraint = d.constraint_str(untemplated = False, as_range = True)
assert constraint == 'foo >= VERSION-REVISION foo < 1.2.4'
# VERSION is not full, so a VERSION constraint is not expanded
assert constraint == 'foo = VERSION-REVISION'
# A full version stays exact; a non-full one expands
d = Dependency('foo = VERSION', app.get_version)
assert d.constraint_str(as_range = True) == 'foo = 1.2.3'
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3 foo < 1.2.4'
d = Dependency('foo >= VERSION', app.get_version)
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3'
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3 foo < 1.2.4'
# '<' and '<=' are not expanded
d = Dependency('foo <= VERSION', app.get_version)
assert d.constraint_str(as_range = True) == 'foo <= 1.2.3'
# versions without a full major.minor.micro-revision are not expanded
d = Dependency('foo = 1.0', app.get_version)
assert d.constraint_str(as_range = True) == 'foo = 1.0'
# The bound steps a micro, so a tripartite core expands
d = Dependency('foo = 1.2.3', app.get_version)
assert d.constraint_str(as_range = True) == 'foo = 1.2.3'
d = Dependency('foo = 1.0-rc1', app.get_version)
assert d.constraint_str(as_range = True) == 'foo = 1.0-rc1'
assert d.constraint_str(as_range = True) == 'foo >= 1.2.3 foo < 1.2.4'
# Default syntax is SEM_VER
d = Dependency('foo < 2.0')
assert d.constraint_str(untemplated = False) == 'foo < 2.0'