Compare commits

...
Author SHA1 Message Date
c31dfb4bbf
lib.version.Dependency: Reject unsupported spec operators
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m27s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m54s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m0s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m17s
CI / Packaging test (push) Successful in 0s
The spec split pattern ([=><]+) tokenizes only the =, > and < characters,
so a PEP 440 operator like ~= or != leaves its ~ or ! glued to the package
name: Dependency('pkg~=1.0') parses to base name 'pkg~' with operator '='.
App.__get_project_refs() carries the same pattern inline, so the same specs
corrupt the module name used for the -devel subpackage check. The split
also tolerates operator strings the language does not support, most visibly
==, which parses and renders but raises NotImplementedError only when
expansion is requested.

The spec language supports exactly =, <, <=, > and >=, and boundary
expansion implements all of them. Extend the split pattern with ~ and ! so
that foreign operators tokenize as operator strings, and reject every
operator outside the supported set in Dependency.__parsed_spec() with
Dependency.Error, naming the supported operators. Route
App.__get_project_refs() through Dependency for the name and module parts
instead of the second inline split, so the validation lives in one place.
The catch all in Dependency.__version_boundaries() stays as a backstop
against drift between the allow list and the expansion cases.

The tests drop == from the accepted operator loop, drop the now-unreachable
not-expandable case, and assert that ~=, !=, ~, ==, ===, << and >> are
rejected at parse time with a message naming the operator.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-09-11 11:22:33 +02:00
d5e09fca91
Release 1.0.0-262@suse-tumbleweed/x86_64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 4m25s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m38s
CI / Packaging test (push) Successful in 0s
2026-09-10 23:32:02 +00:00
150f9f1bbc
Release 1.0.0-262@kali-rolling/amd64
All checks were successful
CI / Packaging - Kali Linux (push) Successful in 4m11s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m37s
CI / Packaging test (push) Successful in 0s
Signed-off-by: janware DevOps <devops@janware.com>
2026-09-10 23:12:01 +00:00
225b4ec456
Start version: 1.0.0-262
Signed-off-by: janware DevOps <devops@janware.com>
2026-09-10 23:10:51 +00:00
6 changed files with 36 additions and 17 deletions

4
HASH
View file

@ -1,4 +1,4 @@
suse-tumbleweed/x86_64: 0ac23bf5e3b8c21775911bc8d7afc9c9
suse-tumbleweed/x86_64: 6d39e6eb74af4b013e5b98175aea29ae
suse-tumbleweed/i586: 86ea923ca3861900dd03d4b1da44f8b6
debian-10/amd64: 47167eb2d7fe2d845a1b12e0702a6e9b
suse-42.3/x86_64: bd0e29fda82e38c89d2ed6f11797ce3a
@ -7,4 +7,4 @@ debian-8/amd64: b16e55fee0967a75aa67a4d859f0455d
ubuntu-18.04/amd64: 190b5c45953399fd93354db0621d6f5f
debian-10/armhf: 5d92c234d483deaf44c80cad168a8d5d
debian-2025.4/amd64: 977965179baa6fd24d0975a05d583eb6
kali-rolling/amd64: e76880f8ee0608d4220eb77e0abddc62
kali-rolling/amd64: 6d39e6eb74af4b013e5b98175aea29ae

View file

@ -1,4 +1,4 @@
suse-tumbleweed/x86_64: 1.0.0-260
suse-tumbleweed/x86_64: 1.0.0-262
suse-tumbleweed/i586: 1.0.0-44
debian-10/amd64: 1.0.0-47
suse-42.3/x86_64: 1.0.0-48
@ -7,4 +7,4 @@ debian-8/amd64: 1.0.0-84
ubuntu-18.04/amd64: 1.0.0-99
debian-10/armhf: 1.0.0-102
debian-2025.4/amd64: 1.0.0-172
kali-rolling/amd64: 1.0.0-261
kali-rolling/amd64: 1.0.0-262

View file

@ -1 +1 @@
1.0.0-261-dev
1.0.0-262-dev

View file

@ -209,8 +209,9 @@ class App(Base):
scope: Scope,
names_only: bool,
) -> None:
name = self.strip_module_from_spec(spec)
mod = re.split('([=><]+)', spec)[0].strip()
dep = Dependency(spec)
name = dep.base_name
mod = dep.full_name
if names_only:
spec = name
if spec in buf:

View file

@ -22,7 +22,7 @@ class Dependency: # export
class Error(ValueError):
pass
__SPLIT_RE: ClassVar[re.Pattern[str]] = re.compile('([=><]+)')
__SPLIT_RE: ClassVar[re.Pattern[str]] = re.compile('([~=><!]+)')
@property
def __target_prefix(self) -> str:
@ -45,6 +45,12 @@ class Dependency: # export
case 3:
if not parts[0] or not parts[2]:
self.__raise(f'Invalid dependency spec "{self.__spec}"')
if parts[1] not in ('=', '<', '<=', '>', '>='):
self.__raise(
f'Spec "{self.__spec}": unsupported operator '
f'"{parts[1]}", supported operators are =, <, '
'<=, > and >='
)
if parts[2] == 'REVISION':
self.__raise(
f'Spec "{self.__spec}": a bare REVISION renders as a '

View file

@ -40,7 +40,7 @@ assert d.base_name == 'dev'
assert d.full_name == 'dev'
# Operators with and without whitespace
for op in ['=', '==', '<', '<=', '>', '>=']:
for op in ['=', '<', '<=', '>', '>=']:
d = Dependency(f'foo {op} 1.0')
assert d.base_name == 'foo'
assert d.full_name == 'foo'
@ -135,14 +135,6 @@ 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'
# unimplemented operators raise
d = Dependency('foo == 1.2.3-45', app.get_version)
try:
d.constraint_str(as_range = True)
assert False, 'Should have raised'
except NotImplementedError:
pass
# Default syntax is SEM_VER
d = Dependency('foo < 2.0')
assert d.constraint_str(untemplated = False) == 'foo < 2.0'
@ -238,6 +230,26 @@ for bad in ['', 'foo =', ' = 1.0']:
except Dependency.Error:
pass
# Operators outside the supported set are rejected when parsed,
# not folded into the package name or deferred to expansion
for bad in [
'foo ~= 1.0',
'foo~=1.0',
'foo ~ 1.0',
'foo != 1.0',
'foo!=1.0',
'foo == 1.0',
'foo==1.0',
'foo === 1.0',
'foo << 1.0',
'foo >> 1.0',
]:
try:
Dependency(bad).full_name
assert False, f'Should have raised for {bad!r}'
except Dependency.Error as e:
assert 'unsupported operator' in str(e)
# str
assert str(Dependency('foo-devel >= 1.0')) == 'foo-devel >= 1.0'
assert str(Dependency('foo')) == 'foo'