The Gaudi Framework  v36r0 (4abb4d13)
GaudiKernel.Configurable Namespace Reference

Classes

class  Configurable
 
class  ConfigurableAlgorithm
 
class  ConfigurableAlgTool
 
class  ConfigurableAuditor
 
class  ConfigurableGeneric
 
class  ConfigurableService
 
class  ConfigurableUser
 
class  CreateSequencesVisitor
 
class  DummyDescriptor
 
class  Error
 
class  PropertyReference
 
class  SuperAlgorithm
 

Functions

def expandvars (data)
 
def isApplicable (self)
 rep += v.__str__( indent + 1 ) + os.linesep elif isinstance(v,GaudiHandleArray): for vi in v: if isinstance(vi,Configurable) and not vi.isPublic(): rep += vi.__str__( indent + 1 ) + os.linesep More...
 
def appendPostConfigAction (function)
 
def removePostConfigAction (function)
 
def applyConfigurableUsers ()
 
def applyConfigurableUsers_old ()
 
def getNeededConfigurables ()
 
def purge ()
 
def makeSequences (expression)
 

Variables

list __all__
 
 log = logging.getLogger('Configurable')
 
list postConfigActions = []
 
bool _appliedConfigurableUsers_ = False
 

Function Documentation

◆ appendPostConfigAction()

def GaudiKernel.Configurable.appendPostConfigAction (   function)
Add a new callable ('function') to the list of post-configuration actions.
If the callable is already in the list, it is moved to the end of the list.
The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.

Definition at line 1518 of file Configurable.py.

1518 def appendPostConfigAction(function):
1519  """
1520  Add a new callable ('function') to the list of post-configuration actions.
1521  If the callable is already in the list, it is moved to the end of the list.
1522  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1523  """
1524  try:
1525  postConfigActions.remove(function)
1526  except:
1527  pass
1528  postConfigActions.append(function)
1529 
1530 

◆ applyConfigurableUsers()

def GaudiKernel.Configurable.applyConfigurableUsers ( )
Call the apply method of all the ConfigurableUser instances respecting the
dependencies. First the C.U.s that are not used by anybody, then the used
ones, when they are not used anymore.

Definition at line 1542 of file Configurable.py.

1543  """
1544  Call the apply method of all the ConfigurableUser instances respecting the
1545  dependencies. First the C.U.s that are not used by anybody, then the used
1546  ones, when they are not used anymore.
1547  """
1548  # Avoid double calls
1549  global _appliedConfigurableUsers_, postConfigActions
1550  if _appliedConfigurableUsers_:
1551  return
1552  _appliedConfigurableUsers_ = True
1553 
1554  def applicableConfUsers():
1555  '''
1556  Generator returning all the configurables that can be applied in the
1557  order in which they can be applied.
1558  '''
1559  # This is tricky...
1560  # We keep on looking for the first configurable that can be applied.
1561  # When we cannot find any, 'next()' raises a StopIteration that is
1562  # propagated outside of the infinite loop and the function, then handled
1563  # correctly from outside (it is the exception that is raised when you
1564  # exit from a generator).
1565  # Checking every time the full list is inefficient, but it is the
1566  # easiest way to fix bug #103803.
1567  # <https://savannah.cern.ch/bugs/?103803>
1568  while True:
1569  try:
1570  yield next(c for c in Configurable.allConfigurables.values()
1571  if c.isApplicable())
1572  except StopIteration:
1573  break
1574 
1575  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1576  for c in applicableConfUsers():
1577  if c._enabled:
1578  log.info("applying configuration of %s", c.name())
1579  if debugApplyOrder:
1580  sys.stderr.write('applying %r' % c)
1581  c.__apply_configuration__()
1582  log.info(c)
1583  else:
1584  log.info("skipping configuration of %s", c.name())
1585  c._applied = True # flag the instance as already applied
1586  if hasattr(c, "__detach_used__"):
1587  # tells the used configurables that they are not needed anymore
1588  c.__detach_used__()
1589 
1590  # check for dependency loops
1591  leftConfUsers = [
1592  c for c in Configurable.allConfigurables.values() if
1593  hasattr(c, '__apply_configuration__') and c._enabled and not c._applied
1594  ]
1595  # if an enabled configurable has not been applied, there must be a dependency loop
1596  if leftConfUsers:
1597  raise Error("Detected loop in the ConfigurableUser"
1598  " dependencies: %r" % [c.name() for c in leftConfUsers])
1599  # ensure that all the Handles have been triggered
1600  known = set()
1601  unknown = set(Configurable.allConfigurables)
1602  while unknown:
1603  for k in unknown:
1604  if not known: # do not print during the first iteration
1605  log.debug('new configurable created automatically: %s', k)
1606  # this trigger the instantiation from handles
1607  Configurable.allConfigurables[k].properties()
1608  known.add(k)
1609  unknown -= known
1610  # Call post-config actions
1611  for action in postConfigActions:
1612  action()
1613 
1614 

