PuLP 3.3.1__tar.gz → 3.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {pulp-3.3.1 → pulp-3.3.2}/PKG-INFO +19 -12
  2. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/PKG-INFO +19 -12
  3. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/SOURCES.txt +1 -0
  4. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/requires.txt +3 -0
  5. {pulp-3.3.1 → pulp-3.3.2}/README.rst +15 -10
  6. {pulp-3.3.1 → pulp-3.3.2}/pulp/__init__.py +1 -0
  7. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/__init__.py +9 -6
  8. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/coin_api.py +69 -51
  9. {pulp-3.3.1 → pulp-3.3.2}/pulp/constants.py +1 -1
  10. {pulp-3.3.1 → pulp-3.3.2}/pulp/pulp.py +6 -13
  11. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/test_pulp.py +50 -1
  12. pulp-3.3.2/pulp/v4_migration.py +19 -0
  13. {pulp-3.3.1 → pulp-3.3.2}/pyproject.toml +3 -2
  14. {pulp-3.3.1 → pulp-3.3.2}/LICENSE +0 -0
  15. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/dependency_links.txt +0 -0
  16. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/entry_points.txt +0 -0
  17. {pulp-3.3.1 → pulp-3.3.2}/PuLP.egg-info/top_level.txt +0 -0
  18. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/choco_api.py +0 -0
  19. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/copt_api.py +0 -0
  20. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/core.py +0 -0
  21. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/cplex_api.py +0 -0
  22. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/cuopt_api.py +0 -0
  23. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/glpk_api.py +0 -0
  24. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/gurobi_api.py +0 -0
  25. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/highs_api.py +0 -0
  26. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/mipcl_api.py +0 -0
  27. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/mosek_api.py +0 -0
  28. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/sas_api.py +0 -0
  29. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/scip_api.py +0 -0
  30. {pulp-3.3.1 → pulp-3.3.2}/pulp/apis/xpress_api.py +0 -0
  31. {pulp-3.3.1 → pulp-3.3.2}/pulp/mps_lp.py +0 -0
  32. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/__init__.py +0 -0
  33. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/__init__.py +0 -0
  34. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/cbc +0 -0
  35. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/arm64/coin-license.txt +0 -0
  36. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/__init__.py +0 -0
  37. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/cbc +0 -0
  38. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i32/coin-license.txt +0 -0
  39. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/__init__.py +0 -0
  40. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/cbc +0 -0
  41. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/linux/i64/coin-license.txt +0 -0
  42. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/__init__.py +0 -0
  43. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/cbc +0 -0
  44. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/osx/i64/coin-license.txt +0 -0
  45. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/__init__.py +0 -0
  46. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/cbc.exe +0 -0
  47. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i32/coin-license.txt +0 -0
  48. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/__init__.py +0 -0
  49. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/cbc.exe +0 -0
  50. {pulp-3.3.1 → pulp-3.3.2}/pulp/solverdir/cbc/win/i64/coin-license.txt +0 -0
  51. {pulp-3.3.1 → pulp-3.3.2}/pulp/sparse.py +0 -0
  52. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/__init__.py +0 -0
  53. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/bin_packing_problem.py +0 -0
  54. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/run_tests.py +0 -0
  55. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/test_examples.py +0 -0
  56. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/test_gurobipy_env.py +0 -0
  57. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/test_lpdot.py +0 -0
  58. {pulp-3.3.1 → pulp-3.3.2}/pulp/tests/test_sparse.py +0 -0
  59. {pulp-3.3.1 → pulp-3.3.2}/pulp/utilities.py +0 -0
  60. {pulp-3.3.1 → pulp-3.3.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PuLP
3
- Version: 3.3.1
3
+ Version: 3.3.2
4
4
  Summary: PuLP is an LP modeler written in python. PuLP can generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to solve linear problems.
5
5
  Author: J.S. Roy
6
6
  Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
@@ -15,9 +15,11 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Programming Language :: Python
17
17
  Classifier: Topic :: Scientific/Engineering :: Mathematics
18
- Requires-Python: >=3.9
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/x-rst
20
20
  License-File: LICENSE
21
+ Provides-Extra: cbc
22
+ Requires-Dist: cbcbox; extra == "cbc"
21
23
  Provides-Extra: open-py
22
24
  Requires-Dist: highspy==1.13; extra == "open-py"
23
25
  Requires-Dist: pyscipopt; extra == "open-py"
@@ -63,7 +65,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
63
65
  Installation
64
66
  ================
65
67
 
66
- PuLP requires Python 3.9 or newer.
68
+ PuLP requires Python 3.10 or newer.
67
69
 
68
70
  The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
69
71
 
@@ -74,8 +76,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
74
76
  Installing solvers
75
77
  ----------------------
76
78
 
77
- PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver, which is included with PuLP. If you want to use other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
79
+ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
78
80
 
81
+ python -m pip install pulp[cbc]
82
+
83
+ If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
84
+
85
+ To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
86
+
87
+ python -m pip install pulp[cbc]
79
88
  python -m pip install pulp[gurobi]
80
89
  python -m pip install pulp[cplex]
81
90
  python -m pip install pulp[xpress]
@@ -108,10 +117,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
108
117
 
109
118
  prob += -4*x + y
110
119
 
111
- To solve the problem with the default included solver::
120
+ To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
112
121
 
113
122
  status = prob.solve()
114
123
 
124
+ To solve explicitly with CBC::
125
+
126
+ status = prob.solve(COIN_CMD(msg=0))
127
+
115
128
  If you want to try another solver to solve the problem::
116
129
 
117
130
  status = prob.solve(GLPK(msg = 0))
@@ -151,7 +164,7 @@ More Examples
151
164
 
152
165
  Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
153
166
 
154
- The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
167
+ The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
155
168
 
156
169
 
157
170
  For Developers
@@ -163,12 +176,6 @@ If you want to install the latest version from GitHub you can run::
163
176
  python -m pip install -U git+https://github.com/coin-or/pulp
164
177
 
165
178
 
166
- On Linux and MacOS systems, you must run the tests to make the default solver executable::
167
-
168
- sudo pulptest
169
-
170
-
171
-
172
179
 
173
180
  Building the documentation
174
181
  --------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PuLP
3
- Version: 3.3.1
3
+ Version: 3.3.2
4
4
  Summary: PuLP is an LP modeler written in python. PuLP can generate MPS or LP files and call GLPK, COIN CLP/CBC, CPLEX, and GUROBI to solve linear problems.
5
5
  Author: J.S. Roy
6
6
  Author-email: "S.A. Mitchell" <pulp@stuartmitchell.com>, Franco Peschiera <pchtsp@gmail.com>
@@ -15,9 +15,11 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Programming Language :: Python
17
17
  Classifier: Topic :: Scientific/Engineering :: Mathematics
18
- Requires-Python: >=3.9
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/x-rst
20
20
  License-File: LICENSE
21
+ Provides-Extra: cbc
22
+ Requires-Dist: cbcbox; extra == "cbc"
21
23
  Provides-Extra: open-py
22
24
  Requires-Dist: highspy==1.13; extra == "open-py"
23
25
  Requires-Dist: pyscipopt; extra == "open-py"
@@ -63,7 +65,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
63
65
  Installation
64
66
  ================
65
67
 
66
- PuLP requires Python 3.9 or newer.
68
+ PuLP requires Python 3.10 or newer.
67
69
 
68
70
  The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
69
71
 
@@ -74,8 +76,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
74
76
  Installing solvers
75
77
  ----------------------
76
78
 
77
- PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver, which is included with PuLP. If you want to use other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
79
+ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
78
80
 
81
+ python -m pip install pulp[cbc]
82
+
83
+ If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
84
+
85
+ To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
86
+
87
+ python -m pip install pulp[cbc]
79
88
  python -m pip install pulp[gurobi]
80
89
  python -m pip install pulp[cplex]
81
90
  python -m pip install pulp[xpress]
@@ -108,10 +117,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
108
117
 
109
118
  prob += -4*x + y
110
119
 
111
- To solve the problem with the default included solver::
120
+ To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
112
121
 
113
122
  status = prob.solve()
114
123
 
124
+ To solve explicitly with CBC::
125
+
126
+ status = prob.solve(COIN_CMD(msg=0))
127
+
115
128
  If you want to try another solver to solve the problem::
116
129
 
117
130
  status = prob.solve(GLPK(msg = 0))
@@ -151,7 +164,7 @@ More Examples
151
164
 
152
165
  Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
153
166
 
154
- The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
167
+ The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
155
168
 
156
169
 
157
170
  For Developers
@@ -163,12 +176,6 @@ If you want to install the latest version from GitHub you can run::
163
176
  python -m pip install -U git+https://github.com/coin-or/pulp
164
177
 
165
178
 
166
- On Linux and MacOS systems, you must run the tests to make the default solver executable::
167
-
168
- sudo pulptest
169
-
170
-
171
-
172
179
 
173
180
  Building the documentation
174
181
  --------------------------
@@ -13,6 +13,7 @@ pulp/mps_lp.py
13
13
  pulp/pulp.py
14
14
  pulp/sparse.py
15
15
  pulp/utilities.py
16
+ pulp/v4_migration.py
16
17
  pulp/apis/__init__.py
17
18
  pulp/apis/choco_api.py
18
19
  pulp/apis/coin_api.py
@@ -1,4 +1,7 @@
1
1
 
2
+ [cbc]
3
+ cbcbox
4
+
2
5
  [copt]
3
6
  coptpy
4
7
 
@@ -19,7 +19,7 @@ PuLP is part of the `COIN-OR project <https://www.coin-or.org/>`_.
19
19
  Installation
20
20
  ================
21
21
 
22
- PuLP requires Python 3.9 or newer.
22
+ PuLP requires Python 3.10 or newer.
23
23
 
24
24
  The easiest way to install PuLP is with ``pip``. If ``pip`` is available on your system, type::
25
25
 
@@ -30,8 +30,15 @@ Otherwise follow the download instructions on the `PyPi page <https://pypi.pytho
30
30
  Installing solvers
31
31
  ----------------------
32
32
 
33
- PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver, which is included with PuLP. If you want to use other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
33
+ PuLP can use a variety of solvers. The default solver is the COIN-OR CBC solver via the ``COIN_CMD`` API. Install CBC with::
34
34
 
35
+ python -m pip install pulp[cbc]
36
+
37
+ If CBC is not available on your system, PuLP falls back to other solvers such as the legacy bundled CBC (``PULP_CBC_CMD``) or GLPK.
38
+
39
+ To install other solvers, PuLP offers a quick way to install most solvers via their pypi package (some require a commercial license for running or for running large models)::
40
+
41
+ python -m pip install pulp[cbc]
35
42
  python -m pip install pulp[gurobi]
36
43
  python -m pip install pulp[cplex]
37
44
  python -m pip install pulp[xpress]
@@ -64,10 +71,14 @@ An expression is a constraint without a right-hand side (RHS) sense (one of ``=`
64
71
 
65
72
  prob += -4*x + y
66
73
 
67
- To solve the problem with the default included solver::
74
+ To solve the problem with the default solver (CBC via ``COIN_CMD`` when installed with ``pulp[cbc]``)::
68
75
 
69
76
  status = prob.solve()
70
77
 
78
+ To solve explicitly with CBC::
79
+
80
+ status = prob.solve(COIN_CMD(msg=0))
81
+
71
82
  If you want to try another solver to solve the problem::
72
83
 
73
84
  status = prob.solve(GLPK(msg = 0))
@@ -107,7 +118,7 @@ More Examples
107
118
 
108
119
  Several tutorial are given in `documentation <https://coin-or.github.io/pulp/CaseStudies/index.html>`_ and pure code examples are available in `examples/ directory <https://github.com/coin-or/pulp/tree/master/examples>`_ .
109
120
 
110
- The examples use the default solver (CBC). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
121
+ The examples use the default solver (CBC via ``COIN_CMD`` when available). To use other solvers they must be available (installed and accessible). For more information on how to do that, see the `guide on configuring solvers <https://coin-or.github.io/pulp/guides/how_to_configure_solvers.html>`_.
111
122
 
112
123
 
113
124
  For Developers
@@ -119,12 +130,6 @@ If you want to install the latest version from GitHub you can run::
119
130
  python -m pip install -U git+https://github.com/coin-or/pulp
120
131
 
121
132
 
122
- On Linux and MacOS systems, you must run the tests to make the default solver executable::
123
-
124
- sudo pulptest
125
-
126
-
127
-
128
133
 
129
134
  Building the documentation
130
135
  --------------------------
@@ -56,6 +56,7 @@ except Exception:
56
56
 
57
57
  from .constants import VERSION
58
58
 
59
+ from .v4_migration import set_v4_migration_warnings
59
60
  from .pulp import *
60
61
  from .apis import *
61
62
  from .utilities import *
@@ -45,14 +45,14 @@ _all_solvers: List[Type[LpSolver]] = [
45
45
  CUOPT,
46
46
  ]
47
47
 
48
- LpSolverDefault: Optional[Union[PULP_CBC_CMD, GLPK_CMD, COIN_CMD]] = None
48
+ LpSolverDefault: Optional[Union[COIN_CMD, PULP_CBC_CMD, GLPK_CMD]] = None
49
49
  # Default solver selection
50
- if PULP_CBC_CMD().available():
51
- LpSolverDefault = PULP_CBC_CMD()
50
+ if COIN_CMD().available():
51
+ LpSolverDefault = COIN_CMD()
52
+ elif PULP_CBC_CMD(_skip_v4_deprecation=True).available():
53
+ LpSolverDefault = PULP_CBC_CMD(_skip_v4_deprecation=True)
52
54
  elif GLPK_CMD().available():
53
55
  LpSolverDefault = GLPK_CMD()
54
- elif COIN_CMD().available():
55
- LpSolverDefault = COIN_CMD()
56
56
 
57
57
 
58
58
  def getSolver(solver: str, *args, **kwargs) -> LpSolver:
@@ -116,7 +116,10 @@ def listSolvers(onlyAvailable: bool = False) -> List[str]:
116
116
  """
117
117
  result = []
118
118
  for s in _all_solvers:
119
- solver = s(msg=False)
119
+ kwargs: Dict[str, Union[str, bool, float, int]] = {"msg": False}
120
+ if s is PULP_CBC_CMD:
121
+ kwargs["_skip_v4_deprecation"] = True
122
+ solver = s(**kwargs)
120
123
  if (not onlyAvailable) or solver.available():
121
124
  result.append(solver.name)
122
125
  del solver
@@ -48,9 +48,9 @@ import ctypes
48
48
  import warnings
49
49
  from tempfile import mktemp
50
50
 
51
+ from ..v4_migration import v4_deprecation
52
+
51
53
  cbc_path = "cbc"
52
- if operating_system == "win":
53
- cbc_path += ".exe"
54
54
 
55
55
  coinMP_path = ["libCoinMP.so"]
56
56
  # workaround for (https://github.com/coin-or/pulp/issues/802)
@@ -60,6 +60,15 @@ pulp_cbc_path = os.path.join(
60
60
  os.path.dirname(__file__), f"../solverdir/cbc/{operating_system}/{arch}/{cbc_path}"
61
61
  )
62
62
 
63
+ PULP_CBC_CMD_DEPRECATION_MSG = (
64
+ "PULP_CBC_CMD is deprecated and will be removed in PuLP 4.0. "
65
+ "Install CBC with `pip install pulp[cbc]` and use COIN_CMD instead."
66
+ )
67
+
68
+
69
+ def warn_pulp_cbc_cmd_deprecated(*, stacklevel: int = 2) -> None:
70
+ v4_deprecation(PULP_CBC_CMD_DEPRECATION_MSG, stacklevel=stacklevel)
71
+
63
72
 
64
73
  class COIN_CMD(LpSolver_CMD):
65
74
  """The COIN CLP/CBC LP solver
@@ -192,7 +201,7 @@ class COIN_CMD(LpSolver_CMD):
192
201
  for option in options:
193
202
  cmds += "-" + option + " "
194
203
  if self.mip:
195
- cmds += "-branch "
204
+ cmds += "-solve "
196
205
  else:
197
206
  cmds += "-initialSolve "
198
207
  cmds += "-printingOptions all "
@@ -363,11 +372,15 @@ COIN = COIN_CMD
363
372
 
364
373
  class PULP_CBC_CMD(COIN_CMD):
365
374
  """
366
- This solver uses a precompiled version of cbc provided with the package
375
+ Legacy solver that uses a precompiled version of cbc bundled with PuLP.
376
+
377
+ Deprecated: will be removed in PuLP 4.0. Install CBC with
378
+ ``pip install pulp[cbc]`` and use :class:`COIN_CMD` instead.
367
379
  """
368
380
 
369
381
  name = "PULP_CBC_CMD"
370
- pulp_cbc_path = pulp_cbc_path
382
+ pulp_cbc_path = COIN_CMD.executableExtension(pulp_cbc_path)
383
+ _permissions_ok = True
371
384
  try:
372
385
  if os.name != "nt":
373
386
  if not os.access(pulp_cbc_path, os.X_OK):
@@ -375,61 +388,66 @@ class PULP_CBC_CMD(COIN_CMD):
375
388
 
376
389
  os.chmod(pulp_cbc_path, stat.S_IXUSR + stat.S_IXOTH)
377
390
  except: # probably due to incorrect permissions
391
+ _permissions_ok = False
378
392
 
379
- def available(self):
380
- """True if the solver is available"""
393
+ def available(self):
394
+ """True if the solver is available"""
395
+ if not self._permissions_ok:
381
396
  return False
397
+ return super().available()
382
398
 
383
- def actualSolve(self, lp, callback=None):
384
- """Solve a well formulated lp problem"""
399
+ def actualSolve(self, lp, **kwargs):
400
+ """Solve a well formulated lp problem"""
401
+ if not self._permissions_ok:
385
402
  raise PulpSolverError(
386
403
  "PULP_CBC_CMD: Not Available (check permissions on %s)"
387
404
  % self.pulp_cbc_path
388
405
  )
406
+ return super().actualSolve(lp, **kwargs)
389
407
 
390
- else:
391
-
392
- def __init__(
408
+ def __init__(
409
+ self,
410
+ mip=True,
411
+ msg=True,
412
+ timeLimit=None,
413
+ gapRel=None,
414
+ gapAbs=None,
415
+ presolve=None,
416
+ cuts=None,
417
+ strong=None,
418
+ options=None,
419
+ warmStart=False,
420
+ keepFiles=False,
421
+ path=None,
422
+ threads=None,
423
+ logPath=None,
424
+ timeMode="elapsed",
425
+ maxNodes=None,
426
+ _skip_v4_deprecation: bool = False,
427
+ ):
428
+ if not _skip_v4_deprecation:
429
+ warn_pulp_cbc_cmd_deprecated(stacklevel=2)
430
+ if path is not None:
431
+ raise PulpSolverError("Use COIN_CMD if you want to set a path")
432
+ COIN_CMD.__init__(
393
433
  self,
394
- mip=True,
395
- msg=True,
396
- timeLimit=None,
397
- gapRel=None,
398
- gapAbs=None,
399
- presolve=None,
400
- cuts=None,
401
- strong=None,
402
- options=None,
403
- warmStart=False,
404
- keepFiles=False,
405
- path=None,
406
- threads=None,
407
- logPath=None,
408
- timeMode="elapsed",
409
- maxNodes=None,
410
- ):
411
- if path is not None:
412
- raise PulpSolverError("Use COIN_CMD if you want to set a path")
413
- # check that the file is executable
414
- COIN_CMD.__init__(
415
- self,
416
- path=self.pulp_cbc_path,
417
- mip=mip,
418
- msg=msg,
419
- timeLimit=timeLimit,
420
- gapRel=gapRel,
421
- gapAbs=gapAbs,
422
- presolve=presolve,
423
- cuts=cuts,
424
- strong=strong,
425
- options=options,
426
- warmStart=warmStart,
427
- keepFiles=keepFiles,
428
- threads=threads,
429
- logPath=logPath,
430
- timeMode=timeMode,
431
- maxNodes=maxNodes,
432
- )
434
+ path=self.pulp_cbc_path,
435
+ mip=mip,
436
+ msg=msg,
437
+ timeLimit=timeLimit,
438
+ gapRel=gapRel,
439
+ gapAbs=gapAbs,
440
+ presolve=presolve,
441
+ cuts=cuts,
442
+ strong=strong,
443
+ options=options,
444
+ warmStart=warmStart,
445
+ keepFiles=keepFiles,
446
+ threads=threads,
447
+ logPath=logPath,
448
+ timeMode=timeMode,
449
+ maxNodes=maxNodes,
450
+ )
433
451
 
434
452
 
435
453
  def COINMP_DLL_load_dll(path: list[str]):
@@ -28,7 +28,7 @@ This file contains the constant definitions for PuLP
28
28
  Note that hopefully these will be changed into something more pythonic
29
29
  """
30
30
 
31
- VERSION = "3.3.1"
31
+ VERSION = "3.3.2"
32
32
  EPS = 1e-7
33
33
 
34
34
  # variable categories
@@ -133,6 +133,7 @@ from time import time
133
133
  from typing import Any, Dict, Literal, Optional, Union, cast, overload
134
134
 
135
135
  from .apis import LpSolverDefault, PULP_CBC_CMD
136
+ from .apis.coin_api import warn_pulp_cbc_cmd_deprecated
136
137
  from .apis.core import clock
137
138
  from .utilities import value
138
139
  from . import constants as const
@@ -151,19 +152,7 @@ except ImportError:
151
152
 
152
153
  import re
153
154
 
154
- V4_MIGRATION_WARNINGS = True
155
-
156
-
157
- def set_v4_migration_warnings(enabled: bool) -> None:
158
- """Enable or disable PuLP 4.0 migration DeprecationWarnings (default: enabled)."""
159
-
160
- global V4_MIGRATION_WARNINGS
161
- V4_MIGRATION_WARNINGS = enabled
162
-
163
-
164
- def _v4_deprecation(message: str, stacklevel: int = 2) -> None:
165
- if V4_MIGRATION_WARNINGS:
166
- warnings.warn(message, category=DeprecationWarning, stacklevel=stacklevel)
155
+ from .v4_migration import v4_deprecation as _v4_deprecation
167
156
 
168
157
 
169
158
  class LpElement:
@@ -2410,6 +2399,8 @@ class LpProblem:
2410
2399
  solver = self.solver
2411
2400
  if not (solver):
2412
2401
  solver = LpSolverDefault
2402
+ if isinstance(solver, PULP_CBC_CMD):
2403
+ warn_pulp_cbc_cmd_deprecated(stacklevel=3)
2413
2404
  wasNone, dummyVar = self.fixObjective()
2414
2405
  # time it
2415
2406
  self.startClock()
@@ -2452,6 +2443,8 @@ class LpProblem:
2452
2443
  solver = self.solver
2453
2444
  if not (solver):
2454
2445
  solver = LpSolverDefault
2446
+ if isinstance(solver, PULP_CBC_CMD):
2447
+ warn_pulp_cbc_cmd_deprecated(stacklevel=3)
2455
2448
  if not (absoluteTols):
2456
2449
  absoluteTols = [0] * len(objectives)
2457
2450
  if not (relativeTols):
@@ -10,6 +10,7 @@ import unittest
10
10
  import warnings
11
11
  from decimal import Decimal
12
12
  from typing import Union, Optional, Type
13
+ from unittest.mock import patch
13
14
 
14
15
 
15
16
  from pulp import (
@@ -1342,7 +1343,7 @@ class BaseSolverTest:
1342
1343
  time_limit = 10
1343
1344
  solver_settings = dict(
1344
1345
  PULP_CBC_CMD=30,
1345
- COIN_CMD=30,
1346
+ COIN_CMD=20,
1346
1347
  SCIP_PY=30,
1347
1348
  SCIP_CMD=30,
1348
1349
  GUROBI_CMD=50,
@@ -1901,6 +1902,11 @@ class BaseSolverTest:
1901
1902
  class PULP_CBC_CMDTest(BaseSolverTest.PuLPTest):
1902
1903
  solveInst = solvers.PULP_CBC_CMD
1903
1904
 
1905
+ def setUp(self):
1906
+ with warnings.catch_warnings():
1907
+ warnings.simplefilter("ignore", DeprecationWarning)
1908
+ super().setUp()
1909
+
1904
1910
  @staticmethod
1905
1911
  def read_command_line_from_log_file(logPath):
1906
1912
  """
@@ -2534,6 +2540,49 @@ class PuLP4MigrationTests(unittest.TestCase):
2534
2540
  set_v4_migration_warnings(True)
2535
2541
 
2536
2542
 
2543
+ class PULP_CBC_CMDDeprecationTest(unittest.TestCase):
2544
+ def test_pulp_cbc_cmd_deprecation_warns(self) -> None:
2545
+ set_v4_migration_warnings(True)
2546
+ try:
2547
+ with self.assertWarns(DeprecationWarning):
2548
+ solvers.PULP_CBC_CMD()
2549
+ finally:
2550
+ set_v4_migration_warnings(True)
2551
+
2552
+ def test_pulp_cbc_cmd_deprecation_respects_v4_flag(self) -> None:
2553
+ set_v4_migration_warnings(False)
2554
+ try:
2555
+ with warnings.catch_warnings():
2556
+ warnings.simplefilter("error", DeprecationWarning)
2557
+ solvers.PULP_CBC_CMD()
2558
+ finally:
2559
+ set_v4_migration_warnings(True)
2560
+
2561
+ def test_pulp_cbc_cmd_skip_v4_deprecation(self) -> None:
2562
+ set_v4_migration_warnings(True)
2563
+ try:
2564
+ with warnings.catch_warnings():
2565
+ warnings.simplefilter("error", DeprecationWarning)
2566
+ solvers.PULP_CBC_CMD(_skip_v4_deprecation=True)
2567
+ finally:
2568
+ set_v4_migration_warnings(True)
2569
+
2570
+ def test_solve_with_pulp_cbc_default_warns(self) -> None:
2571
+ set_v4_migration_warnings(True)
2572
+ default_solver = solvers.PULP_CBC_CMD(_skip_v4_deprecation=True)
2573
+ prob = LpProblem("m")
2574
+ prob.add_variable("x")
2575
+ try:
2576
+ with patch("pulp.pulp.LpSolverDefault", default_solver):
2577
+ with patch.object(
2578
+ default_solver, "actualSolve", return_value=const.LpStatusOptimal
2579
+ ):
2580
+ with self.assertWarns(DeprecationWarning):
2581
+ prob.solve()
2582
+ finally:
2583
+ set_v4_migration_warnings(True)
2584
+
2585
+
2537
2586
  def getSortedDict(prob, keyCons="name", keyVars="name"):
2538
2587
  _dict = prob.toDict()
2539
2588
  _dict["constraints"].sort(key=lambda v: v[keyCons])
@@ -0,0 +1,19 @@
1
+ """PuLP 4.0 migration deprecation warnings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import warnings
6
+
7
+ V4_MIGRATION_WARNINGS = True
8
+
9
+
10
+ def set_v4_migration_warnings(enabled: bool) -> None:
11
+ """Enable or disable PuLP 4.0 migration DeprecationWarnings (default: enabled)."""
12
+
13
+ global V4_MIGRATION_WARNINGS
14
+ V4_MIGRATION_WARNINGS = enabled
15
+
16
+
17
+ def v4_deprecation(message: str, stacklevel: int = 2) -> None:
18
+ if V4_MIGRATION_WARNINGS:
19
+ warnings.warn(message, category=DeprecationWarning, stacklevel=stacklevel)
@@ -9,7 +9,7 @@ authors = [
9
9
  ]
10
10
  maintainers= [{name= "Franco Peschiera", email= "pchtsp@gmail.com"}]
11
11
  dependencies = []
12
- requires-python = ">=3.9"
12
+ requires-python = ">=3.10"
13
13
  readme = "README.rst"
14
14
  license = "MIT"
15
15
  license-files = ["LICENSE"]
@@ -80,7 +80,7 @@ pulptest = "pulp.tests.run_tests:pulpTestAll"
80
80
 
81
81
  [tool.black]
82
82
  line-length = 88
83
- target-version = ['py37']
83
+ target-version = ['py310']
84
84
  include = '\.pyi?$'
85
85
  exclude = '/(\.eggs|\.git|\.hg|\.mypy_cache|\.tox|\.venv|_build|buck-out|build|dist)/'
86
86
 
@@ -91,6 +91,7 @@ required-environments = [
91
91
 
92
92
 
93
93
  [project.optional-dependencies]
94
+ cbc = ["cbcbox"]
94
95
  open_py = ["highspy==1.13", "pyscipopt"]
95
96
  public_py = ["gurobipy", "coptpy", 'xpress', "cplex; sys_platform != 'darwin' or python_full_version < '3.12'"]
96
97
  highs = ["highspy==1.13"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes