Package: src:genshi
Version: 0.7.10-2 User: [email protected]
Usertags: python3.15
Tags: patch

Hi!

While rebuilding the python related packages against the Python 3.15rc1
version we found that genshi fails to build from source [1].
While looking for the fix, I found an unapplied PR upstream that tackles
the problem [2].

I've applied the PR fix in the sandbox [3] to be able to build the
packages that depend on genshi, please consider applying the patch to
support the upcoming 3.15 version.

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/artifact/4283826/
[2]: https://github.com/edgewall/genshi/pull/93
[3]: https://debusine.debian.net/debian/r-python-python3.15/

--
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
From 0bcd1eeefaa58d49441ad1d82d0852c049154811 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Krier?= <[email protected]>
Date: Mon, 12 May 2025 00:28:42 +0200
Subject: [PATCH 1/4] Fix deprecation warning when creating AST node without
 required fields

Python 3.13 added the warning which will become an error in Python 3.15
(see https://github.com/python/cpython/pull/105880)
---
 genshi/template/astutil.py | 16 +++++++++++++++-
 genshi/template/eval.py    | 11 +++++------
 pytest.ini                 |  3 +++
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py
index c841aeb..b53b573 100644
--- a/genshi/template/astutil.py
+++ b/genshi/template/astutil.py
@@ -802,7 +802,7 @@ def visit(self, node):
         return visitor(node)
 
     def _clone(self, node):
-        clone = node.__class__()
+        clone = construct_ast_class(node.__class__)
         for name in getattr(clone, '_attributes', ()):
             try:
                 setattr(clone, name, getattr(node, name))
@@ -887,3 +887,17 @@ def _clone(self, node):
     visit_Index = _clone
 
     del _clone
+
+
+def construct_ast_class(cls):
+    kwargs = {}
+    for name, typ in cls.__annotations__.items():
+        if typ is str:
+            kwargs[name] = 'foo'
+        elif typ is int:
+            kwargs[name] = 42
+        elif typ is object:
+            kwargs[name] = b'foo'
+        elif isinstance(typ, type) and issubclass(typ, _ast.AST):
+            kwargs[name] = construct_ast_class(typ)
+    return cls(**kwargs)
diff --git a/genshi/template/eval.py b/genshi/template/eval.py
index 82bddf3..4197597 100644
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -18,7 +18,8 @@
 
 from genshi.compat import builtins, exec_, string_types, text_type
 from genshi.core import Markup
-from genshi.template.astutil import ASTTransformer, ASTCodeGenerator, parse
+from genshi.template.astutil import (
+    ASTTransformer, ASTCodeGenerator, parse, construct_ast_class)
 from genshi.template.base import TemplateRuntimeError
 from genshi.util import flatten
 
@@ -59,11 +60,9 @@ def __init__(self, source, filename=None, lineno=-1, lookup='strict',
                 'Expected string or AST node, but got %r' % source
             self.source = '?'
             if self.mode == 'eval':
-                node = _ast.Expression()
-                node.body = source
+                node = _ast.Expression(body=source)
             else:
-                node = _ast.Module()
-                node.body = [source]
+                node = _ast.Module(body=[source])
 
         self.ast = node
         self.code = _compile(node, self.source, mode=self.mode,
@@ -454,7 +453,7 @@ def _compile(node, source=None, mode='eval', filename=None, lineno=-1,
 
 
 def _new(class_, *args, **kwargs):
-    ret = class_()
+    ret = construct_ast_class(class_)
     for attr, value in zip(ret._fields, args):
         if attr in kwargs:
             raise ValueError('Field set both in args and kwargs')
diff --git a/pytest.ini b/pytest.ini
index 980658e..b05daa7 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,3 +1,6 @@
 [pytest]
 addopts = --doctest-modules
 doctest_optionflags = NORMALIZE_WHITESPACE ALLOW_UNICODE
+filterwarnings =
+    error
+    ignore:pkg_resources

From 01c8b3219a79fea139bf8ac717c8b06ca02aa2de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Krier?= <[email protected]>
Date: Mon, 12 May 2025 00:45:46 +0200
Subject: [PATCH 2/4] Simplify configuration of github workflows tests

---
 .github/workflows/tests.yml | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d0ce1c6..59e157e 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -9,15 +9,7 @@ jobs:
 
     strategy:
       matrix:
-        python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "pypy3.9"]
-        pytest-extra-options: ["--strict-config"]
-        include:
-          - python-version: "pypy2.7"
-            pytest-extra-options: ""
-          - python-version: "pypy3.11"
-            pytest-extra-options: ""
-          - python-version: "3.13.0-beta.2"
-            pytest-extra-options: "--strict-config -W ignore::DeprecationWarning"
+        python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13", "pypy3.9"]
       fail-fast: false
 
     steps:
@@ -37,12 +29,8 @@ jobs:
 
       - name: Run test suite
         run: |
-          pytest -Werror --strict-markers --verbosity=1 --color=yes ${{ matrix.pytest-extra-options }} genshi
+          pytest --strict-markers --verbosity=1 --color=yes genshi
           # Above flags are:
-          #  -Werror
-          #     treat warnings as errors
-          #  --strict-config
-          #     error out if the configuration file is not parseable
           #  --strict-markers
           #     error out if a marker is used but not defined in the
           #     configuration file

From 09fd95760e231d4f487c7378b11215e5c5d184c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Krier?= <[email protected]>
Date: Mon, 12 May 2025 00:49:35 +0200
Subject: [PATCH 3/4] Use ast Node annotations to construct if available

---
 genshi/template/astutil.py | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py
index b53b573..510d3a8 100644
--- a/genshi/template/astutil.py
+++ b/genshi/template/astutil.py
@@ -891,13 +891,14 @@ def _clone(self, node):
 
 def construct_ast_class(cls):
     kwargs = {}
-    for name, typ in cls.__annotations__.items():
-        if typ is str:
-            kwargs[name] = 'foo'
-        elif typ is int:
-            kwargs[name] = 42
-        elif typ is object:
-            kwargs[name] = b'foo'
-        elif isinstance(typ, type) and issubclass(typ, _ast.AST):
-            kwargs[name] = construct_ast_class(typ)
+    if hasattr(cls, '__annotations__'):
+        for name, typ in cls.__annotations__.items():
+            if typ is str:
+                kwargs[name] = 'foo'
+            elif typ is int:
+                kwargs[name] = 42
+            elif typ is object:
+                kwargs[name] = b'foo'
+            elif isinstance(typ, type) and issubclass(typ, _ast.AST):
+                kwargs[name] = construct_ast_class(typ)
     return cls(**kwargs)

From 76055327af17c5fc6c4bc5365407175276ff6a04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Krier?= <[email protected]>
Date: Mon, 12 May 2025 00:50:13 +0200
Subject: [PATCH 4/4] Remove 3.6 and 3.7 from github workflows tests

---
 .github/workflows/tests.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 59e157e..448fff8 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -9,7 +9,7 @@ jobs:
 
     strategy:
       matrix:
-        python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13", "pypy3.9"]
+        python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13", "pypy3.9"]
       fail-fast: false
 
     steps:

Reply via email to