◆ applyConfigurableUsers_old()

def GaudiKernel.Configurable.applyConfigurableUsers_old ( )
Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
backward compatibility for configurations that where relying (implicitly) on
bug #103803, or on a specific (non guaranteed) order of execution.

@see applyConfigurableUsers()

Definition at line 1615 of file Configurable.py.

1616  """
1617  Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
1618  backward compatibility for configurations that where relying (implicitly) on
1619  bug #103803, or on a specific (non guaranteed) order of execution.
1620 
1621  @see applyConfigurableUsers()
1622  """
1623  # Avoid double calls
1624  global _appliedConfigurableUsers_, postConfigActions
1625  if _appliedConfigurableUsers_:
1626  return
1627  _appliedConfigurableUsers_ = True
1628 
1629  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1630  confUsers = [
1631  c for c in Configurable.allConfigurables.values()
1632  if hasattr(c, "__apply_configuration__")
1633  ]
1634  applied = True # needed to detect dependency loops
1635  while applied and confUsers:
1636  newConfUsers = [] # list of conf users that cannot be applied yet
1637  applied = False
1638  for c in confUsers:
1639  if hasattr(c, "__users__") and c.__users__:
1640  newConfUsers.append(c) # cannot use this one yet
1641  else: # it does not have users or the list is empty
1642  applied = True
1643  # the ConfigurableUser is enabled if it doesn't have an _enabled
1644  # property or its value is True
1645  enabled = (not hasattr(c, "_enabled")) or c._enabled
1646  if enabled:
1647  log.info("applying configuration of %s", c.name())
1648  if debugApplyOrder:
1649  sys.stderr.write('applying %r' % c)
1650  c.__apply_configuration__()
1651  log.info(c)
1652  else:
1653  log.info("skipping configuration of %s", c.name())
1654  if hasattr(c, "__detach_used__"):
1655  # tells the used configurables that they are not needed anymore
1656  c.__detach_used__()
1657  confUsers = newConfUsers # list of C.U.s still to go
1658  if confUsers:
1659  # this means that some C.U.s could not be applied because of a dependency loop
1660  raise Error("Detected loop in the ConfigurableUser "
1661  " dependencies: %r" % [c.name() for c in confUsers])
1662  # ensure that all the Handles have been triggered
1663  known = set()
1664  unknown = set(Configurable.allConfigurables)
1665  while unknown:
1666  for k in unknown:
1667  if not known: # do not print during the first iteration
1668  log.debug('new configurable created automatically: %s', k)
1669  # this trigger the instantiation from handles
1670  Configurable.allConfigurables[k].properties()
1671  known.add(k)
1672  unknown -= known
1673  # Call post-config actions
1674  for action in postConfigActions:
1675  action()
1676 
1677 

◆ expandvars()

def GaudiKernel.Configurable.expandvars (   data)
Expand environment variables "data".
Data can be string, list, tuple and dictionary. For collection, all the
contained strings will be manipulated (recursively).

Definition at line 47 of file Configurable.py.

47 def expandvars(data):
48  """
49  Expand environment variables "data".
50  Data can be string, list, tuple and dictionary. For collection, all the
51  contained strings will be manipulated (recursively).
52  """
53  import os.path
54  typ = type(data)
55  if typ is str:
56  return os.path.expandvars(data)
57  elif typ in [list, tuple]:
58  collect = []
59  for i in data:
60  collect.append(expandvars(i))
61  return typ(collect)
62  elif typ is dict:
63  collect = {}
64  for k in data:
65  collect[expandvars(k)] = expandvars(data[k])
66  return collect
67  return data
68 
69 

◆ getNeededConfigurables()

def GaudiKernel.Configurable.getNeededConfigurables ( )
Function to select all and only the configurables that have to be used in
GaudiPython.AppMgr constructor.
This is needed because in Athena the implementation have to be different (the
configuration is used in a different moment).

Definition at line 1678 of file Configurable.py.

1679  """
1680  Function to select all and only the configurables that have to be used in
1681  GaudiPython.AppMgr constructor.
1682  This is needed because in Athena the implementation have to be different (the
1683  configuration is used in a different moment).
1684  """
1685  return sorted(
1686  k for k, v in Configurable.allConfigurables.items()
1687  if v.getGaudiType() != "User") # Exclude ConfigurableUser instances
1688 
1689 

◆ isApplicable()

def GaudiKernel.Configurable.isApplicable (   self)

rep += v.__str__( indent + 1 ) + os.linesep elif isinstance(v,GaudiHandleArray): for vi in v: if isinstance(vi,Configurable) and not vi.isPublic(): rep += vi.__str__( indent + 1 ) + os.linesep

Return True is the instance can be "applied".
Always False for plain Configurable instances
(i.e. not ConfigurableUser).

Definition at line 1013 of file Configurable.py.

1013  def isApplicable(self):
1014  '''
1015  Return True is the instance can be "applied".
1016  Always False for plain Configurable instances
1017  (i.e. not ConfigurableUser).
1018  '''
1019  return False
1020 
1021 
1022 # classes for generic Gaudi component ===========
1023 
1024 

◆ makeSequences()

def GaudiKernel.Configurable.makeSequences (   expression)
Convert a control flow expression to nested GaudiSequencers.

Definition at line 1764 of file Configurable.py.

1764 def makeSequences(expression):
1765  '''
1766  Convert a control flow expression to nested GaudiSequencers.
1767  '''
1768  if not isinstance(expression, ControlFlowNode):
1769  raise ValueError('ControlFlowNode instance expected, got %s' %
1770  type(expression).__name__)
1771  visitor = CreateSequencesVisitor()
1772  expression.visitNode(visitor)
1773  return visitor.sequence
1774 
1775 

◆ purge()

def GaudiKernel.Configurable.purge ( )
Clean up all configurations and configurables.

Definition at line 1690 of file Configurable.py.

1690 def purge():
1691  """
1692  Clean up all configurations and configurables.
1693  """
1694  for c in Configurable.allConfigurables.values():
1695  c.__class__.configurables.clear()
1696  Configurable.allConfigurables.clear()
1697  # FIXME: (MCl) this is needed because instances of ConfigurableGeneric are not
1698  # migrated to the correct class when this is known.
1699  ConfigurableGeneric.configurables.clear()
1700  from .ProcessJobOptions import _included_files
1701  import os.path
1702  import sys
1703  for file in _included_files:
1704  dirname, basname = os.path.split(file)
1705  basname, ext = os.path.splitext(basname)
1706  if basname in sys.modules:
1707  del sys.modules[basname]
1708  _included_files.clear()
1709 
1710 

◆ removePostConfigAction()

def GaudiKernel.Configurable.removePostConfigAction (   function)
Remove a callable from the list of post-config actions.
The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.

Definition at line 1531 of file Configurable.py.

1531 def removePostConfigAction(function):
1532  """
1533  Remove a callable from the list of post-config actions.
1534  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1535  """
1536  postConfigActions.remove(function)
1537 
1538 

Variable Documentation

◆ __all__

list GaudiKernel.Configurable.__all__
private
Initial value:
1 = [
2  'Configurable', 'ConfigurableAlgorithm', 'ConfigurableAlgTool',
3  'ConfigurableAuditor', 'ConfigurableService', 'ConfigurableUser',
4  'VERBOSE', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'FATAL',
5  'appendPostConfigAction', 'removePostConfigAction'
6 ]

Definition at line 35 of file Configurable.py.

◆ _appliedConfigurableUsers_

bool GaudiKernel.Configurable._appliedConfigurableUsers_ = False
private

Definition at line 1539 of file Configurable.py.

◆ log

GaudiKernel.Configurable.log = logging.getLogger('Configurable')

Definition at line 44 of file Configurable.py.

◆ postConfigActions

list GaudiKernel.Configurable.postConfigActions = []

Definition at line 1515 of file Configurable.py.

GaudiKernel.Configurable.applyConfigurableUsers_old
def applyConfigurableUsers_old()
Definition: Configurable.py:1615
GaudiKernel.Configurable.makeSequences
def makeSequences(expression)
Definition: Configurable.py:1764
GaudiKernel.Configurable.appendPostConfigAction
def appendPostConfigAction(function)
Definition: Configurable.py:1518
GaudiKernel.Configurable.isApplicable
def isApplicable(self)
rep += v.__str__( indent + 1 ) + os.linesep elif isinstance(v,GaudiHandleArray): for vi in v: if isin...
Definition: Configurable.py:1013
gaudiComponentHelp.properties
properties
Definition: gaudiComponentHelp.py:62
gaudirun.type
type
Definition: gaudirun.py:154
GaudiKernel.Configurable.removePostConfigAction
def removePostConfigAction(function)
Definition: Configurable.py:1531
GaudiKernel.Configurable.getNeededConfigurables
def getNeededConfigurables()
Definition: Configurable.py:1678
gaudirun.action
action
Definition: gaudirun.py:148
GaudiKernel.Configurable.purge
def purge()
Definition: Configurable.py:1690
GaudiKernel.Configurable.expandvars
def expandvars(data)
Definition: Configurable.py:47
GaudiKernel.Configurable.applyConfigurableUsers
def applyConfigurableUsers()
Definition: Configurable.py:1542