Your message dated Fri, 28 Aug 2026 15:50:06 +0000
with message-id <[email protected]>
and subject line Bug#1145438: fixed in python-django 3:5.2.17-2
has caused the Debian Bug report #1145438,
regarding python-django: FTBFS against python 3.15rc1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1145438: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1145438
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: src:python-django
Version: 3:5.2.17-1
User: [email protected]
Usertags: python3.15
Tags: patch, ftbfs, forky, sid

Hi!

While rebuilding the python related packages against the Python 3.15rc1
version we found that python-django fails to build from source [1].

There are three separate issues related to python 3.15.

First, tests failing with `NameError: name 'SomeType' is not defined.
Did you mean: 'TokenType'?`. This was fixed upstream with Commit e7f539f
[2].

Second, the error message for `test_invalid_choice_db_option` has
changed. To fix this, it required applying a few upstream patches [3]
[4].

Third, test_strip_tags failed with `sys.version_info >=
min_fixed_security[sys.version_info[:2]] KeyError: (3, 15)`, this is
caused by line 136 of tests/utils_tests/test_html.py, which defines
htmlparser_fixed_security but that's never used and it's later recrated
in line 151 in a way that avoids the error, the related upstream fix
about this is in [5], but backporting the fix is actually only deleting
the line 136.

I applied the upstream fixes in the sandbox [5] to be able to build the
packages that depend on python-django, 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/4415709/raw/python-django_5.2.17-1+py315.1_amd64-2026-08-22T01:25:30Z.build
[2]: 
https://github.com/django/django/commit/e7f539f813bd56a71ca3c1fbf379f47691002086
[3]: https://github.com/django/django/pull/20021
[4]: 
https://github.com/django/django/commit/ed13a58bf63df94508c8a0fe779da0b6a2bc26bb
[5]: https://github.com/django/django/commit/185b049
[6]: 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: Jacob Walls <[email protected]>
Date: Wed, 6 May 2026 15:39:41 -0400
Subject: [PATCH] Refs #36712, #36664 -- Used annotation_format parameter of
 getfullargspec() on Python 3.15.

https://github.com/python/cpython/pull/149457

Origin: upstream, https://github.com/django/django/commit/e7f539f813bd56a71ca3c1fbf379f47691002086
---
 django/contrib/admin/templatetags/base.py |  9 +++------
 django/template/base.py                   |  5 ++---
 django/template/library.py                | 23 ++++++++++-------------
 django/utils/inspect.py                   | 27 ++++++++++++++++++++++-----
 4 files changed, 37 insertions(+), 27 deletions(-)

Index: python-django/django/contrib/admin/templatetags/base.py
===================================================================
--- python-django.orig/django/contrib/admin/templatetags/base.py
+++ python-django/django/contrib/admin/templatetags/base.py
@@ -1,7 +1,5 @@
-from inspect import getfullargspec
-
 from django.template.library import InclusionNode, parse_bits
-from django.utils.inspect import lazy_annotations
+from django.utils.inspect import getfullargspec
 
 
 class InclusionAdminNode(InclusionNode):
@@ -12,10 +10,9 @@ class InclusionAdminNode(InclusionNode):
 
     def __init__(self, parser, token, func, template_name, takes_context=True):
         self.template_name = template_name
