Pyomo / pyomo

An object-oriented algebraic modeling language in Python for structured optimization problems.
https://www.pyomo.org
Other
1.98k stars 509 forks source link

Python 3.11.8 on Windows: tuple object does not support item assignment #3320

Open transreductionist opened 2 months ago

transreductionist commented 2 months ago

Summary

I ran a very simple Python script (see below) that imports pyomo.environ. When executing the script I received the following error: TypeError: 'tuple' object does not support item assignment

Steps to reproduce the issue

The Python script to reproduce the error:

import pyomo.environ

def do_nothing():
    pass

if __name__ == '__main__':
    do_nothing()

Error Message

Traceback (most recent call last):
  File "C:\devwork\forecasting_fas1\src_py\test\unit\calculator\fas\debt_optimizer\tuple_error.py", line 1, in <module>
    import pyomo.environ
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\environ\__init__.py", line 103, in <module>
    _import_packages()
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\environ\__init__.py", line 74, in _import_packages
    _do_import(pname)
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\environ\__init__.py", line 18, in _do_import
    importlib.import_module(pkg_name)
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\__init__.py", line 36, in <module>
    import pyomo.core.base._pyomo
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\__init__.py", line 20, in <module>
    import pyomo.core.base.boolean_var
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\boolean_var.py", line 15, in <module>
    from pyomo.core.base.set import Set, BooleanSet
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\set.py", line 4055, in <module>
    DeclareGlobalSet(_AnySet(
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\set.py", line 4049, in DeclareGlobalSet
    _set.__class__.__setstate__(_set, obj.__getstate__())
                                      ^^^^^^^^^^^^^^^^^^
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\component.py", line 734, in __getstate__
    state = _base.__getstate__()
            ^^^^^^^^^^^^^^^^^^^^
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\indexed_component.py", line 227, in __getstate__
    state = super(IndexedComponent, self).__getstate__()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\devwork\forecasting_fas1\src_py\cenv\Lib\site-packages\pyomo\core\base\component.py", line 438, in __getstate__
    state[key] = val
    ~~~~~^^^^^
TypeError: 'tuple' object does not support item assignment

Information on your system

Pyomo version: 6.7.3 Python version: 3.11.8 Operating system: Windows 10 Enterprise with OS build=19045.4529 How Pyomo was installed: PyPy Solver (if applicable): N/A

Additional information

An exception occurs in the file core.base.component.py. Here is the function __getstate__ with docstring and comments dropped:

def __getstate__(self):
    _base = super(Component,self)
    if hasattr(_base, '__getstate__'):
        state = _base.__getstate__()
        for key,val in iteritems(self.__dict__):
            if key not in state:
                state[key] = val  # >>>> TypeError occurs here: 'tuple' object does not support item assignment <<<<
    else:
        state = dict(self.__dict__)
    if self._parent is not None:
        state['_parent'] = self._parent()
    return state

Consider the code snippet from __getstate__:

        state = _base.__getstate__()
        for key,val in iteritems(self.__dict__):
            if key not in state:
                state[key] = val

the variable state is a tuple with 2 elements. The variable self.__dict__ is a dictionary with 16 items. When the line:

for key, val in iteritems(self.__dict__):

is executed and the key is 'init_domain' the statement if key not in state is true by construction.

The key 'init_domain' will never be in the tuple state, but will be in state[0], which is a dictionary.

mrmundt commented 2 months ago

Somewhat expectedly, I cannot reproduce this. I will keep trying to do so, but my suspicion is that there may be something in your environment that is to blame. Can you try to create a virtual environment and see what happens?

This is how I do so on a Mac:

python -m venv virtual-python
source virtual-python/bin/activate
pip install pyomo
# Run your script

Here are some instructions that include Windows: https://www.geeksforgeeks.org/creating-python-virtual-environment-windows-linux/

transreductionist commented 2 months ago

I will look at it again.

On Wed, Jul 17, 2024, 11:47 Miranda Mundt @.***> wrote:

Somewhat expectedly, I cannot reproduce this. I will keep trying to do so, but my suspicion is that there may be something in your environment that is to blame. Can you try to create a virtual environment and see what happens?

This is how I do so on a Mac:

python -m venv virtual-python source virtual-python/bin/activate pip install pyomo

Run your script

Here are some instructions that include Windows: https://www.geeksforgeeks.org/creating-python-virtual-environment-windows-linux/

— Reply to this email directly, view it on GitHub https://github.com/Pyomo/pyomo/issues/3320#issuecomment-2233636937, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACBR5L3VMZNV3TPCSGFWBD3ZM2GXTAVCNFSM6AAAAABK43KJV2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMZTGYZTMOJTG4 . You are receiving this because you authored the thread.Message ID: @.***>