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: [email protected], [email protected], 
[email protected], [email protected]
User: [email protected]
Usertags: origin-ubuntu stonking ubuntu-patch
User: [email protected]
Usertags: amd64
User: [email protected]
Usertags: arm64 armhf
User: [email protected]
Usertags: i386
User: [email protected]
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
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 <[email protected]>
+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) -> "Reaction":
+-        """Copy the Reaction.
+-
+-        Returns
+-        -------
+-        Reaction
+-            A new reaction that is a copy of the original reaction.
+-        """
+-        cop = copy(super(Reaction, self))
+-        return cop
+-
+-    def __deepcopy__(self, memo: dict) -> "Reaction":
+-        """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.
+-        """
+-        cop = deepcopy(super(Reaction, self), memo)
+-        return cop
+-
+     @staticmethod
+     def _check_bounds(lb: float, ub: float) -> None:
+         """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

Reply via email to