-        with lazy_annotations():
-            params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = (
-                getfullargspec(func)
-            )
+        params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(
+            func
+        )
         bits = token.split_contents()
         args, kwargs = parse_bits(
             parser,
Index: python-django/django/template/base.py
===================================================================
--- python-django.orig/django/template/base.py
+++ python-django/django/template/base.py
@@ -58,7 +58,7 @@ from enum import Enum
 from django.template.context import BaseContext
 from django.utils.formats import localize
 from django.utils.html import conditional_escape
-from django.utils.inspect import lazy_annotations, signature
+from django.utils.inspect import getfullargspec, signature
 from django.utils.regex_helper import _lazy_re_compile
 from django.utils.safestring import SafeData, SafeString, mark_safe
 from django.utils.text import get_text_list, smart_split, unescape_string_literal
@@ -761,8 +761,7 @@ class FilterExpression:
         # Check to see if a decorator is providing the real function.
         func = inspect.unwrap(func)
 
-        with lazy_annotations():
-            args, _, _, defaults, _, _, _ = inspect.getfullargspec(func)
+        args, _, _, defaults, _, _, _ = getfullargspec(func)
         alen = len(args)
         dlen = len(defaults or [])
         # Not enough OR Too many
Index: python-django/django/template/library.py
===================================================================
--- python-django.orig/django/template/library.py
+++ python-django/django/template/library.py
@@ -1,10 +1,10 @@
 from collections.abc import Iterable
 from functools import wraps
 from importlib import import_module
-from inspect import getfullargspec, unwrap
+from inspect import unwrap
 
 from django.utils.html import conditional_escape
-from django.utils.inspect import lazy_annotations
+from django.utils.inspect import getfullargspec
 
 from .base import Node, Template, token_kwargs
 from .exceptions import TemplateSyntaxError
@@ -110,16 +110,15 @@ class Library:
         """
 
         def dec(func):
-            with lazy_annotations():
-                (
-                    params,
-                    varargs,
-                    varkw,
-                    defaults,
-                    kwonly,
-                    kwonly_defaults,
-                    _,
-                ) = getfullargspec(unwrap(func))
+            (
+                params,
+                varargs,
+                varkw,
+                defaults,
+                kwonly,
+                kwonly_defaults,
+                _,
+            ) = getfullargspec(unwrap(func))
             function_name = name or func.__name__
 
             @wraps(func)
@@ -166,16 +165,15 @@ class Library:
 
         def dec(func):
             nonlocal end_name
-            with lazy_annotations():
-                (
-                    params,
-                    varargs,
-                    varkw,
-                    defaults,
-                    kwonly,
-                    kwonly_defaults,
-                    _,
-                ) = getfullargspec(unwrap(func))
+            (
+                params,
+                varargs,
+                varkw,
+                defaults,
+                kwonly,
+                kwonly_defaults,
+                _,
+            ) = getfullargspec(unwrap(func))
             function_name = name or func.__name__
 
             if end_name is None:
@@ -250,16 +248,15 @@ class Library:
         """
 
         def dec(func):
-            with lazy_annotations():
-                (
-                    params,
-                    varargs,
-                    varkw,
-                    defaults,
-                    kwonly,
-                    kwonly_defaults,
-                    _,
-                ) = getfullargspec(unwrap(func))
+            (
+                params,
+                varargs,
+                varkw,
+                defaults,
+                kwonly,
+                kwonly_defaults,
+                _,
+            ) = getfullargspec(unwrap(func))
             function_name = name or func.__name__
 
             @wraps(func)
Index: python-django/django/utils/inspect.py
===================================================================
--- python-django.orig/django/utils/inspect.py
+++ python-django/django/utils/inspect.py
@@ -3,16 +3,17 @@ import inspect
 import threading
 from contextlib import contextmanager
 
-from django.utils.version import PY314
+from django.utils.version import PY314, PY315
 
 if PY314:
     import annotationlib
 
-    lock = threading.Lock()
-    safe_signature_from_callable = functools.partial(
-        inspect._signature_from_callable,
-        annotation_format=annotationlib.Format.FORWARDREF,
-    )
+    if not PY315:
+        lock = threading.Lock()
+        safe_signature_from_callable = functools.partial(
+            inspect._signature_from_callable,
+            annotation_format=annotationlib.Format.FORWARDREF,
+        )
 
 
 @functools.lru_cache(maxsize=512)
@@ -96,12 +97,12 @@ def lazy_annotations():
     compatibility with Python 3.14+ deferred evaluation, patch the module-level
     helper to provide the annotation_format that we are using elsewhere.
 
-    This private helper could be removed when there is an upstream solution for
-    https://github.com/python/cpython/issues/141560.
+    This private helper should only be used for Python 3.14, as
+    https://github.com/python/cpython/issues/141560 was fixed in 3.15.
 
     This context manager is not reentrant.
     """
-    if not PY314:
+    if PY315 or not PY314:
         yield
         return
     with lock:
@@ -113,6 +114,22 @@ def lazy_annotations():
             inspect._signature_from_callable = original_helper
 
 
+def getfullargspec(*args, annotation_format=None, **kwargs):
+    """
+    A wrapper around inspect.getfullargspec that leaves deferred annotations
+    unevaluated on Python 3.14+, since they are not used in our case.
+    """
+    if PY315:
+        return inspect.getfullargspec(
+            *args, **kwargs, annotation_format=annotationlib.Format.FORWARDREF
+        )
+    if PY314:
+        with lazy_annotations():
+            return inspect.getfullargspec(*args, **kwargs)
+    else:
+        return inspect.getfullargspec(*args, **kwargs)
+
+
 def signature(obj):
     """
     A wrapper around inspect.signature that leaves deferred annotations
From: kihuni <[email protected]>
Date: Sun, 2 Nov 2025 08:50:45 +0300
Subject: [PATCH] Fixed #36321 -- Defaulted suggest_on_error=True in management
 commands.

Python 3.15 defaults suggest_on_error=True, but the feature is available
from 3.14, so this change opts in earlier. This change can be reverted
when Python 3.15 is the minimum supported version.

Origin: upstream, https://github.com/django/django/commit/b1a65eac7c09250d36e12464fc8fff2a401246b6
---
 django/core/management/base.py |  3 +++
 django/utils/version.py        |  1 +
 tests/admin_scripts/tests.py   |  8 +++++++-
 tests/user_commands/tests.py   | 16 ++++++++++++++++
 4 files changed, 27 insertions(+), 1 deletion(-)

Index: python-django/django/core/management/base.py
===================================================================
--- python-django.orig/django/core/management/base.py
+++ python-django/django/core/management/base.py
@@ -15,7 +15,7 @@ from django.core import checks
 from django.core.exceptions import ImproperlyConfigured
 from django.core.management.color import color_style, no_style
 from django.db import DEFAULT_DB_ALIAS, connections
-from django.utils.version import PY314
+from django.utils.version import PY314, PY315
 
 ALL_CHECKS = "__all__"
 
@@ -58,6 +58,8 @@ class CommandParser(ArgumentParser):
     ):
         self.missing_args_message = missing_args_message
         self.called_from_command_line = called_from_command_line
