3131from pyomo .common .sorting import sorted_robust
3232from pyomo .core .pyomoobject import PyomoObject
3333from pyomo .core .base .component_namer import name_repr , index_repr
34+ from pyomo .core .base .enums import SortComponents
3435from pyomo .core .base .global_set import UnindexedComponent_index
3536from pyomo .core .base .initializer import PartialInitializer
3637
4142)
4243
4344_ref_types = {type (None ), weakref_ref }
45+ DEFAULT_PPRINT_SORT = SortComponents .ALPHABETICAL | SortComponents .SORTED_INDICES
4446
4547
4648class ModelComponentFactoryClass (Factory ):
@@ -274,7 +276,7 @@ def __deepcopy_field__(self, value, memo, slot_name):
274276 def cname (self , * args , ** kwds ):
275277 return self .getname (* args , ** kwds )
276278
277- def pprint (self , ostream = None , verbose = False , prefix = "" ):
279+ def pprint (self , ostream = None , verbose = False , prefix = "" , sort = NOTSET ):
278280 """Print component information
279281
280282 Note that this method is generally only reachable through
@@ -292,12 +294,13 @@ def pprint(self, ostream=None, verbose=False, prefix=""):
292294 _name = comp .local_name
293295 else :
294296 # restrict output to only this data object
295- _data = iter (((self .index (), self ),))
297+ _data = lambda _sort : iter (((self .index (), self ),))
296298 _name = "{Member of %s}" % (comp .local_name ,)
297299 self ._pprint_base_impl (
298300 ostream ,
299301 verbose ,
300302 prefix ,
303+ sort ,
301304 _name ,
302305 comp .doc ,
303306 comp .is_constructed (),
@@ -348,6 +351,7 @@ def _pprint_base_impl(
348351 ostream ,
349352 verbose ,
350353 prefix ,
354+ sort ,
351355 _name ,
352356 _doc ,
353357 _constructed ,
@@ -361,6 +365,10 @@ def _pprint_base_impl(
361365 if prefix :
362366 ostream = StreamIndenter (ostream , prefix )
363367
368+ if sort is NOTSET :
369+ sort = DEFAULT_PPRINT_SORT
370+ sort = SortComponents (sort )
371+
364372 # FIXME: HACK for backwards compatibility with suppressing the
365373 # header for the top block
366374 if not _attr and self .parent_block () is None :
@@ -391,23 +399,37 @@ def _pprint_base_impl(
391399 return
392400
393401 if type (_fcn ) is tuple :
402+ # Exception to the standard formatter case: with two
403+ # callbacks, we will use the first to generate the normal
404+ # table, then call the second callback for each data.
405+ # Currently only used by Complimentarity (which should be
406+ # refactored to remove the need for this edge case)
394407 _fcn , _fcn2 = _fcn
395408 else :
396409 _fcn2 = None
397410
411+ if hasattr (_data , '__call__' ):
412+ _data = _data (sort )
413+
398414 if _header is not None :
415+ # This is a standard component, where all the component
416+ # information is printed in a single table
399417 if _fcn2 is not None :
400- _data_dict = dict (_data )
401- _data = _data_dict .items ()
418+ _data = list (_data )
402419 tabular_writer (ostream , '' , _data , _header , _fcn )
403420 if _fcn2 is not None :
404- for _key in sorted_robust ( _data_dict ) :
405- _fcn2 (ostream , _key , _data_dict [ _key ] )
421+ for _key , _val in _data :
422+ _fcn2 (ostream , sort , _key , _val )
406423 elif _fcn is not None :
407- _data_dict = dict (_data )
408- for _key in sorted_robust (_data_dict ):
409- _fcn (ostream , _key , _data_dict [_key ])
424+ # This is a non-standard component where we will not
425+ # generate a table at all, and instead defer all formatting
426+ # / printing to the callback. This is primarily used by
427+ # Blocks (and block-like things)
428+ for _key , _val in _data :
429+ _fcn (ostream , sort , _key , _val )
410430 elif _data is not None :
431+ # Catch all for everything else: assume that _pprint()
432+ # returned a formatted string.
411433 ostream .write (_data )
412434
413435
@@ -512,12 +534,13 @@ def valid_model_component(self):
512534 """Return True if this can be used as a model component."""
513535 return True
514536
515- def pprint (self , ostream = None , verbose = False , prefix = "" ):
537+ def pprint (self , ostream = None , verbose = False , prefix = "" , sort = NOTSET ):
516538 """Print component information"""
517539 self ._pprint_base_impl (
518540 ostream ,
519541 verbose ,
520542 prefix ,
543+ sort ,
521544 self .local_name ,
522545 self .doc ,
523546 self .is_constructed (),
0 commit comments