The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
GaudiKernel.Configurable Namespace Reference

Classes

class  _DefaultPropertiesCollectorHelper
 
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

 expandvars (data)
 
 appendPostConfigAction (function)
 
 removePostConfigAction (function)
 
 applyConfigurableUsers ()
 
 applyConfigurableUsers_old ()
 
 getNeededConfigurables ()
 
 purge ()
 
 makeSequences (expression)
 

Variables

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

Function Documentation

◆ appendPostConfigAction()

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 1580 of file Configurable.py.

1580def appendPostConfigAction(function):
1581 """
1582 Add a new callable ('function') to the list of post-configuration actions.
1583 If the callable is already in the list, it is moved to the end of the list.
1584 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1585 """
1586 try:
1587 postConfigActions.remove(function)
1588 except Exception:
1589 pass
1590 postConfigActions.append(function)
1591
1592

◆ applyConfigurableUsers()

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 1604 of file Configurable.py.

1604def applyConfigurableUsers():
1605 """
1606 Call the apply method of all the ConfigurableUser instances respecting the
1607 dependencies. First the C.U.s that are not used by anybody, then the used
1608 ones, when they are not used anymore.
1609 """
1610 # Avoid double calls
1611 global _appliedConfigurableUsers_, postConfigActions
1612 if _appliedConfigurableUsers_:
1613 return
1614 _appliedConfigurableUsers_ = True
1615
1616 def applicableConfUsers():
1617 """
1618 Generator returning all the configurables that can be applied in the
1619 order in which they can be applied.
1620 """
1621 # This is tricky...
1622 # We keep on looking for the first configurable that can be applied.
1623 # When we cannot find any, 'next()' raises a StopIteration that is
1624 # propagated outside of the infinite loop and the function, then handled
1625 # correctly from outside (it is the exception that is raised when you
1626 # exit from a generator).
1627 # Checking every time the full list is inefficient, but it is the
1628 # easiest way to fix bug #103803.
1629 # <https://savannah.cern.ch/bugs/?103803>
1630 while True:
1631 try:
1632 yield next(
1633 c
1634 for c in Configurable.allConfigurables.values()
1635 if c.isApplicable()
1636 )
1637 except StopIteration:
1638 break
1639
1640 debugApplyOrder = "GAUDI_DUBUG_CONF_USER" in os.environ
1641 for c in applicableConfUsers():
1642 if c._enabled:
1643 log.info("applying configuration of %s", c.name())
1644 if debugApplyOrder:
1645 sys.stderr.write("applying %r" % c)
1646 c.__apply_configuration__()
1647 log.info(c)
1648 else:
1649 log.info("skipping configuration of %s", c.name())
1650 c._applied = True # flag the instance as already applied
1651 if hasattr(c, "__detach_used__"):
1652 # tells the used configurables that they are not needed anymore
1653 c.__detach_used__()
1654
1655 # check for dependency loops
1656 leftConfUsers = [
1657 c
1658 for c in Configurable.allConfigurables.values()
1659 if hasattr(c, "__apply_configuration__") and c._enabled and not c._applied
1660 ]
1661 # if an enabled configurable has not been applied, there must be a dependency loop
1662 if leftConfUsers:
1663 raise Error(
1664 "Detected loop in the ConfigurableUser"
1665 " dependencies: %r" % [c.name() for c in leftConfUsers]
1666 )
1667 # ensure that all the Handles have been triggered
1668 known = set()
1669 unknown = set(Configurable.allConfigurables)
1670 while unknown:
1671 for k in unknown:
1672 if not known: # do not print during the first iteration
1673 log.debug("new configurable created automatically: %s", k)
1674 # this trigger the instantiation from handles
1675 Configurable.allConfigurables[k].properties()
1676 known.add(k)
1677 unknown -= known
1678 # Call post-config actions
1679 for action in postConfigActions:
1680 action()
1681
1682

◆ applyConfigurableUsers_old()

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 1683 of file Configurable.py.

