Source code for pyomo.core.kernel.list_container

#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright (c) 2008-2024
#  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.
#  ___________________________________________________________________________

import logging
import collections.abc

from pyomo.core.kernel.tuple_container import TupleContainer

logger = logging.getLogger('pyomo.core')


[docs]class ListContainer(TupleContainer, collections.abc.MutableSequence): """ A partial implementation of the IHomogeneousContainer interface that provides list-like storage functionality. Complete implementations need to set the _ctype property at the class level and initialize the remaining ICategorizedObject attributes during object creation. If using __slots__, a slot named "_data" must be included. Note that this implementation allows nested storage of other ICategorizedObjectContainer implementations that are defined with the same ctype. """ __slots__ = ()
[docs] def __init__(self, *args): self._data = [] self._init(args)
# # Define the MutableSequence abstract methods # def __setitem__(self, i, item): if item.ctype is self.ctype: if item._parent is None: # be sure the current object is properly # removed logger.warning( "Implicitly replacing the entry %s (type=%s) " "with a new object (type=%s). This is usually " "indicative of a modeling error. To avoid this " "warning, delete the original object from the " "container before assigning a new object." % ( self[i].name, self[i].__class__.__name__, item.__class__.__name__, ) ) self._data[i]._clear_parent_and_storage_key() item._update_parent_and_storage_key(self, i) self._data[i] = item return elif self._data[i] is item: # a very special case that makes sense to handle # because the implied order should be: (1) delete # the object at the current index, (2) insert the # the new object. This performs both without any # actions, but it is an extremely rare case, so # it should go last. return # see note about allowing objects to live in more than # one container raise ValueError( "Invalid assignment to %s type with name '%s' " "at index %s. A parent container has already been " "assigned to the object being inserted: %s" % (self.__class__.__name__, self.name, i, item.parent.name) ) else: raise TypeError( "Invalid assignment to type %s with index %s. " "The object being inserted has the wrong " "category type: %s" % (self.__class__.__name__, i, item.ctype) )
[docs] def insert(self, i, item): """S.insert(index, object) -- insert object before index""" self._insert(i, item)
def __delitem__(self, i): self._data[i]._clear_parent_and_storage_key() del self._data[i] # # Override a few default implementations on Sequence # # We want to avoid issues with parent ownership # as we shuffle items
[docs] def reverse(self): """S.reverse() -- reverse *IN PLACE*""" n = len(self) data = self._data for i in range(n // 2): data[i], data[n - i - 1] = data[n - i - 1], data[i]