From 5dab553c7a72dfbcef4c100fd3f63e94c48a7be7 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 10:57:15 -0700 Subject: [PATCH 1/6] Adding bilevel work --- pyomo/bilevel/plugins/lcp.py | 3 +-- pyomo/bilevel/tests/test_blp.py | 5 ++--- pyomo/bilevel/tests/test_linear_dual.py | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pyomo/bilevel/plugins/lcp.py b/pyomo/bilevel/plugins/lcp.py index 11ab41e9e1c..3c728e30c3b 100644 --- a/pyomo/bilevel/plugins/lcp.py +++ b/pyomo/bilevel/plugins/lcp.py @@ -8,7 +8,6 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -import six import logging from pyomo.core.base import Block, VarList, ConstraintList, Objective, Var, Constraint, maximize, ComponentUID, Set, TransformationFactory @@ -287,7 +286,7 @@ def _add_optimality_conditions(self, instance, submodel): exp -= B2_[uid] * lb_dual if not ub_dual is None: exp += B2_[uid] * ub_dual - if type(exp) in six.integer_types or type(exp) is float: + if type(exp) in [int, float]: # TODO: Annotate the model as unbounded raise IOError("Unbounded variable without side constraints") else: diff --git a/pyomo/bilevel/tests/test_blp.py b/pyomo/bilevel/tests/test_blp.py index f9fe4e63631..e5e4773f4c9 100644 --- a/pyomo/bilevel/tests/test_blp.py +++ b/pyomo/bilevel/tests/test_blp.py @@ -26,10 +26,9 @@ from pyomo.scripting.util import cleanup from pyomo.environ import TransformationFactory -from six import iteritems - solvers = pyomo.opt.check_available_solvers('cplex', 'glpk', 'ipopt') + class CommonTests: solve = True @@ -148,7 +147,7 @@ def check(self, problem, solver): self.assertEqual(len(refObj), len(ansObj)) for i in range(len(refObj)): self.assertEqual(len(refObj[i]), len(ansObj[i])) - for key,val in iteritems(refObj[i]): + for key,val in refObj[i].items(): #self.assertEqual(val['Id'], ansObj[i].get(key,None)['Id']) self.assertAlmostEqual(val['Value'], ansObj[i].get(key,None)['Value'], places=3) diff --git a/pyomo/bilevel/tests/test_linear_dual.py b/pyomo/bilevel/tests/test_linear_dual.py index 05c0dc425a3..96645c45503 100644 --- a/pyomo/bilevel/tests/test_linear_dual.py +++ b/pyomo/bilevel/tests/test_linear_dual.py @@ -25,8 +25,6 @@ from pyomo.scripting.util import cleanup import pyomo.environ -from six import iteritems - solvers = pyomo.opt.check_available_solvers('cplex', 'glpk') @@ -154,7 +152,7 @@ def check(self, problem, solver): self.assertEqual(len(refObj), len(ansObj)) for i in range(len(refObj)): self.assertEqual(len(refObj[i]), len(ansObj[i])) - for key,val in iteritems(refObj[i]): + for key,val in refObj[i].items(): #self.assertEqual(val['Id'], ansObj[i].get(key,None)['Id']) self.assertAlmostEqual(val['Value'], ansObj[i].get(key,None)['Value'], places=3) From 535a3d99605c1f1c0613fd4feaa33dd58838fd0b Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 11:17:40 -0700 Subject: [PATCH 2/6] Move pyutilib Container to pyomo/common/collections and rename Bunch --- pyomo/common/collections/__init__.py | 3 +- pyomo/common/collections/bunch.py | 121 ++++++++++++++++++++++++ pyomo/core/base/PyomoModel.py | 10 +- pyomo/network/decomposition.py | 4 +- pyomo/scripting/commands.py | 4 +- pyomo/scripting/convert.py | 10 +- pyomo/scripting/driver_help.py | 10 +- pyomo/scripting/plugins/convert.py | 4 +- pyomo/scripting/pyomo_command.py | 14 +-- pyomo/scripting/tests/test_pms.py | 4 +- pyomo/scripting/util.py | 26 ++--- pyomo/solvers/plugins/solvers/CONOPT.py | 4 +- pyomo/util/model_size.py | 10 +- 13 files changed, 172 insertions(+), 52 deletions(-) create mode 100644 pyomo/common/collections/bunch.py diff --git a/pyomo/common/collections/__init__.py b/pyomo/common/collections/__init__.py index 1fcfc12c1c4..80e468eb9d3 100644 --- a/pyomo/common/collections/__init__.py +++ b/pyomo/common/collections/__init__.py @@ -23,5 +23,4 @@ from .orderedset import OrderedDict, OrderedSet from .component_map import ComponentMap from .component_set import ComponentSet - -from pyutilib.misc import Bunch, Container, Options +from .bunch import Bunch diff --git a/pyomo/common/collections/bunch.py b/pyomo/common/collections/bunch.py new file mode 100644 index 00000000000..4ddf90c62c9 --- /dev/null +++ b/pyomo/common/collections/bunch.py @@ -0,0 +1,121 @@ +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC +# Under the terms of Contract DE-NA0003525 with National Technology and +# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain +# rights in this software. +# This software is distributed under the 3-clause BSD License. +# ___________________________________________________________________________ +# +# This module was originally developed as part of the PyUtilib project +# Copyright (c) 2008 Sandia Corporation. +# This software is distributed under the BSD License. +# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +# the U.S. Government retains certain rights in this software. +# ___________________________________________________________________________ + +import shlex + + +class Bunch(dict): + """ + A class that can be used to store a bunch of data dynamically. + This class allows all other attributes to have a default value of None. + This borrows the output formatting ideas from the + ActiveState Code Container (recipe 496697). + """ + + def __init__(self, *args, **kw): + for arg in args: + for item in shlex.split(arg): + r = item.find('=') + if r != -1: + try: + val = eval(item[r + 1:]) + except: + val = item[r + 1:] + kw[item[:r]] = val + dict.__init__(self, kw) + self.__dict__.update(kw) + if not '_name_' in kw: + self._name_ = self.__class__.__name__ + + def update(self, d): + """ + The update is specialized for JSON-like data. This + recursively replaces dictionaries with Container objects. + """ + for k in d: + if type(d[k]) is dict: + tmp = Bunch() + tmp.update(d[k]) + self.__setattr__(k, tmp) + elif type(d[k]) is list: + val = [] + for i in d[k]: + if type(i) is dict: + tmp = Bunch() + tmp.update(i) + val.append(tmp) + else: + val.append(i) + self.__setattr__(k, val) + else: + self.__setattr__(k, d[k]) + + def set_name(self, name): + self._name_ = name + + def __setitem__(self, name, val): + self.__setattr__(name, val) + + def __getitem__(self, name): + return self.__getattr__(name) + + def __setattr__(self, name, val): + if name[0] != '_': + dict.__setitem__(self, name, val) + self.__dict__[name] = val + + def __getattr__(self, name): + try: + return dict.__getitem__(self, name) + except: + if name[0] == '_': + raise AttributeError("Unknown attribute %s" % name) + return None + + def __repr__(self): + attrs = sorted("%s = %r" % (k, v) for k, v in self.__dict__.items() + if not k.startswith("_")) + return "%s(%s)" % (self.__class__.__name__, ", ".join(attrs)) + + def __str__(self): + return self.as_string() + + def __str__(self, nesting=0, indent=''): + attrs = [] + indentation = indent + " " * nesting + for k, v in self.__dict__.items(): + if not k.startswith("_"): + text = [indentation, k, ":"] + if isinstance(v, Bunch): + if len(v) > 0: + text.append('\n') + text.append(v.__str__(nesting + 1)) + elif isinstance(v, list): + if len(v) == 0: + text.append(' []') + else: + for v_ in v: + text.append('\n' + indentation + "-") + if isinstance(v_, Bunch): + text.append('\n' + v_.__str__(nesting + 1)) + else: + text.append(" " + repr(v_)) + else: + text.append(' ' + repr(v)) + attrs.append("".join(text)) + attrs.sort() + return "\n".join(attrs) diff --git a/pyomo/core/base/PyomoModel.py b/pyomo/core/base/PyomoModel.py index 045c951e6ff..ccc9622ae7c 100644 --- a/pyomo/core/base/PyomoModel.py +++ b/pyomo/core/base/PyomoModel.py @@ -17,7 +17,7 @@ import math from pyomo.common import timing, PyomoAPIFactory -from pyomo.common.collections import Container +from pyomo.common.collections import Bunch from pyomo.common.dependencies import pympler, pympler_available from pyomo.common.deprecation import deprecated, deprecation_warning from pyomo.common.gc_manager import PauseGC @@ -61,7 +61,7 @@ def wrapper_function(*args, **kwargs): return wrapper_function -class PyomoConfig(Container): +class PyomoConfig(Bunch): """ This is a pyomo-specific configuration object, which is a subclass of Container. """ @@ -69,7 +69,7 @@ class PyomoConfig(Container): _option = {} def __init__(self, *args, **kw): - Container.__init__(self, *args, **kw) + Bunch.__init__(self, *args, **kw) self.set_name('PyomoConfig') # # Create the nested options specified by the the PyomoConfig._option @@ -79,7 +79,7 @@ def __init__(self, *args, **kw): d = self for attr in item[:-1]: if not attr in d: - d[attr] = Container() + d[attr] = Bunch() d = d[attr] d[item[-1]] = PyomoConfig._option[item] @@ -573,7 +573,7 @@ def __init__(self, name='unknown', **kwargs): # SimpleBlock.__init__(self, **kwargs) self._name = name - self.statistics = Container() + self.statistics = Bunch() self.config = PyomoConfig() self.solutions = ModelSolutions(self) self.config.preprocessor = 'pyomo.model.simple_preprocessor' diff --git a/pyomo/network/decomposition.py b/pyomo/network/decomposition.py index d9e0701b163..688d898f7b2 100644 --- a/pyomo/network/decomposition.py +++ b/pyomo/network/decomposition.py @@ -14,7 +14,7 @@ from pyomo.network.foqus_graph import FOQUSGraph from pyomo.core import Constraint, value, Objective, Var, ConcreteModel, \ Binary, minimize, Expression -from pyomo.common.collections import ComponentSet, ComponentMap, Options +from pyomo.common.collections import ComponentSet, ComponentMap, Bunch from pyomo.core.expr.current import identify_variables from pyomo.repn import generate_standard_repn import logging, time @@ -146,7 +146,7 @@ class SequentialDecomposition(FOQUSGraph): def __init__(self, **kwds): """Pass kwds to update the options attribute after setting defaults""" self.cache = {} - options = self.options = Options() + options = self.options = Bunch() # defaults options["graph"] = None options["tear_set"] = None diff --git a/pyomo/scripting/commands.py b/pyomo/scripting/commands.py index 7239f50b50d..96bb92519d4 100644 --- a/pyomo/scripting/commands.py +++ b/pyomo/scripting/commands.py @@ -16,7 +16,7 @@ import subprocess import pyutilib.pyro -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.opt import SolverResults from pyomo.common._command import pyomo_command import pyomo.scripting.pyomo_parser @@ -138,7 +138,7 @@ def pyomo(args=None): def results_schema(): if len(sys.argv) > 1: print("results_schema - Print the predefined schema in a SolverResults object") - options = Options(schema=True) + options = Bunch(schema=True) r=SolverResults() repn = r._repn_(options) r.pprint(sys.stdout, options, repn=repn) diff --git a/pyomo/scripting/convert.py b/pyomo/scripting/convert.py index c064bf6e687..84742a2e8ed 100644 --- a/pyomo/scripting/convert.py +++ b/pyomo/scripting/convert.py @@ -13,7 +13,7 @@ import os import sys -from pyomo.common.collections import Options, Container +from pyomo.common.collections import Bunch from pyomo.opt import ProblemFormat from pyomo.core.base import (Objective, Var, @@ -24,7 +24,7 @@ _format = None -def convert(options=Options(), parser=None, model_format=None): +def convert(options=Bunch(), parser=None, model_format=None): global _format if not model_format is None: _format = model_format @@ -40,7 +40,7 @@ def convert(options=Options(), parser=None, model_format=None): options.model.save_file = 'unknown.'+str(_format) options.model.save_format = _format - data = Options(options=options) + data = Bunch(options=options) model_data = None try: @@ -49,7 +49,7 @@ def convert(options=Options(), parser=None, model_format=None): pyomo.scripting.util.apply_preprocessing(data, parser=parser) if data.error: - return Container() + return Bunch() model_data = pyomo.scripting.util.create_model(data) @@ -73,7 +73,7 @@ def convert(options=Options(), parser=None, model_format=None): return model_data -def convert_dakota(options=Options(), parser=None): +def convert_dakota(options=Bunch(), parser=None): # # Import plugins # diff --git a/pyomo/scripting/driver_help.py b/pyomo/scripting/driver_help.py index 581d45613ca..38a174cb46a 100644 --- a/pyomo/scripting/driver_help.py +++ b/pyomo/scripting/driver_help.py @@ -19,7 +19,7 @@ import subprocess import pyomo.common -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch import pyomo.scripting.pyomo_parser logger = logging.getLogger('pyomo.solvers') @@ -221,9 +221,9 @@ def help_api(options): print(" "+line) def help_environment(): - info = Options() + info = Bunch() # - info.python = Options() + info.python = Bunch() info.python.version = '%d.%d.%d' % sys.version_info[:3] info.python.executable = sys.executable info.python.platform = sys.platform @@ -231,13 +231,13 @@ def help_environment(): packages = [] import pip for package in pip.get_installed_distributions(): - packages.append(Options(name=package.project_name, + packages.append(Bunch(name=package.project_name, version=package.version)) info.python.packages = packages except: pass # - info.environment = Options() + info.environment = Bunch() path = os.environ.get('PATH', None) if not path is None: info.environment['shell path'] = path.split(os.pathsep) diff --git a/pyomo/scripting/plugins/convert.py b/pyomo/scripting/plugins/convert.py index 631f76780d8..f05f119b09d 100644 --- a/pyomo/scripting/plugins/convert.py +++ b/pyomo/scripting/plugins/convert.py @@ -12,7 +12,7 @@ import sys import argparse -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.opt import ProblemConfigFactory, guess_format from pyomo.scripting.pyomo_parser import add_subparser, CustomHelpFormatter @@ -42,7 +42,7 @@ def create_parser(parser=None): return parser -def run_convert(options=Options(), parser=None): +def run_convert(options=Bunch(), parser=None): from pyomo.scripting.convert import convert, convert_dakota if options.model.save_format is None and options.model.save_file: options.model.save_format = options.model.save_file.split('.')[-1] diff --git a/pyomo/scripting/pyomo_command.py b/pyomo/scripting/pyomo_command.py index e3901f2b6b6..f9bed65b152 100644 --- a/pyomo/scripting/pyomo_command.py +++ b/pyomo/scripting/pyomo_command.py @@ -9,7 +9,7 @@ # ___________________________________________________________________________ from pyomo.common.dependencies import pympler_available -from pyomo.common.collections import Options, Container +from pyomo.common.collections import Bunch import pyomo.scripting.util from pyomo.core import ConcreteModel @@ -273,12 +273,12 @@ def add_misc_group(parser): return group -def run_pyomo(options=Options(), parser=None): - data = Options(options=options) +def run_pyomo(options=Bunch(), parser=None): + data = Bunch(options=options) if options.model.filename == '': parser.print_help() - return Container() + return Bunch() try: pyomo.scripting.util.setup_environment(data) @@ -307,7 +307,7 @@ def run_pyomo(options=Options(), parser=None): model=ConcreteModel(), instance=None, results=None) - return Container() #pragma:nocover + return Bunch() #pragma:nocover try: model_data = pyomo.scripting.util.create_model(data) @@ -330,7 +330,7 @@ def run_pyomo(options=Options(), parser=None): model=model_data.model, instance=model_data.instance, results=None) - return Container(instance=model_data.instance) + return Bunch(instance=model_data.instance) try: opt_data = pyomo.scripting.util.apply_optimizer(data, @@ -361,7 +361,7 @@ def run_pyomo(options=Options(), parser=None): instance=model_data.instance, results=opt_data.results) - return Container(options=options, + return Bunch(options=options, instance=model_data.instance, results=opt_data.results, local=opt_data.local) diff --git a/pyomo/scripting/tests/test_pms.py b/pyomo/scripting/tests/test_pms.py index 166e6663156..2cd0c439d24 100644 --- a/pyomo/scripting/tests/test_pms.py +++ b/pyomo/scripting/tests/test_pms.py @@ -19,7 +19,7 @@ from pyutilib.pyro import using_pyro4 import pyutilib.th as unittest -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager import pyomo.opt from pyomo.environ import (ConcreteModel, RangeSet, Var, @@ -63,7 +63,7 @@ def c_rule(model): model.c = Constraint(rule=c_rule) # - data = Options() + data = Bunch() data.suffixes = {} data.solver_options = {} data.warmstart_filename = None diff --git a/pyomo/scripting/util.py b/pyomo/scripting/util.py index e582fd8330b..1dd9c1d4a6c 100644 --- a/pyomo/scripting/util.py +++ b/pyomo/scripting/util.py @@ -30,7 +30,7 @@ pympler, pympler_available, ) from pyomo.common.plugin import ExtensionPoint, Plugin, implements -from pyomo.common.collections import Container, Options +from pyomo.common.collections import Bunch from pyomo.opt import ProblemFormat from pyomo.opt.base import SolverFactory from pyomo.opt.parallel import SolverManagerFactory @@ -38,7 +38,7 @@ from pyomo.core import IPyomoScriptCreateModel, IPyomoScriptCreateDataPortal, IPyomoScriptPrintModel, IPyomoScriptModifyInstance, IPyomoScriptPrintInstance, IPyomoScriptSaveInstance, IPyomoScriptPrintResults, IPyomoScriptSaveResults, IPyomoScriptPostprocess, IPyomoScriptPreprocess, Model, TransformationFactory, Suffix, display -memory_data = Options() +memory_data = Bunch() # Importing IPython is slow; defer the import to the point that it is # actually needed. IPython_available = None @@ -156,7 +156,7 @@ def apply_preprocessing(data, parser=None): Returned: error: This is true if an error has occurred. """ - data.local = Options() + data.local = Bunch() # if not data.options.runtime.logging == 'quiet': sys.stdout.write('[%8.2f] Applying Pyomo preprocessing actions\n' % (time.time()-start_time)) @@ -274,8 +274,8 @@ def create_model(data): else: model_options = data.options.model.options.value() tick = time.time() - model = ep.service().apply( options = Container(*data.options), - model_options=Container(*model_options) ) + model = ep.service().apply( options = Bunch(*data.options), + model_options=Bunch(*model_options) ) if data.options.runtime.report_timing is True: print(" %6.2f seconds required to construct instance" % (time.time() - tick)) data.local.time_initial_import = None @@ -474,8 +474,8 @@ def create_model(data): data.local.max_memory = mem_used print(" Total memory = %d bytes following Pyomo instance creation" % mem_used) - return Options(model=model, instance=instance, - smap_id=smap_id, filename=fname, local=data.local ) + return Bunch(model=model, instance=instance, + smap_id=smap_id, filename=fname, local=data.local ) @pyomo_api(namespace='pyomo.script') def apply_optimizer(data, instance=None): @@ -620,7 +620,7 @@ def apply_optimizer(data, instance=None): data.local.max_memory = mem_used print(" Total memory = %d bytes following optimization" % mem_used) - return Options(results=results, opt=solver, local=data.local) + return Bunch(results=results, opt=solver, local=data.local) @pyomo_api(namespace='pyomo.script') @@ -826,9 +826,9 @@ class PyomoCommandLogContext(object): def __init__(self, options): if options is None: - options = Options() + options = Bunch() if options.runtime is None: - options.runtime = Options() + options.runtime = Bunch() self.options = options self.fileLogger = None self.original = None @@ -927,7 +927,7 @@ def run_command(command=None, parser=None, args=None, name='unknown', data=None, _options = parser.parse_args(args=args) # Replace the parser options object with a # pyomo.common.collections.Options object - options = Options() + options = Bunch() for key in dir(_options): if key[0] != '_': val = getattr(_options, key) @@ -936,7 +936,7 @@ def run_command(command=None, parser=None, args=None, name='unknown', data=None, except SystemExit: # the parser throws a system exit if "-h" is specified - catch # it to exit gracefully. - return Container(retval=None, errorcode=0) + return Bunch(retval=None, errorcode=0) # # Configure loggers # @@ -950,7 +950,7 @@ def run_command(command=None, parser=None, args=None, name='unknown', data=None, gc.enable() TempfileManager.pop(remove=not options.runtime.keep_files) - return Container(retval=retval, errorcode=errorcode) + return Bunch(retval=retval, errorcode=errorcode) def _run_command_impl(command, parser, args, name, data, options): diff --git a/pyomo/solvers/plugins/solvers/CONOPT.py b/pyomo/solvers/plugins/solvers/CONOPT.py index 899cab1930a..7faef069c5e 100644 --- a/pyomo/solvers/plugins/solvers/CONOPT.py +++ b/pyomo/solvers/plugins/solvers/CONOPT.py @@ -12,7 +12,7 @@ import subprocess from pyomo.common import Executable -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat @@ -47,7 +47,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.nl) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True self._capabilities.quadratic_objective = True diff --git a/pyomo/util/model_size.py b/pyomo/util/model_size.py index e8fd02ae3f4..3bbf91435c0 100644 --- a/pyomo/util/model_size.py +++ b/pyomo/util/model_size.py @@ -11,7 +11,7 @@ """This module contains functions to interrogate the size of a Pyomo model.""" import logging -from pyomo.common.collections import ComponentSet, Container +from pyomo.common.collections import ComponentSet, Bunch from pyomo.core import Block, Constraint, Var from pyomo.core.expr import current as EXPR from pyomo.gdp import Disjunct, Disjunction @@ -21,7 +21,7 @@ default_logger.setLevel(logging.INFO) -class ModelSizeReport(Container): +class ModelSizeReport(Bunch): """Stores model size information. Activated blocks are those who have an active flag of True and whose @@ -86,7 +86,7 @@ def build_model_size_report(model): activated_vars.update( disj.indicator_var for disj in activated_disjuncts) - report.activated = Container() + report.activated = Bunch() report.activated.variables = len(activated_vars) report.activated.binary_variables = sum( 1 for v in activated_vars if v.is_binary()) @@ -101,7 +101,7 @@ def build_model_size_report(model): 1 for c in activated_constraints if c.body.polynomial_degree() not in (1, 0)) - report.overall = Container() + report.overall = Bunch() block_like = (Block, Disjunct) all_vars = ComponentSet( model.component_data_objects(Var, descend_into=block_like)) @@ -125,7 +125,7 @@ def build_model_size_report(model): Constraint, descend_into=block_like) if c.body.polynomial_degree() not in (1, 0)) - report.warning = Container() + report.warning = Bunch() report.warning.unassociated_disjuncts = sum( 1 for d in model.component_data_objects( Disjunct, descend_into=block_like) From 77f97a5ee40df754a03a14412a376606d2bedfe6 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 11:20:49 -0700 Subject: [PATCH 3/6] Adding back in Options/Container import in init --- pyomo/common/collections/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyomo/common/collections/__init__.py b/pyomo/common/collections/__init__.py index 80e468eb9d3..b4423709a45 100644 --- a/pyomo/common/collections/__init__.py +++ b/pyomo/common/collections/__init__.py @@ -24,3 +24,5 @@ from .component_map import ComponentMap from .component_set import ComponentSet from .bunch import Bunch + +from pyutilib.misc import Options, Container From 1bbf54b554ebadb927d2ae86918582905ca4205c Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 12:24:56 -0700 Subject: [PATCH 4/6] Next round of Bunch conversion --- pyomo/contrib/mindtpy/MindtPy.py | 4 ++-- pyomo/solvers/plugins/solvers/ASL.py | 4 ++-- pyomo/solvers/plugins/solvers/BARON.py | 4 ++-- pyomo/solvers/plugins/solvers/CBCplugin.py | 4 ++-- pyomo/solvers/plugins/solvers/CPLEX.py | 6 +++--- pyomo/solvers/plugins/solvers/GAMS.py | 6 +++--- pyomo/solvers/plugins/solvers/GLPK.py | 4 ++-- pyomo/solvers/plugins/solvers/GLPK_old.py | 6 +++--- pyomo/solvers/plugins/solvers/GUROBI.py | 4 ++-- pyomo/solvers/plugins/solvers/IPOPT.py | 4 ++-- pyomo/solvers/plugins/solvers/PICO.py | 4 ++-- pyomo/solvers/plugins/solvers/SCIPAMPL.py | 4 ++-- pyomo/solvers/plugins/solvers/XPRESS.py | 4 ++-- .../plugins/solvers/direct_or_persistent_solver.py | 4 ++-- pyomo/solvers/plugins/solvers/direct_solver.py | 4 ++-- pyomo/solvers/plugins/solvers/glpk_direct.py | 4 ++-- pyomo/solvers/plugins/solvers/persistent_solver.py | 4 ++-- pyomo/solvers/tests/core/solvers.py | 4 ++-- pyomo/solvers/tests/solvers.py | 4 ++-- pyomo/solvers/tests/testcases.py | 9 +++++---- 20 files changed, 46 insertions(+), 45 deletions(-) diff --git a/pyomo/contrib/mindtpy/MindtPy.py b/pyomo/contrib/mindtpy/MindtPy.py index 0fbe38109b6..aa029fee19f 100644 --- a/pyomo/contrib/mindtpy/MindtPy.py +++ b/pyomo/contrib/mindtpy/MindtPy.py @@ -47,7 +47,7 @@ Block, ConstraintList, NonNegativeReals, Set, Suffix, Var, VarList, TransformationFactory, Objective) from pyomo.opt import SolverFactory, SolverResults -from pyomo.common.collections import Container +from pyomo.common.collections import Bunch from pyomo.contrib.fbbt.fbbt import fbbt from pyomo.contrib.mindtpy.config_options import _get_GDPopt_config @@ -126,7 +126,7 @@ def solve(self, model, **kwds): solve_data = MindtPySolveData() solve_data.results = SolverResults() - solve_data.timing = Container() + solve_data.timing = Bunch() solve_data.curr_int_sol = [] solve_data.prev_int_sol = [] diff --git a/pyomo/solvers/plugins/solvers/ASL.py b/pyomo/solvers/plugins/solvers/ASL.py index ec2fbaf2b12..288a51e64c3 100644 --- a/pyomo/solvers/plugins/solvers/ASL.py +++ b/pyomo/solvers/plugins/solvers/ASL.py @@ -14,7 +14,7 @@ from pyomo.common import Executable from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat @@ -53,7 +53,7 @@ def __init__(self, **kwds): # # Note: Undefined capabilities default to 'None' # - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True self._capabilities.quadratic_objective = True diff --git a/pyomo/solvers/plugins/solvers/BARON.py b/pyomo/solvers/plugins/solvers/BARON.py index de3d3e73e19..ef12b97ad07 100644 --- a/pyomo/solvers/plugins/solvers/BARON.py +++ b/pyomo/solvers/plugins/solvers/BARON.py @@ -15,7 +15,7 @@ import tempfile from pyomo.common import Executable -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat, OptSolver @@ -50,7 +50,7 @@ def __init__(self, **kwds): self._valid_result_formats[ProblemFormat.bar] = [ResultsFormat.soln] self.set_problem_format(ProblemFormat.bar) - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.quadratic_objective = True self._capabilities.quadratic_constraint = True diff --git a/pyomo/solvers/plugins/solvers/CBCplugin.py b/pyomo/solvers/plugins/solvers/CBCplugin.py index 9fd16a40b5a..adec7fe916a 100644 --- a/pyomo/solvers/plugins/solvers/CBCplugin.py +++ b/pyomo/solvers/plugins/solvers/CBCplugin.py @@ -19,7 +19,7 @@ from pyomo.common import Executable from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.core.kernel.block import IBlock @@ -161,7 +161,7 @@ def __init__(self, **kwds): self._valid_result_formats[ProblemFormat.mps] = [ResultsFormat.soln] # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True # The quadratic capabilities may be true but there is diff --git a/pyomo/solvers/plugins/solvers/CPLEX.py b/pyomo/solvers/plugins/solvers/CPLEX.py index f61a2b10db1..a03a0fc41d4 100644 --- a/pyomo/solvers/plugins/solvers/CPLEX.py +++ b/pyomo/solvers/plugins/solvers/CPLEX.py @@ -19,7 +19,7 @@ from pyomo.common.errors import ApplicationError from pyomo.common.tempfiles import TempfileManager -from pyomo.common.collections import ComponentMap, Options, Bunch +from pyomo.common.collections import ComponentMap, Bunch from pyomo.opt.base import ( ProblemFormat, ResultsFormat, OptSolver, BranchDirection, ) @@ -169,7 +169,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.quadratic_objective = True self._capabilities.quadratic_constraint = True @@ -619,7 +619,7 @@ def process_logfile(self): results.solver.termination_message = ' '.join(tokens) try: - if isinstance(results.solver.termination_message, basestring): + if isinstance(results.solver.termination_message, str): results.solver.termination_message = results.solver.termination_message.replace(':', '\\x3a') except: pass diff --git a/pyomo/solvers/plugins/solvers/GAMS.py b/pyomo/solvers/plugins/solvers/GAMS.py index 42a087ffc85..1c6cbbbe182 100644 --- a/pyomo/solvers/plugins/solvers/GAMS.py +++ b/pyomo/solvers/plugins/solvers/GAMS.py @@ -17,7 +17,7 @@ from pyomo.opt import ProblemFormat, SolverFactory import pyomo.common -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.common.tee import TeeStream from pyomo.opt.base.solvers import _extract_version @@ -45,7 +45,7 @@ def __init__(self, **kwds): self._default_variable_value = None self._metasolver = False - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.quadratic_objective = True self._capabilities.quadratic_constraint = True @@ -53,7 +53,7 @@ def __init__(self, **kwds): self._capabilities.sos1 = False self._capabilities.sos2 = False - self.options = Options() + self.options = Bunch() def version(self): """Returns a 4-tuple describing the solver executable version.""" diff --git a/pyomo/solvers/plugins/solvers/GLPK.py b/pyomo/solvers/plugins/solvers/GLPK.py index 5bdf4c7df6e..c12301e89e4 100644 --- a/pyomo/solvers/plugins/solvers/GLPK.py +++ b/pyomo/solvers/plugins/solvers/GLPK.py @@ -17,7 +17,7 @@ from pyomo.common.tempfiles import TempfileManager from pyomo.common import Executable -from pyomo.common.collections import Bunch, Options +from pyomo.common.collections import Bunch from pyomo.opt import SolverFactory, OptSolver, ProblemFormat, ResultsFormat, SolverResults, TerminationCondition, SolutionStatus, ProblemSense from pyomo.opt.base.solvers import _extract_version from pyomo.opt.solver import SystemCallSolver @@ -136,7 +136,7 @@ def __init__ (self, **kwargs): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True diff --git a/pyomo/solvers/plugins/solvers/GLPK_old.py b/pyomo/solvers/plugins/solvers/GLPK_old.py index 50bda10e64c..03fe0a388c5 100644 --- a/pyomo/solvers/plugins/solvers/GLPK_old.py +++ b/pyomo/solvers/plugins/solvers/GLPK_old.py @@ -15,7 +15,7 @@ import subprocess from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Bunch, Options +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.common import Executable @@ -77,7 +77,7 @@ def __init__ (self, **kwargs): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True @@ -427,7 +427,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True diff --git a/pyomo/solvers/plugins/solvers/GUROBI.py b/pyomo/solvers/plugins/solvers/GUROBI.py index 35010859337..8860f4da732 100644 --- a/pyomo/solvers/plugins/solvers/GUROBI.py +++ b/pyomo/solvers/plugins/solvers/GUROBI.py @@ -16,7 +16,7 @@ import subprocess from pyomo.common import Executable -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat, OptSolver @@ -104,7 +104,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.quadratic_objective = True self._capabilities.quadratic_constraint = True diff --git a/pyomo/solvers/plugins/solvers/IPOPT.py b/pyomo/solvers/plugins/solvers/IPOPT.py index 7a31639404d..1b290f29ff4 100644 --- a/pyomo/solvers/plugins/solvers/IPOPT.py +++ b/pyomo/solvers/plugins/solvers/IPOPT.py @@ -12,7 +12,7 @@ import subprocess from pyomo.common import Executable -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat @@ -46,7 +46,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.nl) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = False self._capabilities.quadratic_objective = True diff --git a/pyomo/solvers/plugins/solvers/PICO.py b/pyomo/solvers/plugins/solvers/PICO.py index ce36f426a35..0089a32e915 100644 --- a/pyomo/solvers/plugins/solvers/PICO.py +++ b/pyomo/solvers/plugins/solvers/PICO.py @@ -15,7 +15,7 @@ from pyomo.common import Executable from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat, OptSolver @@ -91,7 +91,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.cpxlp) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True #self._capabilities.sos1 = True diff --git a/pyomo/solvers/plugins/solvers/SCIPAMPL.py b/pyomo/solvers/plugins/solvers/SCIPAMPL.py index 62eb136a30e..8d35aeb91b1 100644 --- a/pyomo/solvers/plugins/solvers/SCIPAMPL.py +++ b/pyomo/solvers/plugins/solvers/SCIPAMPL.py @@ -12,7 +12,7 @@ import subprocess from pyomo.common import Executable -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat @@ -45,7 +45,7 @@ def __init__(self, **kwds): self.set_problem_format(ProblemFormat.nl) # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True self._capabilities.quadratic_objective = True diff --git a/pyomo/solvers/plugins/solvers/XPRESS.py b/pyomo/solvers/plugins/solvers/XPRESS.py index 109dcf0036c..9a3e1027131 100644 --- a/pyomo/solvers/plugins/solvers/XPRESS.py +++ b/pyomo/solvers/plugins/solvers/XPRESS.py @@ -16,7 +16,7 @@ from pyomo.common import Executable from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options, Bunch +from pyomo.common.collections import Bunch from pyomo.common.tempfiles import TempfileManager from pyomo.opt.base import ProblemFormat, ResultsFormat, OptSolver @@ -99,7 +99,7 @@ def __init__(self, **kwds): # # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.quadratic_objective = True self._capabilities.quadratic_constraint = True diff --git a/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py b/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py index 159473c958b..158c65c5e4f 100644 --- a/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py +++ b/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py @@ -15,7 +15,7 @@ from pyomo.core.base import SymbolMap, NumericLabeler, TextLabeler import pyomo.common from pyomo.common.errors import ApplicationError -from pyomo.common.collections import ComponentMap, ComponentSet, Options +from pyomo.common.collections import ComponentMap, ComponentSet, Bunch from pyomo.common.tempfiles import TempfileManager import pyomo.opt.base.solvers from pyomo.opt.base.formats import ResultsFormat @@ -101,7 +101,7 @@ def __init__(self, **kwds): self._symbolic_solver_labels = False """A bool. If true then the solver components will be given names corresponding to the pyomo component names.""" - self._capabilites = Options() + self._capabilites = Bunch() self._referenced_variables = ComponentMap() """dict: {var: count} where count is the number of constraints/objective referencing the var""" diff --git a/pyomo/solvers/plugins/solvers/direct_solver.py b/pyomo/solvers/plugins/solvers/direct_solver.py index 3faa4b17a0d..c0fcd4113f9 100644 --- a/pyomo/solvers/plugins/solvers/direct_solver.py +++ b/pyomo/solvers/plugins/solvers/direct_solver.py @@ -17,7 +17,7 @@ from pyomo.core.base.suffix import active_import_suffix_generator from pyomo.core.kernel.suffix import import_suffix_generator from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch logger = logging.getLogger('pyomo.solvers') @@ -106,7 +106,7 @@ def solve(self, *args, **kwds): orig_options = self.options - self.options = Options() + self.options = Bunch() self.options.update(orig_options) self.options.update(kwds.pop('options', {})) self.options.update( diff --git a/pyomo/solvers/plugins/solvers/glpk_direct.py b/pyomo/solvers/plugins/solvers/glpk_direct.py index 1e81a69c14b..cd7ebffdb7e 100644 --- a/pyomo/solvers/plugins/solvers/glpk_direct.py +++ b/pyomo/solvers/plugins/solvers/glpk_direct.py @@ -38,7 +38,7 @@ def configure_glpk_direct(): print("Import of glpk failed - glpk message="+str(e)+"\n") glpk_python_api_exists = False -from pyomo.common.collections import Bunch, Options +from pyomo.common.collections import Bunch from pyomo.opt.base import OptSolver from pyomo.opt.base.solvers import _extract_version, SolverFactory @@ -104,7 +104,7 @@ def __init__(self, **kwds): self._timelimit = None # Note: Undefined capabilities default to 'None' - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True self._capabilities.integer = True diff --git a/pyomo/solvers/plugins/solvers/persistent_solver.py b/pyomo/solvers/plugins/solvers/persistent_solver.py index 0d4962ed75b..9a42f4e8974 100644 --- a/pyomo/solvers/plugins/solvers/persistent_solver.py +++ b/pyomo/solvers/plugins/solvers/persistent_solver.py @@ -20,7 +20,7 @@ from pyomo.core.base.sos import SOSConstraint from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch import time import logging @@ -449,7 +449,7 @@ def solve(self, *args, **kwds): orig_options = self.options - self.options = Options() + self.options = Bunch() self.options.update(orig_options) self.options.update(kwds.pop('options', {})) self.options.update(self._options_string_to_dict(kwds.pop('options_string', ''))) diff --git a/pyomo/solvers/tests/core/solvers.py b/pyomo/solvers/tests/core/solvers.py index 73390759769..5ace70a9d4d 100644 --- a/pyomo/solvers/tests/core/solvers.py +++ b/pyomo/solvers/tests/core/solvers.py @@ -18,7 +18,7 @@ import logging from functools import reduce -from pyomo.common.collections import Bunch, Options +from pyomo.common.collections import Bunch import pyutilib.th as unittest import pyutilib.autotest import pyomo.misc.plugin @@ -268,7 +268,7 @@ def test_solvers(options=None, argv=None): else: sys.argv=argv # Create the tests defined in the YAML configuration file - autotest_options = Options() + autotest_options = Bunch() autotest_options.testname_format = "%s_TEST_%s" pyutilib.autotest.create_test_suites(filename=currdir+'test_solvers.yml', _globals=globals(), options=autotest_options) # Execute the tests, using a custom test runner diff --git a/pyomo/solvers/tests/solvers.py b/pyomo/solvers/tests/solvers.py index e1a1090df6d..95090770905 100644 --- a/pyomo/solvers/tests/solvers.py +++ b/pyomo/solvers/tests/solvers.py @@ -13,7 +13,7 @@ import six import logging -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.opt import SolverFactory from pyomo.opt.base.solvers import UnknownSolver @@ -36,7 +36,7 @@ # interfaces may be used for the same "solver" # def initialize(**kwds): - obj = Options(**kwds) + obj = Bunch(**kwds) # # Set obj.available # diff --git a/pyomo/solvers/tests/testcases.py b/pyomo/solvers/tests/testcases.py index 70ae91bded0..98206772d14 100644 --- a/pyomo/solvers/tests/testcases.py +++ b/pyomo/solvers/tests/testcases.py @@ -13,7 +13,7 @@ import pyutilib.th as unittest -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.opt import TerminationCondition from pyomo.solvers.tests.models.base import test_models from pyomo.solvers.tests.solvers import test_solver_cases @@ -397,7 +397,7 @@ def test_scenarios(arg=None): msg=case[2] # Return scenario dimensions and scenario information - yield (model, solver, io), Options( + yield (model, solver, io), Bunch( status=status, msg=msg, model=_model, solver=None, testcase=_solver_case, demo_limits=_solver_case.demo_limits, exclude_suffixes=exclude_suffixes) @@ -477,11 +477,12 @@ def run_test_scenarios(options): # Summarize the runtime statistics, by solver # summary = {} - total = Options(NumEPass=0, NumEFail=0, NumUPass=0, NumUFail=0) + total = Bunch(NumEPass=0, NumEFail=0, NumUPass=0, NumUFail=0) for key in stat: model, solver, io = key if not solver in summary: - summary[solver] = Options(NumEPass=0, NumEFail=0, NumUPass=0, NumUFail=0) + summary[solver] = Bunch(NumEPass=0, NumEFail=0, + NumUPass=0, NumUFail=0) _pass, _str = stat[key] if _pass: if _str == "Expected failure": From 3a3ab8c663124e18670011018e8ca74cc0057714 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 12:39:16 -0700 Subject: [PATCH 5/6] Last round of Bunch conversion --- examples/doc/pyomobook/attic/scripts/alltogether.py | 4 ++-- .../doc/pyomobook/attic/scripts/indexnonlinscript.py | 4 ++-- .../attic/scripts/mimic_pyomo/mimic_pyomo.py | 4 ++-- examples/doc/pyomobook/attic/scripts/nonlinscript.py | 4 ++-- .../pyomo_book/nonlinear_ReactorDesignTable.py | 4 ++-- .../doc/samples/pyomo_book/scripts_mimicPyomo.py | 4 ++-- examples/pyomo/callbacks/sc.py | 12 ++++++------ pyomo/common/collections/__init__.py | 2 -- pyomo/contrib/gdpbb/GDPbb.py | 4 ++-- pyomo/contrib/gdpopt/tests/test_gdpopt.py | 4 ++-- pyomo/contrib/gdpopt/util.py | 4 ++-- pyomo/dataportal/TableData.py | 4 ++-- pyomo/dataportal/plugins/datacommands.py | 4 ++-- pyomo/dataportal/plugins/json_dict.py | 6 +++--- pyomo/dataportal/process_data.py | 6 +++--- pyomo/mpec/plugins/pathampl.py | 4 ++-- pyomo/opt/base/solvers.py | 8 ++++---- 17 files changed, 40 insertions(+), 42 deletions(-) diff --git a/examples/doc/pyomobook/attic/scripts/alltogether.py b/examples/doc/pyomobook/attic/scripts/alltogether.py index 1e4d0d6547f..f097575d669 100644 --- a/examples/doc/pyomobook/attic/scripts/alltogether.py +++ b/examples/doc/pyomobook/attic/scripts/alltogether.py @@ -1,6 +1,6 @@ import pyomo.environ from pyomo.opt import SolverFactory -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch import sys import math @@ -39,7 +39,7 @@ instance=model.create() SolverName = "asl" -so = Options() +so = Bunch() so.solver = "ipopt" opt=SolverFactory(SolverName, options=so) diff --git a/examples/doc/pyomobook/attic/scripts/indexnonlinscript.py b/examples/doc/pyomobook/attic/scripts/indexnonlinscript.py index 961b7382866..5be62ba547d 100644 --- a/examples/doc/pyomobook/attic/scripts/indexnonlinscript.py +++ b/examples/doc/pyomobook/attic/scripts/indexnonlinscript.py @@ -1,7 +1,7 @@ import sys import pyomo.environ from pyomo.opt import SolverFactory -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from indexnonlin import model @@ -12,7 +12,7 @@ instance=model.create() SolverName = "asl" -so = Options() +so = Bunch() so.solver = "ipopt" opt=SolverFactory(SolverName, options=so) diff --git a/examples/doc/pyomobook/attic/scripts/mimic_pyomo/mimic_pyomo.py b/examples/doc/pyomobook/attic/scripts/mimic_pyomo/mimic_pyomo.py index 736b31a36ad..cac032cd99c 100644 --- a/examples/doc/pyomobook/attic/scripts/mimic_pyomo/mimic_pyomo.py +++ b/examples/doc/pyomobook/attic/scripts/mimic_pyomo/mimic_pyomo.py @@ -1,9 +1,9 @@ # Mimic the pyomo script from pyomo.core import * -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch # set high level options that mimic pyomo comand line -options = Options() +options = Bunch() options.model_file = 'DiseaseEstimation.py' options.data_files = ['DiseaseEstimation.dat'] options.solver = 'ipopt' diff --git a/examples/doc/pyomobook/attic/scripts/nonlinscript.py b/examples/doc/pyomobook/attic/scripts/nonlinscript.py index b231c61b3ba..f08b6357e18 100644 --- a/examples/doc/pyomobook/attic/scripts/nonlinscript.py +++ b/examples/doc/pyomobook/attic/scripts/nonlinscript.py @@ -1,7 +1,7 @@ import sys import pyomo.environ from pyomo.opt import SolverFactory -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from nonlin import model @@ -12,7 +12,7 @@ instance=model.create() SolverName = "asl" -so = Options() +so = Bunch() so.solver = "ipopt" opt=SolverFactory(SolverName, options=so) diff --git a/examples/doc/samples/pyomo_book/nonlinear_ReactorDesignTable.py b/examples/doc/samples/pyomo_book/nonlinear_ReactorDesignTable.py index a0c1b61391b..8346cd0ebfa 100644 --- a/examples/doc/samples/pyomo_book/nonlinear_ReactorDesignTable.py +++ b/examples/doc/samples/pyomo_book/nonlinear_ReactorDesignTable.py @@ -1,6 +1,6 @@ # nonlinear_ReactorDesignTable.py from pyomo.environ import * -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch # create the concrete model model = ConcreteModel() @@ -36,7 +36,7 @@ + k3 * model.ca ** 2.0)) # setup the solver options -options = Options() +options = Bunch() options.solver = 'ipopt' options.quiet = True diff --git a/examples/doc/samples/pyomo_book/scripts_mimicPyomo.py b/examples/doc/samples/pyomo_book/scripts_mimicPyomo.py index 870a9f4decd..46723752fcd 100644 --- a/examples/doc/samples/pyomo_book/scripts_mimicPyomo.py +++ b/examples/doc/samples/pyomo_book/scripts_mimicPyomo.py @@ -1,9 +1,9 @@ # Mimic the pyomo script from pyomo.environ import * -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch # set high level options that mimic pyomo comand line -options = Options() +options = Bunch() options.model_file = 'DiseaseEstimation.py' options.data_files = ['DiseaseEstimation.dat'] options.solver = 'ipopt' diff --git a/examples/pyomo/callbacks/sc.py b/examples/pyomo/callbacks/sc.py index 9faa62dd6a1..10781ec8f5a 100644 --- a/examples/pyomo/callbacks/sc.py +++ b/examples/pyomo/callbacks/sc.py @@ -8,7 +8,7 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.core import * import math import random @@ -45,7 +45,7 @@ def print_model_stats(options,model): def pyomo_create_model(options=None, model_options=None): if model_options is None: - model_options = Options() + model_options = Bunch() if model_options.type is None: model_options.type = 'fixed_set_size' # @@ -185,24 +185,24 @@ def test_model(options=None): if __name__ == '__main__': test_model() # - options = Options() + options = Bunch() options.type = 'fixed_set_size' options.m = 11 options.n = 21 options.rho = 0.3 test_model(options) # - options = Options() + options = Bunch() options.type = 'fixed_element_coverage' test_model(options) # - options = Options() + options = Bunch() options.m = 100 options.n = 200 options.type = 'fixed_probability' test_model(options) # - options = Options() + options = Bunch() options.type = 'fixed_element_coverage' options.m = 10 options.n = 100 diff --git a/pyomo/common/collections/__init__.py b/pyomo/common/collections/__init__.py index b4423709a45..80e468eb9d3 100644 --- a/pyomo/common/collections/__init__.py +++ b/pyomo/common/collections/__init__.py @@ -24,5 +24,3 @@ from .component_map import ComponentMap from .component_set import ComponentSet from .bunch import Bunch - -from pyutilib.misc import Options, Container diff --git a/pyomo/contrib/gdpbb/GDPbb.py b/pyomo/contrib/gdpbb/GDPbb.py index 0dd8fac2905..c530375ad47 100644 --- a/pyomo/contrib/gdpbb/GDPbb.py +++ b/pyomo/contrib/gdpbb/GDPbb.py @@ -11,7 +11,7 @@ import traceback from pyomo.common import deprecated -from pyomo.common.collections import ComponentSet, Container +from pyomo.common.collections import ComponentSet, Bunch from pyomo.common.config import (ConfigBlock, ConfigValue, PositiveInt) from pyomo.contrib.gdpopt.util import create_utility_block, time_code, a_logger, restore_logger_level, \ setup_results_object, get_main_elapsed_time, process_objective @@ -112,7 +112,7 @@ def solve(self, model, **kwds): self.validate_model(model) # Set solver as an MINLP solve_data = GDPbbSolveData() - solve_data.timing = Container() + solve_data.timing = Bunch() solve_data.original_model = model solve_data.results = SolverResults() diff --git a/pyomo/contrib/gdpopt/tests/test_gdpopt.py b/pyomo/contrib/gdpopt/tests/test_gdpopt.py index e392142d769..9a03cdf0e36 100644 --- a/pyomo/contrib/gdpopt/tests/test_gdpopt.py +++ b/pyomo/contrib/gdpopt/tests/test_gdpopt.py @@ -17,7 +17,7 @@ import pyutilib.th as unittest from pyomo.common.log import LoggingIntercept -from pyomo.common.collections import Container +from pyomo.common.collections import Bunch from pyomo.common.fileutils import import_file from pyomo.contrib.gdpopt.GDPopt import GDPoptSolver from pyomo.contrib.gdpopt.data_class import GDPoptSolveData @@ -62,7 +62,7 @@ def test_solve_linear_GDP_unbounded(self): output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): solver_data = GDPoptSolveData() - solver_data.timing = Container() + solver_data.timing = Bunch() with time_code(solver_data.timing, 'main', is_main_timer=True): solve_linear_GDP(m, solver_data, GDPoptSolver.CONFIG(dict(mip_solver=mip_solver))) self.assertIn("Linear GDP was unbounded. Resolving with arbitrary bound values", diff --git a/pyomo/contrib/gdpopt/util.py b/pyomo/contrib/gdpopt/util.py index 29d4cf75e8d..4bce9f9a540 100644 --- a/pyomo/contrib/gdpopt/util.py +++ b/pyomo/contrib/gdpopt/util.py @@ -18,7 +18,7 @@ import six from pyomo.common import deprecated, timing -from pyomo.common.collections import ComponentSet, Container +from pyomo.common.collections import ComponentSet, Bunch from pyomo.contrib.fbbt.fbbt import compute_bounds_on_expr from pyomo.contrib.gdpopt.data_class import GDPoptSolveData from pyomo.contrib.mcpp.pyomo_mcpp import mcpp_available, McCormick @@ -484,7 +484,7 @@ def setup_solver_environment(model, config): solve_data = GDPoptSolveData() # data object for storing solver state solve_data.config = config solve_data.results = SolverResults() - solve_data.timing = Container() + solve_data.timing = Bunch() min_logging_level = logging.INFO if config.tee else None with time_code(solve_data.timing, 'total', is_main_timer=True), \ lower_logger_level_to(config.logger, min_logging_level), \ diff --git a/pyomo/dataportal/TableData.py b/pyomo/dataportal/TableData.py index 9d4fd95b6fc..9109b333ebb 100644 --- a/pyomo/dataportal/TableData.py +++ b/pyomo/dataportal/TableData.py @@ -12,7 +12,7 @@ from six.moves import xrange -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.dataportal.process_data import _process_data @@ -28,7 +28,7 @@ def __init__(self): """ self._info=None self._data=None - self.options = Options() + self.options = Bunch() self.options.ncolumns = 1 def available(self): diff --git a/pyomo/dataportal/plugins/datacommands.py b/pyomo/dataportal/plugins/datacommands.py index e5571bccc1d..0bb42c11659 100644 --- a/pyomo/dataportal/plugins/datacommands.py +++ b/pyomo/dataportal/plugins/datacommands.py @@ -10,7 +10,7 @@ import os.path -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.dataportal.factory import DataManagerFactory from pyomo.dataportal.process_data import _process_include @@ -20,7 +20,7 @@ class PyomoDataCommands(object): def __init__(self): self._info = [] - self.options = Options() + self.options = Bunch() def available(self): return True diff --git a/pyomo/dataportal/plugins/json_dict.py b/pyomo/dataportal/plugins/json_dict.py index 7c7234e6a3d..d2af934d13f 100644 --- a/pyomo/dataportal/plugins/json_dict.py +++ b/pyomo/dataportal/plugins/json_dict.py @@ -12,7 +12,7 @@ import json import six -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.common.dependencies import yaml, yaml_available, yaml_load_args from pyomo.dataportal.factory import DataManagerFactory @@ -93,7 +93,7 @@ class JSONDictionary(object): def __init__(self): self._info = {} - self.options = Options() + self.options = Bunch() def available(self): return True @@ -192,7 +192,7 @@ class YamlDictionary(object): def __init__(self): self._info = {} - self.options = Options() + self.options = Bunch() def available(self): return yaml_available diff --git a/pyomo/dataportal/process_data.py b/pyomo/dataportal/process_data.py index 9b0f158a529..77992113bce 100644 --- a/pyomo/dataportal/process_data.py +++ b/pyomo/dataportal/process_data.py @@ -14,7 +14,7 @@ import logging from pyomo.common.log import is_debug_set -from pyomo.common.collections import Options, OrderedDict +from pyomo.common.collections import Bunch, OrderedDict from pyomo.common.errors import ApplicationError from pyomo.dataportal.parse_datacmds import ( @@ -694,7 +694,7 @@ def _process_table(cmd, _model, _data, _default, options=None): #print("_param %s" % _param) #print("_labels %s" % _labels) # - options = Options(**_options) + options = Bunch(**_options) for key in options: if not key in ['columns']: raise ValueError("Unknown table option '%s'" % key) @@ -827,7 +827,7 @@ def _process_load(cmd, _model, _data, _default, options=None): if len(cmd) < 2: raise IOError("The 'load' command must specify a filename") - options = Options(**_options) + options = Bunch(**_options) for key in options: if not key in ['range','filename','format','using','driver','query','table','user','password','database']: raise ValueError("Unknown load option '%s'" % key) diff --git a/pyomo/mpec/plugins/pathampl.py b/pyomo/mpec/plugins/pathampl.py index 6f665559d16..3f32f40f9ac 100644 --- a/pyomo/mpec/plugins/pathampl.py +++ b/pyomo/mpec/plugins/pathampl.py @@ -12,7 +12,7 @@ from pyomo.opt.base.solvers import SolverFactory from pyomo.common import Executable -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.solvers.plugins.solvers.ASL import ASL logger = logging.getLogger('pyomo.solvers') @@ -32,7 +32,7 @@ def __init__(self, **kwds): # # Define solver capabilities, which default to 'None' # - self._capabilities = Options() + self._capabilities = Bunch() self._capabilities.linear = True def _default_executable(self): diff --git a/pyomo/opt/base/solvers.py b/pyomo/opt/base/solvers.py index 4d6acc77abd..e103b0c4bcd 100644 --- a/pyomo/opt/base/solvers.py +++ b/pyomo/opt/base/solvers.py @@ -22,7 +22,7 @@ from pyomo.common.config import ConfigBlock, ConfigList, ConfigValue from pyomo.common import Factory from pyomo.common.errors import ApplicationError -from pyomo.common.collections import Options +from pyomo.common.collections import Bunch from pyomo.opt.base.problem import ProblemConfigFactory from pyomo.opt.base.convert import convert_problem @@ -340,7 +340,7 @@ def __init__(self, **kwds): # through the solve command. Everything else is reset inside # presolve # - self.options = Options() + self.options = Bunch() if 'options' in kwds and not kwds['options'] is None: for key in kwds['options']: setattr(self.options, key, kwds['options'][key]) @@ -389,7 +389,7 @@ def __init__(self, **kwds): # We define no capabilities for the generic solver; base # classes must override this - self._capabilities = Options() + self._capabilities = Bunch() @staticmethod def _options_string_to_dict(istr): @@ -561,7 +561,7 @@ def solve(self, *args, **kwds): orig_options = self.options - self.options = Options() + self.options = Bunch() self.options.update(orig_options) self.options.update(kwds.pop('options', {})) self.options.update( From e4bcb33df5bedfe2dcac9a06d46fbaab855ffd97 Mon Sep 17 00:00:00 2001 From: Miranda Mundt Date: Wed, 24 Feb 2021 14:33:12 -0700 Subject: [PATCH 6/6] Adding Bunch tests --- pyomo/common/tests/test_bunch.py | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 pyomo/common/tests/test_bunch.py diff --git a/pyomo/common/tests/test_bunch.py b/pyomo/common/tests/test_bunch.py new file mode 100644 index 00000000000..af4d2c53d01 --- /dev/null +++ b/pyomo/common/tests/test_bunch.py @@ -0,0 +1,77 @@ +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC +# Under the terms of Contract DE-NA0003525 with National Technology and +# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain +# rights in this software. +# This software is distributed under the 3-clause BSD License. +# ___________________________________________________________________________ +# +# This module was originally developed as part of the PyUtilib project +# Copyright (c) 2008 Sandia Corporation. +# This software is distributed under the BSD License. +# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +# the U.S. Government retains certain rights in this software. +# ___________________________________________________________________________ + +import pickle +import unittest +from pyomo.common.collections import Bunch + +class Test(unittest.TestCase): + def test_Bunch1(self): + opt = Bunch('a=None c=d e="1 2 3"', foo=1, bar='x') + self.assertEqual(opt.ll, None) + self.assertEqual(opt.a, None) + self.assertEqual(opt.c, 'd') + self.assertEqual(opt.e, '1 2 3') + self.assertEqual(opt.foo, 1) + self.assertEqual(opt.bar, 'x') + self.assertEqual(opt['bar'], 'x') + opt.xx = 1 + opt['yy'] = 2 + self.assertEqual( + set(opt.keys()), set(['a', 'bar', 'c', 'foo', 'e', 'xx', 'yy'])) + opt.x = Bunch(a=1, b=2) + self.assertEqual( + set(opt.keys()), set( + ['a', 'bar', 'c', 'foo', 'e', 'xx', 'yy', 'x'])) + self.assertEqual( + repr(opt), + "Bunch(a = None, bar = 'x', c = 'd', e = '1 2 3', foo = 1, x = Bunch(a = 1, b = 2), xx = 1, yy = 2)") + self.assertEqual( + str(opt), """a: None +bar: 'x' +c: 'd' +e: '1 2 3' +foo: 1 +x: + a: 1 + b: 2 +xx: 1 +yy: 2""") + opt._name_ = 'BUNCH' + self.assertEqual( + set(opt.keys()), set( + ['a', 'bar', 'c', 'foo', 'e', 'xx', 'yy', 'x'])) + self.assertEqual( + repr(opt), + "Bunch(a = None, bar = 'x', c = 'd', e = '1 2 3', foo = 1, x = Bunch(a = 1, b = 2), xx = 1, yy = 2)") + self.assertEqual( + str(opt), """a: None +bar: 'x' +c: 'd' +e: '1 2 3' +foo: 1 +x: + a: 1 + b: 2 +xx: 1 +yy: 2""") + + def test_Container2(self): + o1 = Bunch('a=None c=d e="1 2 3"', foo=1, bar='x') + s = pickle.dumps(o1) + o2 = pickle.loads(s) + self.assertEqual(o1, o2)