Open
Description
Summary
In event a Constraint
expression contains a SumExpression
obtained through the core.util.replace_expressions
function, an AttributeError
may be raised, as it appears that the args
attribute of a sum expression is set to a tuple
rather than a list
.
Steps to reproduce the issue
import pyomo.environ as pyo
from pyomo.core.expr.visitor import replace_expressions
m = pyo.ConcreteModel()
m.p = pyo.Param(range(3), initialize=1, mutable=True)
m.x = pyo.Var()
m.v = pyo.Var(range(3), initialize=1)
# note: the lower bound is a SumExpression here
m.c = pyo.Constraint(expr=2 + 3 * m.p[2] == m.x)
lower_expr = replace_expressions(m.c.lower, {id(m.p[2]): m.v[2]})
body_expr = replace_expressions(m.c.body, {id(m.p[2]): m.v[2]})
# build constraint with v[2] substituted for p[2].
# causes error, as the `args` attribute of a SumExpression
# somewhere is a tuple (not list)
m.c2 = pyo.Constraint(expr=lower_expr == body_expr)
Error Message
$
ERROR: Rule failed when generating expression for Constraint c2 with index
None: AttributeError: 'tuple' object has no attribute 'append'
ERROR: Constructing component 'c2' from data=None failed: AttributeError:
'tuple' object has no attribute 'append'
Traceback (most recent call last):
File "/home/jasherma/Documents/vim_example/pyomo_features_examples/test_err_constraint_add.py", line 34, in <module>
m.c2 = pyo.Constraint(expr=lower_expr == body_expr)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/block.py", line 649, in __setattr__
self.add_component(name, val)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/block.py", line 1219, in add_component
val.construct(data)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/disable_methods.py", line 116, in construct
return base.construct(self, data)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/constraint.py", line 763, in construct
self._setitem_when_not_present(index, rule(block, index))
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/indexed_component.py", line 1005, in _setitem_when_not_present
obj.set_value(value)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/constraint.py", line 922, in set_value
return super(ScalarConstraint, self).set_value(expr)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/base/constraint.py", line 589, in set_value
self._body = args[0] - args[1]
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/expr/numvalue.py", line 673, in __sub__
return _generate_sum_expression(_sub,self,other)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/expr/numeric_expr.py", line 1335, in _generate_sum_expression
return _self.add(-_other)
File "/home/jasherma/Documents/cmu/phd-project/pyomo_repo/pyomo/pyomo/core/expr/numeric_expr.py", line 642, in add
self._args_.append(new_arg)
AttributeError: 'tuple' object has no attribute 'append'
Information on your system
Pyomo version: 6.4.3dev0
Python version: 3.9.13
Operating system: Ubuntu 20.04
How Pyomo was installed (PyPI, conda, source): source
Solver (if applicable): N/A
Additional information
- This exception is also raised in the event the expression is added to a
ConstraintList
(such as throughConstraintList.add
). The PyROS solver (contrib.pyros
) adds constraints to subproblems of two-stage RO models in this way. So PyROS users may be affected.