1683def applyConfigurableUsers_old():
1684 """
1685 Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
1686 backward compatibility for configurations that where relying (implicitly) on
1687 bug #103803, or on a specific (non guaranteed) order of execution.
1688
1689 @see applyConfigurableUsers()
1690 """
1691 # Avoid double calls
1692 global _appliedConfigurableUsers_, postConfigActions
1693 if _appliedConfigurableUsers_:
1694 return
1695 _appliedConfigurableUsers_ = True
1696
1697 debugApplyOrder = "GAUDI_DUBUG_CONF_USER" in os.environ
1698 confUsers = [
1699 c
1700 for c in Configurable.allConfigurables.values()
1701 if hasattr(c, "__apply_configuration__")
1702 ]
1703 applied = True # needed to detect dependency loops
1704 while applied and confUsers:
1705 newConfUsers = [] # list of conf users that cannot be applied yet
1706 applied = False
1707 for c in confUsers:
1708 if hasattr(c, "__users__") and c.__users__:
1709 newConfUsers.append(c) # cannot use this one yet
1710 else: # it does not have users or the list is empty
1711 applied = True
1712 # the ConfigurableUser is enabled if it doesn't have an _enabled
1713 # property or its value is True
1714 enabled = (not hasattr(c, "_enabled")) or c._enabled
1715 if enabled:
1716 log.info("applying configuration of %s", c.name())
1717 if debugApplyOrder:
1718 sys.stderr.write("applying %r" % c)
1719 c.__apply_configuration__()
1720 log.info(c)
1721 else:
1722 log.info("skipping configuration of %s", c.name())
1723 if hasattr(c, "__detach_used__"):
1724 # tells the used configurables that they are not needed anymore
1725 c.__detach_used__()
1726 confUsers = newConfUsers # list of C.U.s still to go
1727 if confUsers:
1728 # this means that some C.U.s could not be applied because of a dependency loop
1729 raise Error(
1730 "Detected loop in the ConfigurableUser "
1731 " dependencies: %r" % [c.name() for c in confUsers]
1732 )
1733 # ensure that all the Handles have been triggered
1734 known = set()
1735 unknown = set(Configurable.allConfigurables)
1736 while unknown:
1737 for k in unknown:
1738 if not known: # do not print during the first iteration
1739 log.debug("new configurable created automatically: %s", k)
1740 # this trigger the instantiation from handles
1741 Configurable.allConfigurables[k].properties()
1742 known.add(k)
1743 unknown -= known
1744 # Call post-config actions
1745 for action in postConfigActions:
1746 action()
1747
1748

◆ expandvars()

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 82 of file Configurable.py.

82def expandvars(data):
83 """
84 Expand environment variables "data".
85 Data can be string, list, tuple and dictionary. For collection, all the
86 contained strings will be manipulated (recursively).
87 """
88 import os.path
89
90 typ = type(data)
91 if typ is str:
92 return os.path.expandvars(data)
93 elif typ in [list, tuple]:
94 collect = []
95 for i in data:
96 collect.append(expandvars(i))
97 return typ(collect)
98 elif typ is dict:
99 collect = {}
100 for k in data:
101 collect[expandvars(k)] = expandvars(data[k])
102 return collect
103 return data
104
105

◆ getNeededConfigurables()

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 1749 of file Configurable.py.

1749def getNeededConfigurables():
1750 """
1751 Function to select all and only the configurables that have to be used in
1752 GaudiPython.AppMgr constructor.
1753 This is needed because in Athena the implementation have to be different (the
1754 configuration is used in a different moment).
1755 """
1756 return sorted(
1757 k
1758 for k, v in Configurable.allConfigurables.items()
1759 if v.getGaudiType() != "User"
1760 ) # Exclude ConfigurableUser instances
1761
1762

◆ makeSequences()

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

Definition at line 1841 of file Configurable.py.

1841def makeSequences(expression):
1842 """
1843 Convert a control flow expression to nested GaudiSequencers.
1844 """
1845 if not isinstance(expression, ControlFlowNode):
1846 raise ValueError(
1847 "ControlFlowNode instance expected, got %s" % type(expression).__name__
1848 )
1849 visitor = CreateSequencesVisitor()
1850 expression.visitNode(visitor)
1851 return visitor.sequence
1852
1853

◆ purge()

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

Definition at line 1763 of file Configurable.py.

1763def purge():
1764 """
1765 Clean up all configurations and configurables.
1766 """
1767 for c in Configurable.allConfigurables.values():
1768 c.__class__.configurables.clear()
1769 Configurable.allConfigurables.clear()
1770 # FIXME: (MCl) this is needed because instances of ConfigurableGeneric are not
1771 # migrated to the correct class when this is known.
1772 ConfigurableGeneric.configurables.clear()
1773 import os.path
1774 import sys
1775
1776 from .ProcessJobOptions import _included_files
1777
1778 for file in _included_files:
1779 dirname, basname = os.path.split(file)
1780 basname, ext = os.path.splitext(basname)
1781 if basname in sys.modules:
1782 del sys.modules[basname]
1783 _included_files.clear()
1784
1785

◆ removePostConfigAction()

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 1593 of file Configurable.py.

1593def removePostConfigAction(function):
1594 """
1595 Remove a callable from the list of post-config actions.
1596 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1597 """
1598 postConfigActions.remove(function)
1599
1600

Variable Documentation

◆ __all__

list GaudiKernel.Configurable.__all__
private
Initial value:
1= [
2 "Configurable",
3 "ConfigurableAlgorithm",
4 "ConfigurableAlgTool",
5 "ConfigurableAuditor",
6 "ConfigurableService",
7 "ConfigurableUser",
8 "VERBOSE",
9 "DEBUG",
10 "INFO",
11 "WARNING",
12 "ERROR",
13 "FATAL",
14 "appendPostConfigAction",
15 "removePostConfigAction",
16]

Definition at line 54 of file Configurable.py.

◆ _appliedConfigurableUsers_

bool GaudiKernel.Configurable._appliedConfigurableUsers_ = False
protected

Definition at line 1601 of file Configurable.py.

◆ log

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

Definition at line 79 of file Configurable.py.

◆ postConfigActions

list GaudiKernel.Configurable.postConfigActions = []

Definition at line 1577 of file Configurable.py.