diff --git a/gnu/local.mk b/gnu/local.mk
index dfafe8b8953..0074805dd40 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -2021,6 +2021,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/python-matplotlib-fix-legend-loc-best-test.patch	\
   %D%/packages/patches/python-random2-getrandbits-test.patch		\
   %D%/packages/patches/python-pillow-use-zlib-1.3.patch	\
+  %D%/packages/patches/python-pulp-exclude-solver-binaries.patch	\
   %D%/packages/patches/python-pydocstyle-add-support-for-pep701.patch	\
   %D%/packages/patches/python-pyreadstat-link-libiconv.patch	\
   %D%/packages/patches/python-sip-include-dirs.patch	\
diff --git a/gnu/packages/patches/python-pulp-exclude-solver-binaries.patch b/gnu/packages/patches/python-pulp-exclude-solver-binaries.patch
new file mode 100644
index 00000000000..57e9a1421b0
--- /dev/null
+++ b/gnu/packages/patches/python-pulp-exclude-solver-binaries.patch
@@ -0,0 +1,36 @@
+This patch excludes solver binary executables that the project uses for
+testing. In the package definition, solvers are provided as native inputs,
+instead.
+
+This is an original patch. It was not submitted upstream.
+
+diff --git a/pyproject.toml b/pyproject.toml
+index 82f9d48..0925858 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -61,26 +61,11 @@ dev = [
+ [tool.setuptools]
+ packages = [
+         "pulp",
+-        "pulp.solverdir",
+-        "pulp.solverdir.cbc.linux.i32",
+-        "pulp.solverdir.cbc.linux.i64",
+-        "pulp.solverdir.cbc.linux.arm64",
+-        "pulp.solverdir.cbc.win.i32",
+-        "pulp.solverdir.cbc.win.i64",
+-        "pulp.solverdir.cbc.osx.i64",
+         "pulp.apis",
+         "pulp.tests"]
+ # This is a workaround for https://github.com/astral-sh/uv/issues/9513
+ license-files = []
+
+-[tool.setuptools.package-data]
+-"pulp.solverdir.cbc.linux.i32"= ["*", "*.*"]
+-"pulp.solverdir.cbc.linux.i64"= ["*", "*.*"]
+-"pulp.solverdir.cbc.linux.arm64"= ["*", "*.*"]
+-"pulp.solverdir.cbc.win.i32"= ["*", "*.*"]
+-"pulp.solverdir.cbc.win.i64"= ["*", "*.*"]
+-"pulp.solverdir.cbc.osx.i64"= ["*", "*.*"]
+-
+ [project.scripts]
+ pulptest = "pulp.tests.run_tests:pulpTestAll"
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 5d0ac818398..923da91821d 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -15037,23 +15037,43 @@ (define-public python-amply
 (define-public python-pulp
   (package
     (name "python-pulp")
-    (version "2.4")
+    (version "3.1.1")
     (source
      (origin
        (method url-fetch)
-       (uri (pypi-uri "PuLP" version))
+       (uri (pypi-uri "pulp" version))
+       ;; https://github.com/coin-or/pulp/issues/832
+       (modules '((guix build utils)))
+       (snippet '(substitute* "pulp/tests/test_pulp.py"
+                   (("        def test_time_limit_no_solution")
+                    "        @unittest.skip
+        def test_time_limit_no_solution")))
        (sha256
-        (base32
-         "1dammrg0f1v0r028i3rpxbf2bsyxmjq0q6ihb4x2wsdki44z3bxj"))))
-    (build-system python-build-system)
-    (propagated-inputs
-     (list python-amply))
+        (base32 "15bdjv0hpzg3lfbz25w16sf4h3gkpd4mhvysgynak73wj47362ih"))
+       (patches (search-patches "python-pulp-exclude-solver-binaries.patch"))))
+    (build-system pyproject-build-system)
+    (native-inputs (list cbc ;a solver for testing
+                         glpk ;a solver for testing
+                         highs ;a solver for testing
+                         python-setuptools
+                         python-wheel))
+    (arguments
+     `(#:phases (modify-phases %standard-phases
+                  (add-before 'build 'remove-solver-binaries
+                    (lambda _
+                      (delete-file-recursively "pulp/solverdir/")))
+                  (replace 'check
+                    (lambda* (#:key tests? #:allow-other-keys)
+                      (if tests?
+                          (invoke "pulptest")))))))
     (home-page "https://github.com/coin-or/pulp")
-    (synopsis "Linear Programming modeler")
+    (synopsis "Python Linear Programming API")
     (description
-     "PuLP is a Linear Programming modeler written in Python.  PuLP can
-generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to
-solve linear problems.")
+     "PuLP is an linear and mixed integer programming modeler written in
+Python.  With PuLP, it is simple to create MILP optimisation problems and solve
+them with the latest open-source (or proprietary) solvers.  PuLP can generate
+MPS or LP files and call solvers such as GLPK, COIN-OR CLP/CBC, CPLEX, GUROBI,
+MOSEK, XPRESS, CHOCO, MIPCL, HiGHS, SCIP/FSCIP.")
     (license license:expat)))
 
 (define-public python-py-partiql-parser
