coin-or / coin-or/pulp

TypeError when LpAffineExpressions are Specified Using Decimals

Open
#815 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
2.5k
Forks
432
PR merge metrics
No merged PRs in 30d

Description

When a LpAffineExpression is extended using Decimals, as of pulp 2.9.0 (and before), it would work without raising any exception and returning accurate results. Beginning in 3.0.0, it now raises a TypeError in the addInPlace method:

`self.constant += other.constant * sign `

A reproducing pytest file which can be run, passing in 2.9.0, and failing in 3.0.2(or 3.0.0): https://gist.github.com/mark92223/e590c21df931eda1927ae4230fec118d .

Is using Decimals in this context unsupported in Pulp?

Thank you!

Details for the issue
--------------------

#### What did you do?

#### What did you expect to see?
The test to pass
#### What did you see instead?
```
def test_it(self):
from pulp import LpProblem, LpVariable, LpMaximize, LpAffineExpression
from pulp.apis import GLPK_CMD

m1, m2, extra = 3, Decimal("8.1"), 5

problem = LpProblem("graph", LpMaximize)
y = LpVariable("y", lowBound=0, upBound=Decimal("32.24"), cat="Continuous")
problem += y

expression = LpAffineExpression()
include_extra = LpVariable("include_extra1", cat="Binary")
x = LpVariable("x", lowBound=0,
upBound=random.randint(3, 50), cat="Continuous")
# y = 3x + 5 | y = 3x
expression += x * m1 + include_extra*extra - y
problem += expression == 0

second_expression = LpAffineExpression()
# y = 8.1x - 6
> second_expression += x * m2 - 6 - y

test_pypi_packages_for_wms.py:125:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/mark/ve3.13/lib/python3.13/site-packages/pulp/pulp.py:928: in __iadd__
return self.addInPlace(other)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = 0.0, other = 8.1*x + -1*y + -6.0, sign = 1

def addInPlace(self, other, sign=1):
"""
:param int sign: the sign of the operation to do other.
if we add other => 1
if we subtract other => -1
"""
if isinstance(other, int) and (other == 0):
return self
if other is None:
return self
if isinstance(other, LpElement):
# if a variable, we add it to the dictionary
self.addterm(other, sign)
elif isinstance(other, (LpAffineExpression, LpConstraint)):
# if an expression, we add each variable and the constant
> self.constant += other.constant * sign
E TypeError: unsupported operand type(s) for +=: 'float' and 'decimal.Decimal'

/home/mark/ve3.13/lib/python3.13/site-packages/pulp/pulp.py:888: TypeError
```

Useful extra information
-------------------------

The info below often helps, please fill it out if you're able to. :)

#### What operating system are you using?

- [ ] Windows: ( _version:_ ___ )
- [x] Linux: (Arch Linux)
- [ ] Mac OS: ( _version:_ ___ )
- [ ] Other: ___

#### I'm using python version:

- [ ] 3.7
- [ ] 3.8
- [ ] 3.9
- [ ] 3.10
- [ ] 3.11
- [x] Other: 3.13

#### I installed PuLP via:

- [x] pypi (python -m pip install pulp)
- [ ] github (python -m pip install -U git+https://github.com/coin-or/pulp)
- [ ] Other: ___ (conda?)

#### Did you also

- [ ] Tried out the latest github version: https://github.com/coin-or/pulp
- [x] Searched for an existing similar issue: https://github.com/coin-or/pulp/issues?utf8=%E2%9C%93&q=is%3Aissue%20

Contributor guide

Open the contributing guide

Research direction

Run the linked pytest reproducer against the current PuLP version first. Then inspect pulp.py's LpAffineExpression.addInPlace method and the Decimal handling around the failing operation. Done means the reproducer passes and the reported accurate results are preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.