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),

Reply via email to