+        if PY314 and not PY315:
+            kwargs.setdefault("suggest_on_error", True)
         if PY314:
             if os.environ.get("DJANGO_COLORS") == "nocolor" or "--no-color" in sys.argv:
                 kwargs.setdefault("color", False)
Index: python-django/django/utils/version.py
===================================================================
--- python-django.orig/django/utils/version.py
+++ python-django/django/utils/version.py
@@ -20,6 +20,7 @@ PY311 = sys.version_info >= (3, 11)
 PY312 = sys.version_info >= (3, 12)
 PY313 = sys.version_info >= (3, 13)
 PY314 = sys.version_info >= (3, 14)
+PY315 = sys.version_info >= (3, 15)
 
 
 def get_version(version=None):
Index: python-django/tests/admin_scripts/tests.py
===================================================================
--- python-django.orig/tests/admin_scripts/tests.py
+++ python-django/tests/admin_scripts/tests.py
@@ -38,7 +38,7 @@ from django.db.migrations.recorder impor
 from django.test import LiveServerTestCase, SimpleTestCase, TestCase, override_settings
 from django.test.utils import captured_stderr, captured_stdout
 from django.urls import path
-from django.utils.version import PY313, get_docs_version
+from django.utils.version import PY313, PY314, get_docs_version
 from django.views.static import serve
 
 from . import urls
@@ -2405,10 +2405,16 @@ class Discovery(SimpleTestCase):
 
 class CommandDBOptionChoiceTests(SimpleTestCase):
     def test_invalid_choice_db_option(self):
