[From nobody Tue Jun  2 17:07:04 2026
Received: (at submit) by bugs.debian.org; 29 May 2026 15:13:37 +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=-18.9 required=4.0 tests=BAYES_00,
 BODY_INCLUDES_PACKAGE,FOURLA,FVGT_m_MULTI_ODD,GMAIL,HAS_PACKAGE,
 MD5_SHA1_SUM,NO_RELAYS,XMAILER_REPORTBUG autolearn=ham
 autolearn_force=no version=4.0.1-bugs.debian.org_2005_01_02
X-Spam-Bayes: score:0.0000 Tokens: new, 59; hammy, 150; neutral, 231; spammy,
 0. spammytokens: hammytokens:0.000-+--XDebbugsCc,
 0.000-+--X-Debbugs-Cc, 0.000-+--armhf, 0.000-+--H*Ad:N*Bug,
 0.000-+--H*Ad:N*Tracking
Return-path: &lt;ujjwal.sarswat@canonical.com&gt;
Received: via submission by buxtehude.debian.org with esmtp (Exim 4.96)
 (envelope-from &lt;ujjwal.sarswat@canonical.com&gt;) id 1wSytz-00FrSv-2B
 for submit@bugs.debian.org; Fri, 29 May 2026 15:13:37 +0000
Content-Type: multipart/mixed; boundary=&quot;===============3995393947754011396==&quot;
MIME-Version: 1.0
From: Ujjwal Sarswat &lt;ujjwal.sarswat@canonical.com&gt;
To: Debian Bug Tracking System &lt;submit@bugs.debian.org&gt;
Subject: python-cobra: infinite recursion and GPR deepcopy failures on Python
 3.14
Message-ID: &lt;178006760933.1048326.17786925951261145316.reportbug@carbon&gt;
X-Mailer: reportbug 13.2.0+ubuntu1
Date: Fri, 29 May 2026 20:43:29 +0530
Delivered-To: submit@bugs.debian.org

This is a multi-part MIME message sent by reportbug.


--===============3995393947754011396==
Content-Type: text/plain; charset=&quot;us-ascii&quot;
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Package: python-cobra
Version: 0.29.1-5
Severity: serious
Tags: patch ftbfs
Justification: fails to build from source (but built successfully in the past)
X-Debbugs-Cc: debian-amd64@lists.debian.org, debian-arm@lists.debian.org, debian-powerpc@lists.debian.org, ujjwal.sarswat@canonical.com
User: ubuntu-devel@lists.ubuntu.com
Usertags: origin-ubuntu stonking ubuntu-patch
User: debian-amd64@lists.debian.org
Usertags: amd64
User: debian-arm@lists.debian.org
Usertags: arm64 armhf
User: debian-qa@lists.debian.org
Usertags: i386
User: debian-powerpc@lists.debian.org
Usertags: ppc64el

Dear Maintainer,

In Python 3.14, two related regressions were introduced in cobrapy:

1. `deepcopy(super(Reaction, self), memo)` no longer short-circuits via the
   memo dict, causing `Reaction.__deepcopy__` to call itself indefinitely and
   raise a RecursionError (LP: #2154412,
   https://github.com/opencobra/cobrapy/issues/1474).

2. `ast.Module.__reduce__` now returns three positional arguments, which
   `GPR.__init__` cannot accept, causing deepcopy of any model containing GPR
   objects to fail with a TypeError (LP: #2154413,
   https://github.com/opencobra/cobrapy/issues/1475).

Both failures are triggered by the presence of the custom `__copy__` and
`__deepcopy__` overrides on `Reaction`. Removing them lets Python's default
copy machinery handle `Reaction` and the `GPR` objects it references correctly,
without requiring any manual workaround. The fix is minimal and has been
verified against the upstream test suite. Upstream has a fix PR merged
and should be available soon in debian after a new release:
https://github.com/opencobra/cobrapy/pull/1471

In Ubuntu, the attached patch was applied to achieve the following:

  * d/p/python-314.patch: remove Reaction.__copy__ and __deepcopy__,
    fixing infinite recursion and GPR deepcopy failures on Python 3.14
    (LP: #2154412, LP: #2154413)


Thanks for considering the patch.

-- System Information:
Debian Release: forky/sid
  APT prefers resolute-updates
  APT policy: (500, 'resolute-updates'), (500, 'resolute-security'), (500, 'resolute')
Architecture: amd64 (x86_64)

Kernel: Linux 7.0.0-15-generic (SMP w/16 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

--===============3995393947754011396==
Content-Type: text/plain; charset=&quot;us-ascii&quot;
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=&quot;python-cobra_0.29.1-5.debdiff&quot;

diff -Nru python-cobra-0.29.1/debian/patches/python-314.patch python-cobra-0.29.1/debian/patches/python-314.patch
--- python-cobra-0.29.1/debian/patches/python-314.patch	1970-01-01 05:30:00.000000000 +0530
+++ python-cobra-0.29.1/debian/patches/python-314.patch	2026-05-28 18:00:33.000000000 +0530
@@ -0,0 +1,45 @@
+Description: Remove Reaction.__copy__ and __deepcopy__, broken in Python 3.14
+ The super()-based overrides cause infinite recursion and GPR deepcopy
+ failures in Python 3.14. Removing them lets the default copy machinery
+ handle both correctly.
+Author: Christian Diener &lt;ch.diener@gmail.com&gt;
+Origin: upstream, https://github.com/opencobra/cobrapy/commit/c4a09043c0b378bfbecf597d89020b85eafb5737
+Bug: https://github.com/opencobra/cobrapy/issues/1474
+Bug: https://github.com/opencobra/cobrapy/issues/1475
+Last-Update: 2026-05-29
+--- a/src/cobra/core/reaction.py
++++ b/src/cobra/core/reaction.py
+@@ -246,33 +246,6 @@
+         if self.flux_expression is not None:
+             set_objective(self.model, {self: value}, additive=True)
+ 
+-    def __copy__(self) -&gt; &quot;Reaction&quot;:
+-        &quot;&quot;&quot;Copy the Reaction.
+-
+-        Returns
+-        -------
+-        Reaction
+-            A new reaction that is a copy of the original reaction.
+-        &quot;&quot;&quot;
+-        cop = copy(super(Reaction, self))
+-        return cop
+-
+-    def __deepcopy__(self, memo: dict) -&gt; &quot;Reaction&quot;:
+-        &quot;&quot;&quot;Copy the reaction with memo.
+-
+-        Parameters
+-        ----------
+-        memo: dict
+-            Automatically passed parameter.
+-
+-        Returns
+-        -------
+-        Reaction
+-            A new reaction that is a deep copy of the original reaction with memo.
+-        &quot;&quot;&quot;
+-        cop = deepcopy(super(Reaction, self), memo)
+-        return cop
+-
+     @staticmethod
+     def _check_bounds(lb: float, ub: float) -&gt; None:
+         &quot;&quot;&quot;Check if the lower and upper bounds are valid.
diff -Nru python-cobra-0.29.1/debian/patches/series python-cobra-0.29.1/debian/patches/series
--- python-cobra-0.29.1/debian/patches/series	2026-02-27 19:43:42.000000000 +0530
+++ python-cobra-0.29.1/debian/patches/series	2026-05-28 18:00:33.000000000 +0530
@@ -6,3 +6,4 @@
 remove-appdirs.patch
 a2b9d00a04b85b8c8eb12e4deba29ce2147896cf.patch
 pr1452.patch
+python-314.patch

--===============3995393947754011396==--
]