The Gaudi Framework  master (69a68366)
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 1572 of file Configurable.py.

1572def appendPostConfigAction(function):
1573 """
1574 Add a new callable ('function') to the list of post-configuration actions.
1575 If the callable is already in the list, it is moved to the end of the list.
1576 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1577 """
1578 try:
1579 postConfigActions.remove(function)
1580 except Exception:
1581 pass
1582 postConfigActions.append(function)
1583
1584

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

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

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

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

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

1741def getNeededConfigurables():
1742 """
1743 Function to select all and only the configurables that have to be used in
1744 GaudiPython.AppMgr constructor.
1745 This is needed because in Athena the implementation have to be different (the
1746 configuration is used in a different moment).
1747 """
1748 return sorted(
1749 k
1750 for k, v in Configurable.allConfigurables.items()
1751 if v.getGaudiType() != "User"
1752 ) # Exclude ConfigurableUser instances
1753
1754

◆ makeSequences()

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

Definition at line 1833 of file Configurable.py.

1833def makeSequences(expression):
1834 """
1835 Convert a control flow expression to nested GaudiSequencers.
1836 """
1837 if not isinstance(expression, ControlFlowNode):
1838 raise ValueError(
1839 "ControlFlowNode instance expected, got %s" % type(expression).__name__
1840 )
1841 visitor = CreateSequencesVisitor()
1842 expression.visitNode(visitor)
1843 return visitor.sequence
1844
1845

◆ purge()

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

Definition at line 1755 of file Configurable.py.

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

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

1585def removePostConfigAction(function):
1586 """
1587 Remove a callable from the list of post-config actions.
1588 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1589 """
1590 postConfigActions.remove(function)
1591
1592

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