-        expected_error = (
-            r"Error: argument --database: invalid choice: 'deflaut' "
-            r"\(choose from '?default'?, '?other'?\)"
-        )
+        if PY314:
+            expected_error = (
+                r"Error: argument --database: invalid choice: 'deflaut', "
+                r"maybe you meant 'default'\? \(choose from default, other\)"
+            )
+        else:
+            expected_error = (
+                r"Error: argument --database: invalid choice: 'deflaut' "
+                r"\(choose from '?default'?, '?other'?\)"
+            )
         args = [
             "changepassword",
             "createsuperuser",
From: kasey <[email protected]>
Date: Tue, 12 May 2026 00:15:15 -0500
Subject: [PATCH] Fixed #37096 -- Fixed test_invalid_choice_db_option on Python
 3.14.5+.

Origin: upstream, https://github.com/django/django/commit/ed13a58bf63df94508c8a0fe779da0b6a2bc26bb
---
 tests/admin_scripts/tests.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Index: python-django/tests/admin_scripts/tests.py
===================================================================
--- python-django.orig/tests/admin_scripts/tests.py
+++ python-django/tests/admin_scripts/tests.py
@@ -2408,7 +2408,8 @@ class CommandDBOptionChoiceTests(SimpleT
         if PY314:
             expected_error = (
                 r"Error: argument --database: invalid choice: 'deflaut', "
-                r"maybe you meant 'default'\? \(choose from default, other\)"
+                r"maybe you meant 'default'\? "
+                r"\(choose from '?default'?, '?other'?\)"
             )
         else:
             expected_error = (
From: Mariusz Felisiak <[email protected]>
Date: Wed, 22 Oct 2025 10:04:38 +0200
Subject: [PATCH] Refs #36499 -- Made TestUtilsHtml.test_strip_tags() assume
 behavior change in X.Y.0 version for Python 3.14+.

This also removes unsupported versions of Python from the test dict.

Origin: upstream, https://github.com/django/django/commit/185b049e9e72a5ff4b07e33605e10eb4f52ca74c
---
 tests/utils_tests/test_html.py | 11 -----------
 1 file changed, 11 deletions(-)

Index: python-django/tests/utils_tests/test_html.py
===================================================================
--- python-django.orig/tests/utils_tests/test_html.py
+++ python-django/tests/utils_tests/test_html.py
@@ -126,16 +126,9 @@ class TestUtilsHtml(SimpleTestCase):
         # Python versions and CI workers include the fix. See:
         # https://github.com/python/cpython/commit/6eb6c5db
         min_fixed_security = {
-            (3, 14): (3, 14),
             (3, 13): (3, 13, 6),
             (3, 12): (3, 12, 12),
-            (3, 11): (3, 11, 14),
-            (3, 10): (3, 10, 19),
-            (3, 9): (3, 9, 24),
         }
-        htmlparser_fixed_security = (
-            sys.version_info >= min_fixed_security[sys.version_info[:2]]
-        )
         # Similarly, there was a fix for terminating incomplete entities. See:
         # https://github.com/python/cpython/commit/95296a9d
         min_fixed_incomplete_entities = {

--- End Message ---
--- Begin Message ---
Source: python-django
Source-Version: 3:5.2.17-2
Done: Chris Lamb <[email protected]>

We believe that the bug you reported is fixed in the latest version of
python-django, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [email protected],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Chris Lamb <[email protected]> (supplier of updated python-django package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [email protected])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Format: 1.8
Date: Thu, 27 Aug 2026 16:55:04 -0700
Source: python-django
Architecture: source
Version: 3:5.2.17-2
Distribution: unstable
Urgency: medium
Maintainer: Debian Python Team <[email protected]>
Changed-By: Chris Lamb <[email protected]>
Closes: 1145438
Changes:
 python-django (3:5.2.17-2) unstable; urgency=medium
 .
   * Apply a number of upstream patches to address FTBFS issues under Python
     3.15. Thanks to Maximiliano Curia (maxy) for report and research:
 .
     - "Used annotation_format parameter of getfullargspec() on Python 3.15."
     - "Defaulted suggest_on_error=True in management commands."
     - "Fixed test_invalid_choice_db_option on Python 3.14.5+."
     - Drop incorrect/masked definition of htmlparser_fixed_security in
       tests/utils_tests/test_html.py.
 .
     (Closes: #1145438)
Checksums-Sha1:
 333b37623063d86539a98e156acb6a039957c8ad 2790 python-django_5.2.17-2.dsc
 7c0ecfdec9fdd9c3dcc1e96be06dbd6841beee3b 10889740 
python-django_5.2.17.orig.tar.gz
 3de7539ec0551bf4488233b5a6a9a13b730e5d10 43036 
python-django_5.2.17-2.debian.tar.xz
 1d4051fc0277d40d7d768d838edbd57c4f53ec2e 8035 
python-django_5.2.17-2_source.buildinfo
Checksums-Sha256:
 2a315a609f90054e5293cadd85e67f1ba2c3ec7503635b9ca73be0a3da3c8a7f 2790 
python-django_5.2.17-2.dsc
 9d4d93be539a18ab80d058eb515900e10951e04c537c5a6b394fc49528d3251f 10889740 
python-django_5.2.17.orig.tar.gz
 b4481d5b6e67bababceb6650e7211f844f7e6a3f3136f7a7278e7b851b66cbf4 43036 
python-django_5.2.17-2.debian.tar.xz
 5512199ff669c40b0d14f7ae8f63bc418239341c6ed26b77a3a37008a437deb6 8035 
python-django_5.2.17-2_source.buildinfo
Files:
 2db3efd59c4b6fa76926b29f2c1cbf9b 2790 python optional 
python-django_5.2.17-2.dsc
 d3e9f9ca5c6d7d044a97675def960297 10889740 python optional 
python-django_5.2.17.orig.tar.gz
 267c12b7e7b095943ae8c8efe50d5fe7 43036 python optional 
python-django_5.2.17-2.debian.tar.xz
 f4c8be9c402ab0fa8778bed9e0a667b2 8035 python optional 
python-django_5.2.17-2_source.buildinfo

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEwv5L0nHBObhsUz5GHpU+J9QxHlgFAmqRqHEACgkQHpU+J9Qx
HljWuQ/+I5O75aeJ2BYVK10oAKIfktY5l6XoG0f5Ij8WWHvoMmXD7QAVScZWvrJf
yPVTiOqni3wEVejkBjRlpcXoz29nKZzZ4m2S7oOrZVy3Xq4qcJRpjx+jhPvSxqZJ
yqWKU5fdf32ddZT8HmNFuez/vc5ibf0Sh/vSCzmCkOL1SNnOWgpdqxsHa+MSGw95
5qdmgk6Fdshg6JTDl5SJb7FOp2gvdJheJ0CFMUEyxxPIMX2v0Tnk0Rk06xhQ2p2P
EC3s5SAh7UfMwaEN5Z/cIqoePuwUrrmtJaRJawOAkbuHYPSVI6bVqD7fvOEbFY4j
28b1Do1QRzYOMr/IUCc0qnxZxdarSsCEBuWOdU2gRXhObfD3ri/NzWROFqTTgVBI
+iEPTXUsMGgCkaNb8mBfn20+wDpdMW+ZrrMfZC2ptdQiQ2b1/ID0+vVgi7a4NekN
O06EYNXJkuG2GVvrMD5Hn8M25T/7abm2C6mYw/XrvwcdJVVfcMr0kPCCY0qRydBV
Lte/PXyXo0yAnCGsv9B5n7fyX3NZUaMWrtGPfpuD1F90HYWr9QiBdmJlYfqRd4qu
rKBxK1UlQWiPU0pFDAX2N3p6BBQMqzCYYP+7ctCqPxQodWph0u6iOJLbp7BgRvki
mwdWhj1xPCs+eMhbGwOgBATnvlcyf+6zsMMAHJuB0wBeZqRxoY4=
=vk9y
-----END PGP SIGNATURE-----

Attachment: pgp0reu1jylOH.pgp
Description: PGP signature


--- End Message ---

Reply via email to