Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-cssutils for openSUSE:Factory
checked in at 2026-05-20 15:24:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cssutils (Old)
and /work/SRC/openSUSE:Factory/.python-cssutils.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cssutils"
Wed May 20 15:24:03 2026 rev:41 rq:1354063 version:2.15.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cssutils/python-cssutils.changes
2026-04-26 21:15:31.471737914 +0200
+++
/work/SRC/openSUSE:Factory/.python-cssutils.new.1966/python-cssutils.changes
2026-05-20 15:24:47.026788411 +0200
@@ -1,0 +2,17 @@
+Tue May 19 15:57:42 UTC 2026 - Dirk Müller <[email protected]>
+
+- enable tests
+
+-------------------------------------------------------------------
+Fri May 8 10:29:27 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to 2.15.0
+ * Added support for Selectors Level 4 pseudo-classes that accept
+ full selector lists as arguments (:has(), :is(), :where(),
+ :matches(), :any()). (#66)
+ * Fixed pseudo-class specificity calculation. Pseudo-classes (e.g.
+ ``:hover``, ``:last-child``, ``:nth-child()``) now correctly
+ contribute to the class-weight column per the CSS Selectors spec.
+ (#76)
+
+-------------------------------------------------------------------
Old:
----
cssutils-2.14.0.tar.gz
New:
----
cssutils-2.15.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-cssutils.spec ++++++
--- /var/tmp/diff_new_pack.rDSoMU/_old 2026-05-20 15:24:47.610812476 +0200
+++ /var/tmp/diff_new_pack.rDSoMU/_new 2026-05-20 15:24:47.614812642 +0200
@@ -19,7 +19,7 @@
%bcond_without libalternatives
%{?sle15_python_module_pythons}
Name: python-cssutils
-Version: 2.14.0
+Version: 2.15.0
Release: 0
Summary: A CSS Cascading Style Sheets library for Python
License: LGPL-3.0-or-later
@@ -29,8 +29,10 @@
Source1: %{name}.rpmlintrc
BuildRequires: %{python_module base >= 3.10}
BuildRequires: %{python_module encutils}
+BuildRequires: %{python_module jaraco.test}
BuildRequires: %{python_module more-itertools}
BuildRequires: %{python_module pip}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools >= 77}
BuildRequires: %{python_module setuptools_scm >= 3.4.1}
BuildRequires: %{python_module wheel}
@@ -52,6 +54,9 @@
%build
%pyproject_wheel
+%check
+%pytest tests/
+
%install
%pyproject_install
%python_clone -a %{buildroot}%{_bindir}/csscapture
++++++ cssutils-2.14.0.tar.gz -> cssutils-2.15.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/.github/workflows/main.yml
new/cssutils-2.15.0/.github/workflows/main.yml
--- old/cssutils-2.14.0/.github/workflows/main.yml 2026-04-20
01:50:57.000000000 +0200
+++ new/cssutils-2.15.0/.github/workflows/main.yml 2026-04-27
22:40:10.000000000 +0200
@@ -35,7 +35,8 @@
matrix:
python:
- "3.10"
- - "3.13"
+ - "3.14"
+ - "3.14t"
platform:
- ubuntu-latest
- macos-latest
@@ -45,7 +46,9 @@
platform: ubuntu-latest
- python: "3.12"
platform: ubuntu-latest
- - python: "3.14"
+ - python: "3.13"
+ platform: ubuntu-latest
+ - python: "3.13t"
platform: ubuntu-latest
- python: "3.15"
platform: ubuntu-latest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/AGENTS.md
new/cssutils-2.15.0/AGENTS.md
--- old/cssutils-2.14.0/AGENTS.md 1970-01-01 01:00:00.000000000 +0100
+++ new/cssutils-2.15.0/AGENTS.md 2026-04-27 22:40:10.000000000 +0200
@@ -0,0 +1 @@
+This project follows the [skeleton](https://blog.jaraco.com/skeleton); please
read for context on development.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/NEWS.rst new/cssutils-2.15.0/NEWS.rst
--- old/cssutils-2.14.0/NEWS.rst 2026-04-20 01:50:57.000000000 +0200
+++ new/cssutils-2.15.0/NEWS.rst 2026-04-27 22:40:10.000000000 +0200
@@ -1,3 +1,13 @@
+v2.15.0
+=======
+
+Features
+--------
+
+- Added support for Selectors Level 4 pseudo-classes that accept full selector
lists as arguments (:has(), :is(), :where(), :matches(), :any()). (#66)
+- Fixed pseudo-class specificity calculation. Pseudo-classes (e.g. ``:hover``,
``:last-child``, ``:nth-child()``) now correctly contribute to the class-weight
column per the CSS Selectors spec. (#76)
+
+
v2.14.0
=======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/PKG-INFO new/cssutils-2.15.0/PKG-INFO
--- old/cssutils-2.14.0/PKG-INFO 2026-04-20 01:51:13.550748300 +0200
+++ new/cssutils-2.15.0/PKG-INFO 2026-04-27 22:40:30.873777000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: cssutils
-Version: 2.14.0
+Version: 2.15.0
Summary: A CSS Cascading Style Sheets library for Python
Author-email: Christof Hoeke <[email protected]>
Maintainer-email: "Jason R. Coombs" <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/cssutils/css/selector.py
new/cssutils-2.15.0/cssutils/css/selector.py
--- old/cssutils-2.14.0/cssutils/css/selector.py 2026-04-20
01:50:57.000000000 +0200
+++ new/cssutils-2.15.0/cssutils/css/selector.py 2026-04-27
22:40:10.000000000 +0200
@@ -46,6 +46,14 @@
combinator = ' combinator'
+ # Selectors Level 4 pseudo-classes that accept a full selector list
+ # as their argument (rather than a simple expression like an+b).
+ selector_pseudos = frozenset([':has(', ':is(', ':where(', ':matches(',
':any('])
+
+ # CSS4 pseudo-elements whose argument is a selector (not an expression).
+ # These push a 'pseudo-element' context and accept
simple_selector_sequence.
+ selector_pseudo_elements = frozenset(['::slotted(', '::cue(',
'::cue-region('])
+
@dataclasses.dataclass
class New(cssutils.util._BaseClass):
@@ -132,7 +140,7 @@
if not context or context == 'negation':
if 'id' == typ:
self.specificity[1] += 1
- elif 'class' == typ or '[' == val:
+ elif 'class' == typ or '[' == val or 'pseudo-class' == typ:
self.specificity[2] += 1
elif typ in (
'type-selector',
@@ -154,7 +162,12 @@
def _S(self, expected, seq, token, tokenizer=None):
# S
context = self.context[-1]
- if context.startswith('pseudo-'):
+ if context == 'pseudo-class-has' and 'combinator' in expected:
+ # space is a descendant combinator inside :has(), :is(), etc.
+ self.append(seq, Constants.S, 'descendant', token=token)
+ return Constants.simple_selector_sequence + Constants.combinator
+
+ elif context.startswith('pseudo-'):
if seq and seq[-1].value not in '+-':
# e.g. x:func(a + b)
self.append(seq, Constants.S, 'S', token=token)
@@ -226,8 +239,19 @@
if val.endswith('('):
# function
# "pseudo-" "class" or "element"
- self.context.append(typ)
- return Constants.expressionstart
+ if val.lower() in Constants.selector_pseudos:
+ ctx = 'pseudo-class-has'
+ elif val.lower() in Constants.selector_pseudo_elements:
+ # CSS4 pseudo-elements accepting a full selector argument
+ # (e.g. ::slotted(), ::cue()).
+ ctx = 'pseudo-element'
+ else:
+ self.context.append(typ)
+ return Constants.expressionstart
+ # Selectors Level 4: both pseudo-class and pseudo-element
+ # forms that accept a full selector list as argument
+ self.context.append(ctx)
+ return Constants.simple_selector_sequence
elif 'negation' == context:
return Constants.negationend
elif 'pseudo-element' == typ:
@@ -312,6 +336,11 @@
self.append(seq, val, 'negation-type-selector', token=token)
return Constants.negationend
+ # context: pseudo-class-has (selector-accepting pseudo like :has())
+ elif context == 'pseudo-class-has':
+ self.append(seq, val, 'type-selector', token=token)
+ return Constants.simple_selector_sequence2 + Constants.combinator
+
# context: pseudo
elif context.startswith('pseudo-'):
# :func(...)
@@ -391,6 +420,18 @@
context = self.context[-1]
return Constants.simple_selector_sequence + Constants.combinator
+ # context: pseudo-class-has (:has(), :is(), :where(), etc.)
+ if ')' == val and context == 'pseudo-class-has':
+ # :has(selector) end
+ self.append(seq, val, 'function-end', token=token)
+ self.context.pop() # pseudo-class-has is done
+ context = self.context[-1]
+ if 'pseudo-element' == context:
+ # inside ::slotted(:is(...)) — outer pseudo-element still open
+ return Constants.expression
+ else:
+ return Constants.simple_selector_sequence +
Constants.combinator
+
# context: pseudo (at least one expression)
if val in '+-' and context.startswith('pseudo-'):
# :func(+ -)"
@@ -404,11 +445,16 @@
if (
')' == val
and context.startswith('pseudo-')
- and Constants.expression == expected
+ and (
+ Constants.expression == expected
+ or (context == 'pseudo-element' and 'combinator' in expected)
+ )
):
- # :func(expression)"
+ # :func(expression) or ::slotted(selector) end
self.append(seq, val, 'function-end', token=token)
self.context.pop() # pseudo is done
+ # context still holds the pre-pop value: check what *type* of
pseudo
+ # we just closed to decide what may follow.
if 'pseudo-element' == context:
return Constants.combinator
else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/cssutils.egg-info/PKG-INFO
new/cssutils-2.15.0/cssutils.egg-info/PKG-INFO
--- old/cssutils-2.14.0/cssutils.egg-info/PKG-INFO 2026-04-20
01:51:13.000000000 +0200
+++ new/cssutils-2.15.0/cssutils.egg-info/PKG-INFO 2026-04-27
22:40:30.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: cssutils
-Version: 2.14.0
+Version: 2.15.0
Summary: A CSS Cascading Style Sheets library for Python
Author-email: Christof Hoeke <[email protected]>
Maintainer-email: "Jason R. Coombs" <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/cssutils.egg-info/SOURCES.txt
new/cssutils-2.15.0/cssutils.egg-info/SOURCES.txt
--- old/cssutils-2.14.0/cssutils.egg-info/SOURCES.txt 2026-04-20
01:51:13.000000000 +0200
+++ new/cssutils-2.15.0/cssutils.egg-info/SOURCES.txt 2026-04-27
22:40:30.000000000 +0200
@@ -2,6 +2,7 @@
.editorconfig
.pre-commit-config.yaml
.readthedocs.yaml
+AGENTS.md
LICENSE
NEWS.rst
README.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cssutils-2.14.0/tests/test_selector.py
new/cssutils-2.15.0/tests/test_selector.py
--- old/cssutils-2.14.0/tests/test_selector.py 2026-04-20 01:50:57.000000000
+0200
+++ new/cssutils-2.15.0/tests/test_selector.py 2026-04-27 22:40:10.000000000
+0200
@@ -298,6 +298,33 @@
':not([a])': None,
':not(:first-letter)': None,
':not(::first-letter)': None,
+ # Selectors Level 4: :has() with complex selectors
+ 'fieldset:has(option)': None,
+ 'fieldset:has(option:checked)': None,
+ 'fieldset:has(option[value="foo"]:checked)': None,
+ 'fieldset:has(option[value="foo"])': None,
+ ':has(.bar)': None,
+ ':has(#id)': None,
+ ':has(div span)': None,
+ # Selectors Level 4: :is() and :where()
+ ':is(div)': None,
+ ':is(.foo)': None,
+ ':is(div.foo:hover)': None,
+ ':where(div)': None,
+ ':where(.foo:hover)': None,
+ # pseudo-element selector functions (CSS4: ::slotted, ::cue, etc.)
+ 'x::slotted(div)': None,
+ 'x::slotted(.foo)': None,
+ 'x::slotted(.foo:hover)': None,
+ # ::slotted with nested selector-accepting pseudo (covers
+ # pseudo-class-has closing when outer context is pseudo-element)
+ 'x::slotted(:is(div))': None,
+ 'x::slotted(:is(.foo))': None,
+ ':is(::slotted(.foo))': None,
+ # nested selector-accepting pseudo-elements
+ 'x::slotted(::slotted(.foo))': None,
+ # pseudo-element function with expression argument
+ 'x::func(a)': None,
# escapes
r'\74\72 td': 'trtd',
r'\74\72 td': 'tr td',
@@ -410,11 +437,16 @@
'* a': (0, 0, 0, 1),
'a *': (0, 0, 0, 1),
'a * b': (0, 0, 0, 2),
- 'a:hover': (0, 0, 0, 1),
+ 'a:hover': (0, 0, 1, 1),
'a:first-line': (0, 0, 0, 2),
'a:first-letter': (0, 0, 0, 2),
'a:before': (0, 0, 0, 2),
'a:after': (0, 0, 0, 2),
+ # pseudo-classes count as class selectors (column c)
+ ':last-child': (0, 0, 1, 0),
+ 'tr:last-child': (0, 0, 1, 1),
+ ':nth-child(2)': (0, 0, 1, 0),
+ '.table > :last-child > tr:last-child > *': (0, 0, 3, 1),
# classes and attributes
'.a': (0, 0, 1, 0),
'*.a': (0, 0, 1, 0),