Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-dep-logic for
openSUSE:Factory checked in at 2026-08-21 17:01:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-dep-logic (Old)
and /work/SRC/openSUSE:Factory/.python-dep-logic.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dep-logic"
Fri Aug 21 17:01:16 2026 rev:10 rq:1372809 version:0.7.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-dep-logic/python-dep-logic.changes
2026-06-15 19:45:12.375845388 +0200
+++
/work/SRC/openSUSE:Factory/.python-dep-logic.new.1258/python-dep-logic.changes
2026-08-21 17:02:35.862763807 +0200
@@ -1,0 +2,10 @@
+Fri Aug 21 10:19:59 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.7.1:
+ * Return AnyMarker in EqualityMarkerUnion for complement case
+ and add corresponding test
+- update to 0.7.0:
+ * Update dependencies and improve type hints across the
+ codebase
+
+-------------------------------------------------------------------
Old:
----
dep_logic-0.6.0.tar.gz
New:
----
dep_logic-0.7.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-dep-logic.spec ++++++
--- /var/tmp/diff_new_pack.VOPr2X/_old 2026-08-21 17:02:36.755795425 +0200
+++ /var/tmp/diff_new_pack.VOPr2X/_new 2026-08-21 17:02:36.757795495 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-dep-logic
-Version: 0.6.0
+Version: 0.7.1
Release: 0
Summary: Python dependency specifications supporting logical operations
License: Apache-2.0
++++++ dep_logic-0.6.0.tar.gz -> dep_logic-0.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/PKG-INFO new/dep_logic-0.7.1/PKG-INFO
--- old/dep_logic-0.6.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/dep_logic-0.7.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +1,18 @@
Metadata-Version: 2.1
Name: dep-logic
-Version: 0.6.0
+Version: 0.7.1
Summary: Python dependency specifications supporting logical operations
Keywords: dependency,specification,logic,packaging
Author-Email: Frost Ming <[email protected]>
License: Apache-2.0
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: Apache Software License
-Requires-Python: >=3.9
+Requires-Python: >=3.10
Requires-Dist: packaging>=22
Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/pyproject.toml
new/dep_logic-0.7.1/pyproject.toml
--- old/dep_logic-0.6.0/pyproject.toml 2026-05-19 13:17:55.957042500 +0200
+++ new/dep_logic-0.7.1/pyproject.toml 2026-08-10 11:31:10.026974200 +0200
@@ -7,7 +7,7 @@
dependencies = [
"packaging>=22",
]
-requires-python = ">=3.9"
+requires-python = ">=3.10"
readme = "README.md"
dynamic = []
keywords = [
@@ -19,14 +19,13 @@
classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: Apache Software License",
]
-version = "0.6.0"
+version = "0.7.1"
[project.license]
text = "Apache-2.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/markers/__init__.py
new/dep_logic-0.7.1/src/dep_logic/markers/__init__.py
--- old/dep_logic-0.6.0/src/dep_logic/markers/__init__.py 2026-05-19
13:17:43.453691700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/markers/__init__.py 2026-08-10
11:30:59.525632900 +0200
@@ -20,14 +20,13 @@
from dep_logic.utils import get_reflect_op
if TYPE_CHECKING:
- from typing import List, Literal, Tuple, Union
+ from collections.abc import Sequence
+ from typing import Literal
from packaging.markers import Op, Value, Variable
- _ParsedMarker = Tuple[Variable, Op, Value]
- _ParsedMarkers = Union[
- _ParsedMarker, List[Union["_ParsedMarkers", Literal["or", "and"]]]
- ]
+ _ParsedMarker = tuple[Variable | Value, Op, Variable | Value]
+ _ParsedMarkers = _ParsedMarker | Sequence["_ParsedMarkers" | Literal["or",
"and"]]
__all__ = [
@@ -49,7 +48,7 @@
"""
[email protected]_cache(maxsize=None)
[email protected]
def parse_marker(marker: str) -> BaseMarker:
if marker == "<empty>":
return EmptyMarker()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/markers/multi.py
new/dep_logic-0.7.1/src/dep_logic/markers/multi.py
--- old/dep_logic-0.6.0/src/dep_logic/markers/multi.py 2026-05-19
13:17:43.453745400 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/markers/multi.py 2026-08-10
11:30:59.525668600 +0200
@@ -1,16 +1,16 @@
from __future__ import annotations
+from collections.abc import Iterator
from dataclasses import dataclass
-from typing import Iterator
from dep_logic.markers.any import AnyMarker
from dep_logic.markers.base import BaseMarker, EvaluationContext
from dep_logic.markers.empty import EmptyMarker
from dep_logic.markers.single import MarkerExpression, SingleMarker
-from dep_logic.utils import DATACLASS_ARGS, flatten_items, intersection, union
+from dep_logic.utils import flatten_items, intersection, union
-@dataclass(init=False, frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(init=False, frozen=True, unsafe_hash=True, slots=True, repr=False)
class MultiMarker(BaseMarker):
markers: tuple[BaseMarker, ...]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/markers/single.py
new/dep_logic-0.7.1/src/dep_logic/markers/single.py
--- old/dep_logic-0.6.0/src/dep_logic/markers/single.py 2026-05-19
13:17:43.453745400 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/markers/single.py 2026-08-10
11:30:59.525668600 +0200
@@ -16,7 +16,7 @@
from dep_logic.specifiers import BaseSpecifier
from dep_logic.specifiers.base import VersionSpecifier
from dep_logic.specifiers.generic import GenericSpecifier
-from dep_logic.utils import DATACLASS_ARGS, OrderedSet, get_reflect_op,
normalize_name
+from dep_logic.utils import OrderedSet, get_reflect_op, normalize_name
if t.TYPE_CHECKING:
from dep_logic.markers.multi import MultiMarker
@@ -24,7 +24,7 @@
PYTHON_VERSION_MARKERS = {"python_version", "python_full_version"}
MARKERS_ALLOWING_SET = {"extras", "dependency_groups"}
-Operator = t.Callable[[str, t.Union[str, t.Set[str]]], bool]
+Operator = t.Callable[[str, str | set[str]], bool]
_operators: dict[str, Operator] = {
"in": lambda lhs, rhs: lhs in rhs,
"not in": lambda lhs, rhs: lhs not in rhs,
@@ -85,7 +85,7 @@
raise NotImplementedError
-@dataclass(unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(unsafe_hash=True, slots=True, repr=False)
class MarkerExpression(SingleMarker):
name: str
op: str
@@ -108,7 +108,10 @@
if isinstance(specifier, VersionSpecifier):
if not specifier.is_simple():
return None
- pkg_spec = next(iter(specifier.to_specifierset()))
+ pkg_specs = specifier.to_specifierset()
+ if len(pkg_specs) != 1:
+ return None
+ pkg_spec = next(iter(pkg_specs))
pkg_version = pkg_spec.version
if (
dot_num := pkg_version.count(".")
@@ -211,7 +214,7 @@
return oper(lhs, rhs)
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class EqualityMarkerUnion(SingleMarker):
name: str
values: OrderedSet[str]
@@ -264,7 +267,7 @@
return replace(self, values=self.values | {other.value})
if other.op == "!=":
if other.value in self.values:
- AnyMarker()
+ return AnyMarker()
return other
if all(v in other.specifier for v in self.values):
return other
@@ -283,7 +286,7 @@
return environment[self.name] in self.values
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class InequalityMultiMarker(SingleMarker):
name: str
values: OrderedSet[str]
@@ -359,7 +362,7 @@
return environment[self.name] not in self.values
[email protected]_cache(maxsize=None)
[email protected]
def _merge_single_markers(
marker1: MarkerExpression,
marker2: MarkerExpression,
@@ -376,9 +379,8 @@
# "extra" is special because it can have multiple values at the same time.
# That's why we can only merge two "extra" markers if they have the same
value.
- if marker1.name == "extra":
- if marker1.value != marker2.value: # type: ignore[attr-defined]
- return None
+ if marker1.name == "extra" and marker1.value != marker2.value: # type:
ignore[attr-defined]
+ return None
try:
if merge_class is MultiMarker:
result_specifier = marker1.specifier & marker2.specifier
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/markers/union.py
new/dep_logic-0.7.1/src/dep_logic/markers/union.py
--- old/dep_logic-0.6.0/src/dep_logic/markers/union.py 2026-05-19
13:17:43.453745400 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/markers/union.py 2026-08-10
11:30:59.525668600 +0200
@@ -1,17 +1,17 @@
from __future__ import annotations
+from collections.abc import Iterator
from dataclasses import dataclass
-from typing import Iterator
from dep_logic.markers.any import AnyMarker
from dep_logic.markers.base import BaseMarker, EvaluationContext
from dep_logic.markers.empty import EmptyMarker
from dep_logic.markers.multi import MultiMarker
from dep_logic.markers.single import SingleMarker
-from dep_logic.utils import DATACLASS_ARGS, flatten_items, intersection, union
+from dep_logic.utils import flatten_items, intersection, union
-@dataclass(init=False, frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(init=False, frozen=True, unsafe_hash=True, slots=True, repr=False)
class MarkerUnion(BaseMarker):
markers: tuple[BaseMarker, ...]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/markers/utils.py
new/dep_logic-0.7.1/src/dep_logic/markers/utils.py
--- old/dep_logic-0.6.0/src/dep_logic/markers/utils.py 2026-05-19
13:17:43.453745400 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/markers/utils.py 2026-08-10
11:30:59.525668600 +0200
@@ -2,14 +2,16 @@
import functools
import itertools
-from typing import AbstractSet, Iterable, Iterator, TypeVar
+from collections.abc import Iterable, Iterator
+from collections.abc import Set as AbstractSet
+from typing import TypeVar
from dep_logic.markers.base import BaseMarker
T = TypeVar("T")
[email protected]_cache(maxsize=None)
[email protected]
def cnf(marker: BaseMarker) -> BaseMarker:
from dep_logic.markers.multi import MultiMarker
from dep_logic.markers.union import MarkerUnion
@@ -30,7 +32,7 @@
return marker
[email protected]_cache(maxsize=None)
[email protected]
def dnf(marker: BaseMarker) -> BaseMarker:
"""Transforms the marker into DNF (disjunctive normal form)."""
from dep_logic.markers.multi import MultiMarker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/specifiers/__init__.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/__init__.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/__init__.py 2026-05-19
13:17:43.453745400 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/__init__.py 2026-08-10
11:30:59.525668600 +0200
@@ -119,15 +119,15 @@
__all__ = [
- "from_specifierset",
- "parse_version_specifier",
- "VersionSpecifier",
- "EmptySpecifier",
"AnySpecifier",
- "RangeSpecifier",
- "UnionSpecifier",
+ "ArbitrarySpecifier",
"BaseSpecifier",
+ "EmptySpecifier",
"GenericSpecifier",
- "ArbitrarySpecifier",
"InvalidSpecifier",
+ "RangeSpecifier",
+ "UnionSpecifier",
+ "VersionSpecifier",
+ "from_specifierset",
+ "parse_version_specifier",
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/dep_logic-0.6.0/src/dep_logic/specifiers/arbitrary.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/arbitrary.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/arbitrary.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/arbitrary.py 2026-08-10
11:30:59.525967400 +0200
@@ -7,10 +7,9 @@
from dep_logic.specifiers.base import BaseSpecifier, UnparsedVersion,
VersionSpecifier
from dep_logic.specifiers.special import EmptySpecifier
-from dep_logic.utils import DATACLASS_ARGS
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class ArbitrarySpecifier(VersionSpecifier):
"""`===<version_string>` specifier."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/specifiers/base.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/base.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/base.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/base.py 2026-08-10
11:30:59.525967400 +0200
@@ -6,7 +6,7 @@
from packaging.specifiers import SpecifierSet
from packaging.version import Version
-UnparsedVersion = t.Union[Version, str]
+UnparsedVersion = Version | str
class InvalidSpecifier(ValueError):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/specifiers/generic.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/generic.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/generic.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/generic.py 2026-08-10
11:30:59.525967400 +0200
@@ -6,12 +6,11 @@
from dep_logic.specifiers.base import BaseSpecifier, InvalidSpecifier
from dep_logic.specifiers.special import AnySpecifier, EmptySpecifier
-from dep_logic.utils import DATACLASS_ARGS
Operator = t.Callable[[str, str], bool]
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class GenericSpecifier(BaseSpecifier):
op: str
value: str
@@ -86,11 +85,11 @@
if this.value == that.value:
return AnySpecifier()
return that
- elif this.op == "!=" and that.op == "!=":
- return AnySpecifier()
- elif this.op == "in" and that.op == "not in" and this.value ==
that.value:
- return AnySpecifier()
- elif this.op == "!=" and that.op == "in" and this.value in that.value:
+ elif (
+ (this.op == "!=" and that.op == "!=")
+ or (this.op == "in" and that.op == "not in" and this.value ==
that.value)
+ or (this.op == "!=" and that.op == "in" and this.value in
that.value)
+ ):
return AnySpecifier()
elif this.op == "!=" and that.op == "not in":
if this.value in that.value:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/specifiers/range.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/range.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/range.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/range.py 2026-08-10
11:30:59.525967400 +0200
@@ -14,10 +14,10 @@
VersionSpecifier,
)
from dep_logic.specifiers.special import EmptySpecifier
-from dep_logic.utils import DATACLASS_ARGS, first_different_index, pad_zeros
+from dep_logic.utils import first_different_index, pad_zeros
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class RangeSpecifier(VersionSpecifier):
min: Version | None = None
max: Version | None = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/specifiers/union.py
new/dep_logic-0.7.1/src/dep_logic/specifiers/union.py
--- old/dep_logic-0.6.0/src/dep_logic/specifiers/union.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/specifiers/union.py 2026-08-10
11:30:59.525967400 +0200
@@ -10,10 +10,10 @@
from dep_logic.specifiers.base import BaseSpecifier, UnparsedVersion,
VersionSpecifier
from dep_logic.specifiers.range import RangeSpecifier
from dep_logic.specifiers.special import EmptySpecifier
-from dep_logic.utils import DATACLASS_ARGS, first_different_index, pad_zeros
+from dep_logic.utils import first_different_index, pad_zeros
-@dataclass(frozen=True, unsafe_hash=True, **DATACLASS_ARGS)
+@dataclass(frozen=True, unsafe_hash=True, slots=True, repr=False)
class UnionSpecifier(VersionSpecifier):
ranges: tuple[RangeSpecifier, ...]
simplified: str | None = field(default=None, compare=False, hash=False)
@@ -31,23 +31,32 @@
def _simplified_form(self) -> str | None:
if self.simplified is not None:
return self.simplified
+
# try to get a not-equals form(!=) if possible
left, right, *rest = self.ranges
if rest:
return None
+
+ def with_outer_bounds(exclusion: str) -> str:
+ parts: list[str] = []
+ if left.min is not None:
+ parts.append(f"{'>=' if left.include_min else '>'}{left.min}")
+ parts.append(exclusion)
+ if right.max is not None:
+ parts.append(f"{'<=' if right.include_max else
'<'}{right.max}")
+ return ",".join(parts)
+
if (
- left.min is None
- and right.max is None
- and left.max == right.min
+ left.max == right.min
and left.max is not None
+ and not left.include_max
+ and not right.include_min
):
- # (-inf, version) | (version, inf) => != version
- return f"!={left.max}"
+ # [lower, version) | (version, upper] => lower, != version, upper
+ return with_outer_bounds(f"!={left.max}")
if (
- left.min is None
- and right.max is None
- and not left.include_max
+ not left.include_max
and right.include_min
and left.max is not None
and right.min is not None
@@ -72,7 +81,7 @@
):
epoch = "" if left.max.epoch == 0 else f"{left.max.epoch}!"
version = ".".join(map(str,
left.max.release[:first_different])) + ".*"
- return f"!={epoch}{version}"
+ return with_outer_bounds(f"!={epoch}{version}")
return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/tags/__init__.py
new/dep_logic-0.7.1/src/dep_logic/tags/__init__.py
--- old/dep_logic-0.6.0/src/dep_logic/tags/__init__.py 2026-05-19
13:17:43.454097700 +0200
+++ new/dep_logic-0.7.1/src/dep_logic/tags/__init__.py 2026-08-10
11:30:59.525967400 +0200
@@ -9,12 +9,12 @@
)
__all__ = [
+ "EnvCompatibility",
+ "EnvSpec",
+ "Implementation",
+ "InvalidWheelFilename",
"Platform",
"PlatformError",
"TagsError",
"UnsupportedImplementation",
- "InvalidWheelFilename",
- "EnvSpec",
- "Implementation",
- "EnvCompatibility",
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/src/dep_logic/utils.py
new/dep_logic-0.7.1/src/dep_logic/utils.py
--- old/dep_logic-0.6.0/src/dep_logic/utils.py 2026-05-19 13:17:43.454399600
+0200
+++ new/dep_logic-0.7.1/src/dep_logic/utils.py 2026-08-10 11:30:59.526165000
+0200
@@ -3,31 +3,20 @@
import functools
import itertools
import re
-import sys
-from typing import TYPE_CHECKING, AbstractSet, Iterable, Iterator, Protocol,
TypeVar
+from collections.abc import Iterable, Iterator
+from collections.abc import Set as AbstractSet
+from typing import TYPE_CHECKING, Protocol, TypeVar
_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
if TYPE_CHECKING:
- from typing import TypedDict
-
from dep_logic.markers.base import BaseMarker
- class _DataClassArgs(TypedDict, total=False):
- slots: bool
- repr: bool
-
-
-if sys.version_info >= (3, 10):
- DATACLASS_ARGS: _DataClassArgs = {"slots": True, "repr": False}
-else:
- DATACLASS_ARGS = {"repr": False}
-
class Ident(Protocol):
def __hash__(self) -> int: ...
- def __eq__(self, __value: object) -> bool: ...
+ def __eq__(self, __value: object, /) -> bool: ...
T = TypeVar("T", bound=Ident)
@@ -79,7 +68,7 @@
return parts + [0] * (to_length - len(parts))
[email protected]_cache(maxsize=None)
[email protected]
def cnf(marker: BaseMarker) -> BaseMarker:
from dep_logic.markers.multi import MultiMarker
from dep_logic.markers.union import MarkerUnion
@@ -100,7 +89,7 @@
return marker
[email protected]_cache(maxsize=None)
[email protected]
def dnf(marker: BaseMarker) -> BaseMarker:
"""Transforms the marker into DNF (disjunctive normal form)."""
from dep_logic.markers.multi import MultiMarker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/tests/marker/test_compound.py
new/dep_logic-0.7.1/tests/marker/test_compound.py
--- old/dep_logic-0.6.0/tests/marker/test_compound.py 2026-05-19
13:17:43.454690700 +0200
+++ new/dep_logic-0.7.1/tests/marker/test_compound.py 2026-08-10
11:30:59.526422000 +0200
@@ -55,6 +55,15 @@
assert m2 & m1.is_any()
+def test_equality_marker_union_with_complement_is_any() -> None:
+ marker = parse_marker('os_name == "a" or os_name == "b" or os_name != "a"')
+
+ assert marker.is_any()
+ assert marker.evaluate({"os_name": "a"})
+ assert marker.evaluate({"os_name": "b"})
+ assert marker.evaluate({"os_name": "c"})
+
+
def test_multi_marker_intersect_multi() -> None:
m = parse_marker('sys_platform == "darwin" and implementation_name ==
"cpython"')
@@ -354,8 +363,7 @@
intersection = m & m2
expected = (
- 'python_version >= "2.7" and python_version < "2.8" '
- 'or python_version ~= "3.4"'
+ 'python_version >= "2.7" and python_version < "2.8" or python_version
~= "3.4"'
)
assert str(intersection) == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/tests/specifier/test_range.py
new/dep_logic-0.7.1/tests/specifier/test_range.py
--- old/dep_logic-0.6.0/tests/specifier/test_range.py 2026-05-19
13:17:43.454963700 +0200
+++ new/dep_logic-0.7.1/tests/specifier/test_range.py 2026-08-10
11:30:59.526664500 +0200
@@ -97,7 +97,6 @@
(RangeSpecifier(min=Version("1.0")), ">1.0"),
(RangeSpecifier(min=Version("1.0"), include_min=True), ">=1.0"),
(RangeSpecifier(max=Version("1.0")), "<1.0"),
- (RangeSpecifier(max=Version("1.0")), "<1.0"),
(
RangeSpecifier(
min=Version("1.0"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.6.0/tests/specifier/test_union.py
new/dep_logic-0.7.1/tests/specifier/test_union.py
--- old/dep_logic-0.6.0/tests/specifier/test_union.py 2026-05-19
13:17:43.454963700 +0200
+++ new/dep_logic-0.7.1/tests/specifier/test_union.py 2026-08-10
11:30:59.526664500 +0200
@@ -1,4 +1,5 @@
import pytest
+from packaging.specifiers import SpecifierSet
from packaging.version import Version
from dep_logic.specifiers import (
@@ -39,6 +40,23 @@
@pytest.mark.parametrize(
+ "spec,expected",
+ [
+ (">=3,<4||>4", ">=3,!=4"),
+ (">=3,<4||>4,<5", ">=3,!=4,<5"),
+ ("<4||>4,<5", "!=4,<5"),
+ (">=1,<2.0||>=3.0", ">=1,!=2.*"),
+ ],
+)
+def test_simplify_union_with_outer_bounds(spec: str, expected: str) -> None:
+ value = parse_version_specifier(spec)
+ assert isinstance(value, UnionSpecifier)
+ assert value.is_simple()
+ assert str(value) == expected
+ assert value.to_specifierset() == SpecifierSet(expected)
+
+
[email protected](
"spec,parsed",
[
(
@@ -72,7 +90,7 @@
@pytest.mark.parametrize(
"a,b,expected",
[
- ("!=2.0", ">=1.0", "~=1.0||>2.0"),
+ ("!=2.0", ">=1.0", ">=1.0,!=2.0"),
("!=2.0", ">=2.0", ">2.0"),
("~=2.7||>=3.6", "==3.3", "<empty>"),
("~=2.7||>=3.6", "<3.0", "~=2.7"),