[From nobody Wed Sep 16 22:51:10 2026
Received: (at submit) by bugs.debian.org; 19 Aug 2026 14:28:01 +0000
X-Spam-Checker-Version: SpamAssassin 4.0.1-bugs.debian.org_2005_01_02
 (2024-03-25) on buxtehude.debian.org
X-Spam-Level: 
X-Spam-Status: No, score=-124.4 required=4.0 tests=ALL_TRUSTED,BAYES_00,
 BODY_INCLUDES_PACKAGE,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,
 DKIM_VALID_AU,DKIM_VALID_EF,FOURLA,FROMDEVELOPER,HAS_PACKAGE,
 MD5_SHA1_SUM,PGPSIGNATURE,SPF_HELO_NONE,SPF_PASS,
 USER_IN_DKIM_WELCOMELIST autolearn=ham autolearn_force=no
 version=4.0.1-bugs.debian.org_2005_01_02
X-Spam-Bayes: score:0.0000 Tokens: new, 207; hammy, 150; neutral, 454; spammy,
 0. spammytokens:
 hammytokens:0.000-+--Hx-spam-relays-external:sk:stravin,
 0.000-+--H*RT:sk:stravin, 0.000-+--Hx-spam-relays-external:311,
 0.000-+--H*RT:311, 0.000-+--H*RT:108
Return-path: &lt;maxy@debian.org&gt;
Received: from stravinsky.debian.org ([2001:41b8:202:deb::311:108]:36210)
 by buxtehude.debian.org with esmtps
 (TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)
 (Exim 4.96) (envelope-from &lt;maxy@debian.org&gt;) id 1wwhGr-002EOm-1P
 for submit@bugs.debian.org; Wed, 19 Aug 2026 14:28:01 +0000
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; 
 s=smtpauto.stravinsky;
 h=X-Debian-User:Content-Type:MIME-Version:Message-ID:
 Subject:Cc:To:From:Date:Reply-To:Content-Transfer-Encoding:Content-ID:
 Content-Description:In-Reply-To:References;
 bh=mpJt/KJxcDakVB3iFKf809XHRqciNk+AXJVovuPMW58=; b=blI8moI9pUdSahXNf906h/0ekJ
 LXGb+73OV4usjEIMzBoHbhVtwLcYMbEuh2P2IKy/q9eLt5+Pye5lrfvJtqxVIeaLP6fOHXE6tsVuN
 0TcNNbqMFrP++6g04RyNmlDliAAmkEzWKXYyD+C1ZXoi1dWkesphCRpDbwDYUoiA6WKPQOQlOZsNF
 FS2aOwC1AQFMm9O9cy53J8sLnnd3UIMN9ti1nPlLs4gLedpjeoFh1+IsRILq0OZvCstlMENm7PqGh
 LY3aH3f0jEgwqxgXJ6o5L4cmQ4qNRl0mou1W2yV+psg6g2RELI7YDTP0CYzCKNIeKWnLzA8rCtdDk
 JsdvhKow==;
Received: from authenticated-user by stravinsky.debian.org with esmtpsa
 (TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)
 (Exim 4.96) (envelope-from &lt;maxy@debian.org&gt;) id 1wwhGo-009r1g-2W;
 Wed, 19 Aug 2026 14:28:00 +0000
Date: Wed, 19 Aug 2026 16:27:57 +0200
From: Maximiliano Curia &lt;maxy@debian.org&gt;
To: submit@bugs.debian.org
Cc: debian-python@lists.debian.org
Subject: pandas: FTBFS building against python 3.15
Message-ID: &lt;aoW9bU4BOKbKROFr@hecuba.gnuservers.com.ar&gt;
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha512;
 protocol=&quot;application/pgp-signature&quot;; boundary=&quot;xQGsmXqnhajjBhuJ&quot;
Content-Disposition: inline
X-Debian-User: maxy
Delivered-To: submit@bugs.debian.org

--xQGsmXqnhajjBhuJ
Content-Type: multipart/mixed; boundary=&quot;PXHuQWrQkjBeVe8E&quot;
Content-Disposition: inline

--PXHuQWrQkjBeVe8E
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Package: src:pandas
Version: 3.0.5+dfsg-1
User: debian-python@lists.debian.org
Usertags: python3.15
Tags: patch

Hi!

While rebuilding the Python related packages against the Python 3.15rc1
version we found that pandas fails to build from source[1]. The upstream
code already has fixes for these issues and since there are many
packages that require pandas to build I already applied these fixes in
the packages that are in the rebuild sandbox[2].

Please consider applying this patches in your next upload, or consider
updating pandas when a new release including these patches is available.

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/work-request/10=
12982/
[2]: https://debusine.debian.net/debian/r-python-python3.15/

--=20
&quot;recursividad 95, 154, 156, 201, 224, 293&quot;
-- El Lenguaje de Programacion C, pag. 293 (Kernighan &amp; Ritchie)
Saludos /\/\ /\ &gt;&lt; `/

--PXHuQWrQkjBeVe8E
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename=python3p15_compat.patch
Content-Transfer-Encoding: quoted-printable

Description: Python 3.15 compatibility fixes
 Backport of upstream commit 7bb284ac43 (PR #66473) for Python 3.15 support:
 - Support optional %z and %:z (colon_z) in strptime
 - Explicitly close XML iterparse parser to avoid unclosed iterator Resourc=
eWarning
 - Accept Python 3.15 TypeError / ValueError error message changes in tests
 - Define and export PY315 in pandas.compat
Origin: upstream, https://github.com/pandas-dev/pandas/commit/7bb284ac438d2=
b981a7f42e3bdd0fe5ee26aada0
Bug: https://github.com/pandas-dev/pandas/issues/66473
Forwarded: not-needed

Index: pandas/pandas/_libs/tslibs/strptime.pyx
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/_libs/tslibs/strptime.pyx
+++ pandas/pandas/_libs/tslibs/strptime.pyx
@@ -167,6 +167,7 @@ cdef dict _parse_code_table =3D {&quot;y&quot;: 0,
                                &quot;Z&quot;: 17,
                                &quot;p&quot;: 18,  # an additional key, only with I
                                &quot;z&quot;: 19,
+                               &quot;colon_z&quot;: 24,
                                &quot;G&quot;: 20,
                                &quot;V&quot;: 21,
                                &quot;u&quot;: 22}
@@ -178,7 +179,7 @@ cdef _validate_fmt(str fmt):
             raise ValueError(&quot;Cannot use '%W' or '%U' without day and year=
&quot;)
         if &quot;%A&quot; not in fmt and &quot;%a&quot; not in fmt and &quot;%w&quot; not in fmt:
             raise ValueError(&quot;Cannot use '%W' or '%U' without day and year=
&quot;)
-    elif &quot;%Z&quot; in fmt and &quot;%z&quot; in fmt:
+    elif &quot;%Z&quot; in fmt and (&quot;%z&quot; in fmt or &quot;%:z&quot; in fmt):
         raise ValueError(&quot;Cannot parse both %Z and %z&quot;)
     elif &quot;%j&quot; in fmt and &quot;%G&quot; in fmt:
         raise ValueError(&quot;Day of the year directive '%j' is not &quot;
@@ -618,9 +619,19 @@ cdef tzinfo _parse_with_format(
                 f&quot;time data \&quot;{val}\&quot; doesn't match format \&quot;{fmt}\&quot;&quot;
             )
         if len(val) !=3D found.end():
+            rest =3D val[found.end():]
+            # Specific check for '%:z' directive
+            if (
+                &quot;colon_z&quot; in found.re.groupindex
+                and found.group(&quot;colon_z&quot;) is not None
+                and rest[0] !=3D &quot;:&quot;
+            ):
+                raise ValueError(
+                    f&quot;Missing colon in %:z before '{rest}', got '{val}'&quot;
+                )
             raise ValueError(
                 &quot;unconverted data remains when parsing with &quot;
-                f&quot;format \&quot;{fmt}\&quot;: \&quot;{val[found.end():]}\&quot;&quot;
+                f&quot;format \&quot;{fmt}\&quot;: \&quot;{rest}\&quot;&quot;
             )
=20
     else:
@@ -760,9 +771,15 @@ cdef tzinfo _parse_with_format(
         elif parse_code =3D=3D 17:
             # e.g. val=3D'2011-12-30T00:00:00.000000UTC'; fmt=3D'%Y-%m-%dT=
%H:%M:%S.%f%Z'
             tz =3D zoneinfo.ZoneInfo(found_dict[&quot;Z&quot;])
-        elif parse_code =3D=3D 19:
+        # elif group_key in ('z', 'colon_z'):
+        elif parse_code =3D=3D 19 or parse_code =3D=3D 24:
             # e.g. val=3D'March 1, 2018 12:00:00+0400'; fmt=3D'%B %d, %Y %=
H:%M:%S%z'
-            tz =3D parse_timezone_directive(found_dict[&quot;z&quot;])
+            if found_dict[group_key] is None:
+                raise ValueError(
+                    f&quot;time data \&quot;{val}\&quot; doesn't match format \&quot;{fmt}\&quot;&quot;
+                )
+
+            tz =3D parse_timezone_directive(found_dict[group_key])
         elif parse_code =3D=3D 20:
             # e.g. val=3D'2015-1-7'; fmt=3D'%G-%V-%u'
             iso_year =3D int(found_dict[&quot;G&quot;])
Index: pandas/pandas/compat/__init__.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/compat/__init__.py
+++ pandas/pandas/compat/__init__.py
@@ -21,6 +21,7 @@ from pandas.compat._constants import (
     ISMUSL,
     PY312,
     PY314,
+    PY315,
     PYPY,
     WASM,
 )
@@ -161,6 +162,7 @@ __all__ =3D [
     &quot;ISMUSL&quot;,
     &quot;PY312&quot;,
     &quot;PY314&quot;,
+    &quot;PY315&quot;,
     &quot;PYARROW_INSTALLED&quot;,
     &quot;PYARROW_MIN_VERSION&quot;,
     &quot;PYPY&quot;,
Index: pandas/pandas/compat/_constants.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/compat/_constants.py
+++ pandas/pandas/compat/_constants.py
@@ -15,6 +15,7 @@ IS64 =3D sys.maxsize &gt; 2**32
=20
 PY312 =3D sys.version_info &gt;=3D (3, 12)
 PY314 =3D sys.version_info &gt;=3D (3, 14)
+PY315 =3D sys.version_info &gt;=3D (3, 15)
 PYPY =3D platform.python_implementation() =3D=3D &quot;PyPy&quot;
 WASM =3D (sys.platform =3D=3D &quot;emscripten&quot;) or (platform.machine() in [&quot;wa=
sm32&quot;, &quot;wasm64&quot;])
 ISMUSL =3D &quot;musl&quot; in (sysconfig.get_config_var(&quot;HOST_GNU_TYPE&quot;) or &quot;&quot;)
@@ -30,6 +31,7 @@ __all__ =3D [
     &quot;ISMUSL&quot;,
     &quot;PY312&quot;,
     &quot;PY314&quot;,
+    &quot;PY315&quot;,
     &quot;PYPY&quot;,
     &quot;WASM&quot;,
 ]
Index: pandas/pandas/io/xml.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/io/xml.py
+++ pandas/pandas/io/xml.py
@@ -337,44 +337,53 @@ class _XMLFrameParser:
             set(self.iterparse[row_node])
         )
=20
-        for event, elem in iterparse(self.path_or_buffer, events=3D(&quot;start=
&quot;, &quot;end&quot;)):
-            curr_elem =3D elem.tag.split(&quot;}&quot;)[1] if &quot;}&quot; in elem.tag else e=
lem.tag
-
-            if event =3D=3D &quot;start&quot;:
-                if curr_elem =3D=3D row_node:
-                    row =3D {}
-
-            if row is not None:
-                if self.names and iterparse_repeats:
-                    for col, nm in zip(
-                        self.iterparse[row_node], self.names, strict=3DTrue
-                    ):
-                        if curr_elem =3D=3D col:
-                            elem_val =3D elem.text if elem.text else None
-                            if elem_val not in row.values() and nm not in =
row:
-                                row[nm] =3D elem_val
-
-                        if col in elem.attrib:
-                            if elem.attrib[col] not in row.values() and nm=
 not in row:
-                                row[nm] =3D elem.attrib[col]
-                else:
-                    for col in self.iterparse[row_node]:
-                        if curr_elem =3D=3D col:
-                            row[col] =3D elem.text if elem.text else None
-                        if col in elem.attrib:
-                            row[col] =3D elem.attrib[col]
-
-            if event =3D=3D &quot;end&quot;:
-                if curr_elem =3D=3D row_node and row is not None:
-                    dicts.append(row)
-                    row =3D None
-
-                elem.clear()
-                if hasattr(elem, &quot;getprevious&quot;):
-                    while (
-                        elem.getprevious() is not None and elem.getparent(=
) is not None
-                    ):
-                        del elem.getparent()[0]
+        parser =3D iterparse(self.path_or_buffer, events=3D(&quot;start&quot;, &quot;end&quot;=
))
+        try:
+            for event, elem in parser:
+                curr_elem =3D elem.tag.split(&quot;}&quot;)[1] if &quot;}&quot; in elem.tag el=
se elem.tag
+
+                if event =3D=3D &quot;start&quot;:
+                    if curr_elem =3D=3D row_node:
+                        row =3D {}
+
+                if row is not None:
+                    if self.names and iterparse_repeats:
+                        for col, nm in zip(
+                            self.iterparse[row_node], self.names, strict=
=3DTrue
+                        ):
+                            if curr_elem =3D=3D col:
+                                elem_val =3D elem.text if elem.text else N=
one
+                                if elem_val not in row.values() and nm not=
 in row:
+                                    row[nm] =3D elem_val
+
+                            if col in elem.attrib:
+                                if (
+                                    elem.attrib[col] not in row.values()
+                                    and nm not in row
+                                ):
+                                    row[nm] =3D elem.attrib[col]
+                    else:
+                        for col in self.iterparse[row_node]:
+                            if curr_elem =3D=3D col:
+                                row[col] =3D elem.text if elem.text else N=
one
+                            if col in elem.attrib:
+                                row[col] =3D elem.attrib[col]
+
+                if event =3D=3D &quot;end&quot;:
+                    if curr_elem =3D=3D row_node and row is not None:
+                        dicts.append(row)
+                        row =3D None
+
+                    elem.clear()
+                    if hasattr(elem, &quot;getprevious&quot;):
+                        while (
+                            elem.getprevious() is not None
+                            and elem.getparent() is not None
+                        ):
+                            del elem.getparent()[0]
+        finally:
+            if hasattr(parser, &quot;close&quot;):
+                parser.close()
=20
         if dicts =3D=3D []:
             raise ParserError(&quot;No result from selected items in iterparse.=
&quot;)
Index: pandas/pandas/tests/extension/decimal/test_decimal.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/extension/decimal/test_decimal.py
+++ pandas/pandas/tests/extension/decimal/test_decimal.py
@@ -151,7 +151,12 @@ class TestDecimalArray(base.ExtensionTes
         # GH#57723
         # EAs that don't have special logic for None will raise, unlike pa=
ndas'
         # which interpret None as the NA value for the dtype.
-        msg =3D &quot;conversion from NoneType to Decimal is not supported&quot;
+        msg =3D &quot;|&quot;.join(
+            [
+                &quot;Cannot convert None to Decimal&quot;,  # PY315 - maybe linux s=
pecific
+                &quot;conversion from NoneType to Decimal is not supported&quot;,
+            ]
+        )
         with pytest.raises(TypeError, match=3Dmsg):
             super().test_fillna_with_none(data_missing)
=20
Index: pandas/pandas/tests/frame/indexing/test_indexing.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/frame/indexing/test_indexing.py
+++ pandas/pandas/tests/frame/indexing/test_indexing.py
@@ -12,6 +12,7 @@ import pytest
 from pandas._libs import iNaT
 from pandas.errors import InvalidIndexError
=20
+from pandas.compat import PY315
 from pandas.core.dtypes.common import is_integer
=20
 import pandas as pd
@@ -30,7 +31,10 @@ from pandas import (
 import pandas._testing as tm
=20
 # We pass through a TypeError raised by numpy
-_slice_msg =3D &quot;slice indices must be integers or None or have an __index_=
_ method&quot;
+if PY315:
+    _slice_msg =3D &quot;slice indices must be integers or have an __index__ me=
thod&quot;
+else:
+    _slice_msg =3D &quot;slice indices must be integers or None or have an __in=
dex__ method&quot;
=20
=20
 class TestDataFrameIndexing:
Index: pandas/pandas/tests/indexes/period/test_partial_slicing.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/indexes/period/test_partial_slicing.py
+++ pandas/pandas/tests/indexes/period/test_partial_slicing.py
@@ -1,6 +1,8 @@
 import numpy as np
 import pytest
=20
+from pandas.compat import PY315
+
 from pandas import (
     DataFrame,
     PeriodIndex,
@@ -53,7 +55,10 @@ class TestPeriodIndex:
         # GH#6716
         idx =3D make_range(start=3D&quot;2013/01/01&quot;, freq=3D&quot;D&quot;, periods=3D400)
=20
-        msg =3D &quot;slice indices must be integers or None or have an __index=
__ method&quot;
+        if PY315:
+            msg =3D &quot;slice indices must be integers or have an __index__ m=
ethod&quot;
+        else:
+            msg =3D &quot;slice indices must be integers or None or have an __i=
ndex__ method&quot;
         # slices against index should raise IndexError
         values =3D [
             &quot;2014&quot;,
@@ -82,7 +87,10 @@ class TestPeriodIndex:
     def test_range_slice_seconds(self, make_range):
         # GH#6716
         idx =3D make_range(start=3D&quot;2013/01/01 09:00:00&quot;, freq=3D&quot;s&quot;, peri=
ods=3D4000)
-        msg =3D &quot;slice indices must be integers or None or have an __index=
__ method&quot;
+        if PY315:
+            msg =3D &quot;slice indices must be integers or have an __index__ m=
ethod&quot;
+        else:
+            msg =3D &quot;slice indices must be integers or None or have an __i=
ndex__ method&quot;
=20
         # slices against index should raise IndexError
         values =3D [
Index: pandas/pandas/tests/indexes/test_old_base.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/indexes/test_old_base.py
+++ pandas/pandas/tests/indexes/test_old_base.py
@@ -7,6 +7,7 @@ import numpy as np
 import pytest
=20
 from pandas._libs.tslibs import Timestamp
+from pandas.compat import PY315
 from pandas.errors import Pandas4Warning
=20
 from pandas.core.dtypes.common import (
@@ -452,6 +453,8 @@ class TestBase:
         if len(index) =3D=3D 0:
             # 0 vs 0.5 in error message varies with numpy version
             msg =3D &quot;index (0|0.5) is out of bounds for axis 0 with size 0&quot;
+        elif PY315:
+            msg =3D &quot;slice indices must be integers or have an __index__ m=
ethod&quot;
         else:
             msg =3D &quot;slice indices must be integers or None or have an __i=
ndex__ method&quot;
=20
Index: pandas/pandas/tests/indexing/test_floats.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/indexing/test_floats.py
+++ pandas/pandas/tests/indexing/test_floats.py
@@ -1,6 +1,8 @@
 import numpy as np
 import pytest
=20
+from pandas.compat import PY315
+
 from pandas import (
     DataFrame,
     Index,
@@ -251,7 +253,12 @@ class TestFloatIndexers:
         # setitem
         if indexer_sli is tm.iloc:
             # otherwise we keep the same message as above
-            msg =3D &quot;slice indices must be integers or None or have an __i=
ndex__ method&quot;
+            if PY315:
+                msg =3D &quot;slice indices must be integers or have an __index=
__ method&quot;
+            else:
+                msg =3D (
+                    &quot;slice indices must be integers or None or have an __i=
ndex__ method&quot;
+                )
         with pytest.raises(TypeError, match=3Dmsg):
             indexer_sli(s)[idx] =3D 0
=20
Index: pandas/pandas/tests/scalar/timestamp/test_constructors.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/scalar/timestamp/test_constructors.py
+++ pandas/pandas/tests/scalar/timestamp/test_constructors.py
@@ -18,7 +18,10 @@ import pytest
=20
 import pandas.util._test_decorators as td
 from pandas._libs.tslibs.dtypes import NpyDatetimeUnit
-from pandas.compat import PY314
+from pandas.compat import (
+    PY314,
+    PY315,
+)
 from pandas.errors import (
     OutOfBoundsDatetime,
     Pandas4Warning,
@@ -240,7 +243,13 @@ class TestTimestampConstructorPositional
=20
     def test_constructor_keyword(self):
         # GH#10758
-        msg =3D &quot;function missing required argument 'day'|Required argumen=
t 'day'&quot;
+        msg =3D &quot;|&quot;.join(
+            [
+                r&quot;datetime\(\) missing required argument 'day'&quot;,  # PY315
+                &quot;function missing required argument 'day'&quot;,
+                &quot;Required argument 'day'&quot;,
+            ]
+        )
         with pytest.raises(TypeError, match=3Dmsg):
             Timestamp(year=3D2000, month=3D1)
=20
@@ -299,7 +308,15 @@ class TestTimestampConstructorPositional
         # GH#31200
=20
         # The exact error message of datetime() depends on its version
-        msg1 =3D r&quot;function missing required argument '(year|month|day)' \=
(pos [123]\)&quot;
+        if PY315:
+            msg1 =3D (
+                r&quot;datetime\(\) missing required argument &quot;
+                r&quot;'(year|month|day)' \(pos [123]\)&quot;
+            )
+        else:
+            msg1 =3D (
+                r&quot;function missing required argument '(year|month|day)' \(=
pos [123]\)&quot;
+            )
         msg2 =3D r&quot;Required argument '(year|month|day)' \(pos [123]\) not =
found&quot;
         msg =3D &quot;|&quot;.join([msg1, msg2])
=20
Index: pandas/pandas/tests/tools/test_to_datetime.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- pandas.orig/pandas/tests/tools/test_to_datetime.py
+++ pandas/pandas/tests/tools/test_to_datetime.py
@@ -23,6 +23,7 @@ from pandas._libs.tslibs import (
 )
 from pandas.compat import (
     PY314,
+    PY315,
     WASM,
 )
 from pandas.errors import (
@@ -517,6 +518,39 @@ class TestTimeConversionFormats:
         expected =3D DatetimeIndex(expected_dates)
         tm.assert_index_equal(result, expected)
=20
+    @pytest.mark.xfail(
+        not PY315, reason=3D&quot;%:z directive not supported prior to 3.15&quot;, r=
aises=3DValueError
+    )
+    def test_to_datetime_colon_z_offset(self):
+        dates =3D [
+            &quot;2010-01-01 12:00:00+04:00&quot;,
+            &quot;2010-01-01 12:00:00+04:30&quot;,
+            &quot;2010-01-01 12:00:00-05:00&quot;,
+        ]
+        expected_dates =3D [
+            &quot;2010-01-01 08:00:00+00:00&quot;,
+            &quot;2010-01-01 07:30:00+00:00&quot;,
+            &quot;2010-01-01 17:00:00+00:00&quot;,
+        ]
+        fmt =3D &quot;%Y-%m-%d %H:%M:%S%:z&quot;
+
+        result =3D to_datetime(dates, format=3Dfmt, utc=3DTrue)
+        expected =3D DatetimeIndex(expected_dates)
+        tm.assert_index_equal(result, expected)
+
+    def test_to_datetime_missing_colon_z_offset(self):
+        # test adapted from python/cpython#136961
+        dates =3D [&quot;+04:0030&quot;]
+        fmt =3D &quot;%:z&quot;
+
+        if PY315:
+            msg =3D r&quot;Missing colon in %:z before '30', got '\+04:0030'&quot;
+        else:
+            msg =3D &quot;':' is a bad directive in format '%:z'&quot;
+
+        with pytest.raises(ValueError, match=3Dmsg):
+            to_datetime(dates, format=3Dfmt, utc=3DTrue)
+
     @pytest.mark.parametrize(
         &quot;offset&quot;, [&quot;+0&quot;, &quot;-1foo&quot;, &quot;UTCbar&quot;, &quot;:10&quot;, &quot;+01:000:01&quot;, &quot;&quot;]
     )
@@ -1390,9 +1424,12 @@ class TestToDatetime:
     @pytest.mark.parametrize(&quot;errors&quot;, [&quot;coerce&quot;, &quot;raise&quot;])
     def test_invalid_format_raises(self, errors):
         # https://github.com/pandas-dev/pandas/issues/50255
-        with pytest.raises(
-            ValueError, match=3D&quot;':' is a bad directive in format 'H%:M%:S=
%&quot;
-        ):
+        if PY315:
+            msg =3D r&quot;':M' is a bad directive in format 'H%:M%:S%&quot;
+        else:
+            msg =3D &quot;':' is a bad directive in format 'H%:M%:S%&quot;
+
+        with pytest.raises(ValueError, match=3Dmsg):
             to_datetime([&quot;00:00:00&quot;], format=3D&quot;H%:M%:S%&quot;, errors=3Derrors)
=20
     @pytest.mark.parametrize(&quot;value&quot;, [&quot;a&quot;, &quot;00:01:99&quot;])

--PXHuQWrQkjBeVe8E--

--xQGsmXqnhajjBhuJ
Content-Type: application/pgp-signature; name=signature.asc

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

iQIzBAABCgAdFiEE+JIdOnQEyG4RNSIVxxl2mbKbIyoFAmqFvW0ACgkQxxl2mbKb
IyrAgA//Ygzp+W5fEMheXVEQk+psGFvymtZJbrU+H9YAEqD+/6oSvu7MAvSR2ZWC
K8ROBmam3dlfKPO8sRuzuLWtQFY/+86p6GHBaD6XnJYnYEaCnH3nCkpXT4hVpJO1
qiuM2+bF80N5N2Rm0jclatj6/pQmGyYi1ubnS2nfGYNW2JhXptQh7XA4G1erOM0e
+6FDibT9aBWmv4Hd2rd7n9SGDdKxNj/WJ/xWq/Pn2vgHqs1TpP5+4N8qOipl2KeO
d/Q2Wahcz/KH+a/AQwdBZeif4+RoBE3zoX5MQ53kHXOOesz/0tzNSXLBZIFn7zkL
q1Obqu/XkgXX5atJTCY27pnnM9MaetVWZ3LIsEJnC5VwIiIP06h1oVhpNTSohmzU
9VCKVN4pfG94nloQKaRW3FS5TB+MVMdG1FoujAuLVsWUEkFs+Zi39nssEYxwu350
hUMHjPkl8/w8+U1CwfZH6UIdhS9OdER+dMXgXK/dKlvWQQAr5D732Hoja8CSELxt
ZX7creVpLcboUzTuIIOliCV6no44f75mzKEL7+By1rCUsN49RbwATDgmyslQGlU3
BtNo3TRvKxIAcMlhGRg6Q3bhtaGHxUBGty92dK3W5xfUsuRq5pVucyGvyXg0W355
vf1xBNXhViJxO3tR/g3noKf6+mu8H1F16UOGRPbV4+wiIJoKXls=
=lc6u
-----END PGP SIGNATURE-----

--xQGsmXqnhajjBhuJ--
]