Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-14 23:36:20

0001 #!/usr/bin/env python3
0002 
0003 ### command line options helper
0004 import os
0005 from  .Options import Options
0006 options = Options()
0007 
0008 
0009 ## imports
0010 import sys
0011 from typing import Union
0012 from .Mixins import PrintOptions,_ParameterTypeBase,_SimpleParameterTypeBase, _Parameterizable, _ConfigureComponent, _TypedParameterizable, _Labelable,  _Unlabelable,  _ValidatingListBase, _modifyParametersFromDict
0013 from .Mixins import *
0014 from .Types import *
0015 from .Modules import *
0016 from .Modules import _Module
0017 from .SequenceTypes import *
0018 from .SequenceTypes import _ModuleSequenceType, _Sequenceable  #extend needs it
0019 from .SequenceVisitors import PathValidator, EndPathValidator, ScheduleTaskValidator, NodeVisitor, CompositeVisitor, ModuleNamesFromGlobalsVisitor
0020 from .MessageLogger import MessageLogger
0021 from . import DictTypes
0022 
0023 from .ExceptionHandling import *
0024 
0025 #when building RECO paths we have hit the default recursion limit
0026 if sys.getrecursionlimit()<5000:
0027     sys.setrecursionlimit(5000)
0028 
0029 class edm(object):
0030     class errors(object):
0031         #Allowed errors to be used within Python
0032         Configuration = "{Configuration}"
0033         UnavailableAccelerator = "{UnavailableAccelerator}"
0034 
0035 class EDMException(Exception):
0036     def __init__(self, error:str, message: str):
0037         super().__init__(error+"\n"+message)
0038 
0039 
0040 def checkImportPermission(minLevel: int = 2, allowedPatterns = []):
0041     """
0042     Raise an exception if called by special config files. This checks
0043     the call or import stack for the importing file. An exception is raised if
0044     the importing module is not in allowedPatterns and if it is called too deeply:
0045     minLevel = 2: inclusion by top lvel cfg only
0046     minLevel = 1: No inclusion allowed
0047     allowedPatterns = ['Module1','Module2/SubModule1'] allows import
0048     by any module in Module1 or Submodule1
0049     """
0050 
0051     import inspect
0052     import os
0053 
0054     ignorePatterns = ['FWCore/ParameterSet/Config.py', 'FWCore/ParameterSet/python/Config.py','<string>','<frozen ']
0055     CMSSWPath = [os.path.realpath(os.getenv(base)) for base in ['CMSSW_BASE', 'CMSSW_RELEASE_BASE', 'CMSSW_FULL_RELEASE_BASE'] if os.getenv(base, '')]
0056 
0057     # Filter the stack to things in CMSSWPath and not in ignorePatterns
0058     trueStack = []
0059     for item in inspect.stack():
0060         inPath = False
0061         ignore = False
0062 
0063         for pattern in CMSSWPath:
0064             if item[1].find(pattern) != -1:
0065                 inPath = True
0066                 break
0067         if item[1].find('/') == -1: # The base file, no path
0068             inPath = True
0069 
0070         for pattern in ignorePatterns:
0071             if item[1].find(pattern) != -1:
0072                 ignore = True
0073                 break
0074 
0075         if inPath and not ignore:
0076             trueStack.append(item[1])
0077 
0078     importedFile = trueStack[0]
0079     importedBy   = ''
0080     if len(trueStack) > 1:
0081         importedBy = trueStack[1]
0082 
0083     for pattern in allowedPatterns:
0084         if importedBy.find(pattern) > -1:
0085             return True
0086 
0087     if len(trueStack) <= minLevel: # Imported directly
0088         return True
0089 
0090     raise ImportError("Inclusion of %s is allowed only by cfg or specified cfi files."
0091                       % importedFile)
0092 
0093 def findProcess(module):
0094     """Look inside the module and find the Processes it contains"""
0095     class Temp(object):
0096         pass
0097     process = None
0098     if isinstance(module,dict):
0099         if 'process' in module:
0100             p = module['process']
0101             module = Temp()
0102             module.process = p
0103     if hasattr(module,'process'):
0104         if isinstance(module.process,Process):
0105             process = module.process
0106         else:
0107             raise RuntimeError("The attribute named 'process' does not inherit from the Process class")
0108     else:
0109         raise RuntimeError("no 'process' attribute found in the module, please add one")
0110     return process
0111 
0112 class Process(object):
0113     """Root class for a CMS configuration process"""
0114     _firstProcess = True
0115     def __init__(self,name: str, *Mods):
0116         """The argument 'name' will be the name applied to this Process
0117             Can optionally pass as additional arguments cms.Modifier instances
0118             that will be used to modify the Process as it is built
0119             """
0120         self.__dict__['_Process__name'] = name
0121         if not name.isalnum():
0122             raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
0123         self.__dict__['_Process__filters'] = {}
0124         self.__dict__['_Process__producers'] = {}
0125         self.__dict__['_Process__switchproducers'] = {}
0126         self.__dict__['_Process__source'] = None
0127         self.__dict__['_Process__looper'] = None
0128         self.__dict__['_Process__schedule'] = None
0129         self.__dict__['_Process__analyzers'] = {}
0130         self.__dict__['_Process__outputmodules'] = {}
0131         self.__dict__['_Process__paths'] = DictTypes.SortedKeysDict()    # have to keep the order
0132         self.__dict__['_Process__endpaths'] = DictTypes.SortedKeysDict() # of definition
0133         self.__dict__['_Process__sequences'] = {}
0134         self.__dict__['_Process__tasks'] = {}
0135         self.__dict__['_Process__conditionaltasks'] = {}
0136         self.__dict__['_Process__services'] = {}
0137         self.__dict__['_Process__essources'] = {}
0138         self.__dict__['_Process__esproducers'] = {}
0139         self.__dict__['_Process__esprefers'] = {}
0140         self.__dict__['_Process__aliases'] = {}
0141         self.__dict__['_Process__psets']={}
0142         self.__dict__['_Process__vpsets']={}
0143         self.__dict__['_cloneToObjectDict'] = {}
0144         # policy switch to avoid object overwriting during extend/load
0145         self.__dict__['_Process__InExtendCall'] = False
0146         self.__dict__['_Process__partialschedules'] = {}
0147         self.__isStrict = False
0148         self.__dict__['_Process__modifiers'] = Mods
0149         self.__dict__['_Process__accelerators'] = {}
0150         self.__dict__['_Process__specialOverrideReleaseVersionOnlyForTesting'] = None
0151         self.__injectValidValue('options', Process.defaultOptions_())
0152         self.__injectValidValue('maxEvents', Process.defaultMaxEvents_())
0153         self.maxLuminosityBlocks = Process.defaultMaxLuminosityBlocks_()
0154         # intentionally not cloned to ensure that everyone taking
0155         # MessageLogger still via
0156         # FWCore.Message(Logger|Service).MessageLogger_cfi
0157         # use the very same MessageLogger object.
0158         self.MessageLogger = MessageLogger
0159         if Process._firstProcess:
0160             Process._firstProcess = False
0161         else:
0162             if len(Mods) > 0:
0163                 for m in self.__modifiers:
0164                     if not m._isChosen():
0165                         raise RuntimeError("The Process {} tried to redefine which Modifiers to use after another Process was already started".format(name))
0166         for m in self.__modifiers:
0167             m._setChosen()
0168 
0169     def setStrict(self, value: bool):
0170         self.__isStrict = value
0171         _Module.__isStrict__ = True
0172 
0173     # some user-friendly methods for command-line browsing
0174     def producerNames(self):
0175         """Returns a string containing all the EDProducer labels separated by a blank"""
0176         return ' '.join(self.producers_().keys())
0177     def switchProducerNames(self):
0178         """Returns a string containing all the SwitchProducer labels separated by a blank"""
0179         return ' '.join(self.switchProducers_().keys())
0180     def analyzerNames(self):
0181         """Returns a string containing all the EDAnalyzer labels separated by a blank"""
0182         return ' '.join(self.analyzers_().keys())
0183     def filterNames(self):
0184         """Returns a string containing all the EDFilter labels separated by a blank"""
0185         return ' '.join(self.filters_().keys())
0186     def pathNames(self):
0187         """Returns a string containing all the Path names separated by a blank"""
0188         return ' '.join(self.paths_().keys())
0189 
0190     def __setstate__(self, pkldict):
0191         """
0192         Unpickling hook.
0193 
0194         Since cloneToObjectDict stores a hash of objects by their
0195         id() it needs to be updated when unpickling to use the
0196         new object id values instantiated during the unpickle.
0197 
0198         """
0199         self.__dict__.update(pkldict)
0200         tmpDict = {}
0201         for value in self._cloneToObjectDict.values():
0202             tmpDict[id(value)] = value
0203         self.__dict__['_cloneToObjectDict'] = tmpDict
0204 
0205 
0206 
0207     def filters_(self):
0208         """returns a dict of the filters that have been added to the Process"""
0209         return DictTypes.FixedKeysDict(self.__filters)
0210     filters = property(filters_, doc="dictionary containing the filters for the process")
0211     def name_(self) -> str:
0212         return self.__name
0213     def setName_(self,name: str):
0214         if not name.isalnum():
0215             raise RuntimeError("Error: The process name is an empty string or contains non-alphanumeric characters")
0216         self.__dict__['_Process__name'] = name
0217     process = property(name_,setName_, doc="name of the process")
0218     def producers_(self):
0219         """returns a dict of the producers that have been added to the Process"""
0220         return DictTypes.FixedKeysDict(self.__producers)
0221     producers = property(producers_,doc="dictionary containing the producers for the process")
0222     def switchProducers_(self):
0223         """returns a dict of the SwitchProducers that have been added to the Process"""
0224         return DictTypes.FixedKeysDict(self.__switchproducers)
0225     switchProducers = property(switchProducers_,doc="dictionary containing the SwitchProducers for the process")
0226     def source_(self):
0227         """returns the source that has been added to the Process or None if none have been added"""
0228         return self.__source
0229     def setSource_(self,src):
0230         self._placeSource('source',src)
0231     source = property(source_,setSource_,doc='the main source or None if not set')
0232     def looper_(self):
0233         """returns the looper that has been added to the Process or None if none have been added"""
0234         return self.__looper
0235     def setLooper_(self,lpr):
0236         self._placeLooper('looper',lpr)
0237     looper = property(looper_,setLooper_,doc='the main looper or None if not set')
0238     @staticmethod
0239     def defaultOptions_():
0240         return untracked.PSet(numberOfThreads = untracked.uint32(1),
0241                               numberOfStreams = untracked.uint32(0),
0242                               numberOfConcurrentRuns = untracked.uint32(1),
0243                               numberOfConcurrentLuminosityBlocks = untracked.uint32(0),
0244                               eventSetup = untracked.PSet(
0245                                   numberOfConcurrentIOVs = untracked.uint32(0),
0246                                   forceNumberOfConcurrentIOVs = untracked.PSet(
0247                                       allowAnyLabel_ = required.untracked.uint32
0248                                   )
0249                               ),
0250                               accelerators = untracked.vstring('*'),
0251                               wantSummary = untracked.bool(False),
0252                               fileMode = untracked.string('FULLMERGE'),
0253                               forceEventSetupCacheClearOnNewRun = untracked.bool(False),
0254                               throwIfIllegalParameter = untracked.bool(True),
0255                               printDependencies = untracked.bool(False),
0256                               deleteNonConsumedUnscheduledModules = untracked.bool(True),
0257                               sizeOfStackForThreadsInKB = optional.untracked.uint32,
0258                               Rethrow = untracked.vstring(),
0259                               TryToContinue = untracked.vstring(),
0260                               IgnoreCompletely = untracked.vstring(),
0261                               modulesToCallForTryToContinue = untracked.vstring(),
0262                               canDeleteEarly = untracked.vstring(),
0263                               holdsReferencesToDeleteEarly = untracked.VPSet(),
0264                               modulesToIgnoreForDeleteEarly = untracked.vstring(),
0265                               dumpOptions = untracked.bool(False),
0266                               allowUnscheduled = obsolete.untracked.bool,
0267                               emptyRunLumiMode = obsolete.untracked.string,
0268                               makeTriggerResults = obsolete.untracked.bool,
0269                               )
0270     def __updateOptions(self,opt):
0271         newOpts = self.defaultOptions_()
0272         if isinstance(opt,dict):
0273             for k,v in opt.items():
0274                 setattr(newOpts,k,v)
0275         else:
0276             for p in opt.parameters_():
0277                 setattr(newOpts, p, getattr(opt,p))
0278         return newOpts
0279     @staticmethod
0280     def defaultMaxEvents_():
0281         return untracked.PSet(input=optional.untracked.int32,
0282                               output=optional.untracked.allowed(int32,PSet))
0283     def __updateMaxEvents(self,ps: Union[dict,PSet]):
0284         newMax = self.defaultMaxEvents_()
0285         if isinstance(ps,dict):
0286             for k,v in ps.items():
0287                 setattr(newMax,k,v)
0288         else:
0289             for p in ps.parameters_():
0290                 setattr(newMax, p, getattr(ps,p))
0291         return newMax
0292     @staticmethod
0293     def defaultMaxLuminosityBlocks_():
0294         return untracked.PSet(input=untracked.int32(-1))
0295     def analyzers_(self):
0296         """returns a dict of the analyzers that have been added to the Process"""
0297         return DictTypes.FixedKeysDict(self.__analyzers)
0298     analyzers = property(analyzers_,doc="dictionary containing the analyzers for the process")
0299     def outputModules_(self):
0300         """returns a dict of the output modules that have been added to the Process"""
0301         return DictTypes.FixedKeysDict(self.__outputmodules)
0302     outputModules = property(outputModules_,doc="dictionary containing the output_modules for the process")
0303     def paths_(self):
0304         """returns a dict of the paths that have been added to the Process"""
0305         return DictTypes.SortedAndFixedKeysDict(self.__paths)
0306     paths = property(paths_,doc="dictionary containing the paths for the process")
0307     def endpaths_(self):
0308         """returns a dict of the endpaths that have been added to the Process"""
0309         return DictTypes.SortedAndFixedKeysDict(self.__endpaths)
0310     endpaths = property(endpaths_,doc="dictionary containing the endpaths for the process")
0311     def sequences_(self):
0312         """returns a dict of the sequences that have been added to the Process"""
0313         return DictTypes.FixedKeysDict(self.__sequences)
0314     sequences = property(sequences_,doc="dictionary containing the sequences for the process")
0315     def tasks_(self):
0316         """returns a dict of the tasks that have been added to the Process"""
0317         return DictTypes.FixedKeysDict(self.__tasks)
0318     tasks = property(tasks_,doc="dictionary containing the tasks for the process")
0319     def conditionaltasks_(self):
0320         """returns a dict of the conditionaltasks that have been added to the Process"""
0321         return DictTypes.FixedKeysDict(self.__conditionaltasks)
0322     conditionaltasks = property(conditionaltasks_,doc="dictionary containing the conditionatasks for the process")
0323     def schedule_(self):
0324         """returns the schedule that has been added to the Process or None if none have been added"""
0325         return self.__schedule
0326     def setPartialSchedule_(self,sch: Schedule,label: str):
0327         if label == "schedule":
0328             self.setSchedule_(sch)
0329         else:
0330             self._place(label, sch, self.__partialschedules)
0331     def setSchedule_(self,sch: Schedule):
0332         # See if every path and endpath has been inserted into the process
0333         index = 0
0334         try:
0335             for p in sch:
0336                 p.label_()
0337                 index +=1
0338         except:
0339             raise RuntimeError("The path at index "+str(index)+" in the Schedule was not attached to the process.")
0340         self.__dict__['_Process__schedule'] = sch
0341     schedule = property(schedule_,setSchedule_,doc='the schedule or None if not set')
0342     def services_(self):
0343         """returns a dict of the services that have been added to the Process"""
0344         return DictTypes.FixedKeysDict(self.__services)
0345     services = property(services_,doc="dictionary containing the services for the process")
0346     def processAccelerators_(self):
0347         """returns a dict of the ProcessAccelerators that have been added to the Process"""
0348         return DictTypes.FixedKeysDict(self.__accelerators)
0349     processAccelerators = property(processAccelerators_,doc="dictionary containing the ProcessAccelerators for the process")
0350     def es_producers_(self):
0351         """returns a dict of the esproducers that have been added to the Process"""
0352         return DictTypes.FixedKeysDict(self.__esproducers)
0353     es_producers = property(es_producers_,doc="dictionary containing the es_producers for the process")
0354     def es_sources_(self):
0355         """returns a the es_sources that have been added to the Process"""
0356         return DictTypes.FixedKeysDict(self.__essources)
0357     es_sources = property(es_sources_,doc="dictionary containing the es_sources for the process")
0358     def es_prefers_(self):
0359         """returns a dict of the es_prefers that have been added to the Process"""
0360         return DictTypes.FixedKeysDict(self.__esprefers)
0361     es_prefers = property(es_prefers_,doc="dictionary containing the es_prefers for the process")
0362     def aliases_(self):
0363         """returns a dict of the aliases that have been added to the Process"""
0364         return DictTypes.FixedKeysDict(self.__aliases)
0365     aliases = property(aliases_,doc="dictionary containing the aliases for the process")
0366     def psets_(self):
0367         """returns a dict of the PSets that have been added to the Process"""
0368         return DictTypes.FixedKeysDict(self.__psets)
0369     psets = property(psets_,doc="dictionary containing the PSets for the process")
0370     def vpsets_(self):
0371         """returns a dict of the VPSets that have been added to the Process"""
0372         return DictTypes.FixedKeysDict(self.__vpsets)
0373     vpsets = property(vpsets_,doc="dictionary containing the PSets for the process")
0374 
0375     def isUsingModifier(self,mod) -> bool:
0376         """returns True if the Modifier is in used by this Process"""
0377         if mod._isChosen():
0378             for m in self.__modifiers:
0379                 if m._isOrContains(mod):
0380                     return True
0381         return False
0382 
0383     def __setObjectLabel(self, object, newLabel:str) :
0384         if not object.hasLabel_() :
0385             object.setLabel(newLabel)
0386             return
0387         if newLabel == object.label_() :
0388             return
0389         if newLabel is None :
0390             object.setLabel(None)
0391             return
0392         if (hasattr(self, object.label_()) and id(getattr(self, object.label_())) == id(object)) :
0393             msg100 = "Attempting to change the label of an attribute of the Process\n"
0394             msg101 = "Old label = "+object.label_()+"  New label = "+newLabel+"\n"
0395             msg102 = "Type = "+str(type(object))+"\n"
0396             msg103 = "Some possible solutions:\n"
0397             msg104 = "  1. Clone modules instead of using simple assignment. Cloning is\n"
0398             msg105 = "  also preferred for other types when possible.\n"
0399             msg106 = "  2. Declare new names starting with an underscore if they are\n"
0400             msg107 = "  for temporaries you do not want propagated into the Process. The\n"
0401             msg108 = "  underscore tells \"from x import *\" and process.load not to import\n"
0402             msg109 = "  the name.\n"
0403             msg110 = "  3. Reorganize so the assigment is not necessary. Giving a second\n"
0404             msg111 = "  name to the same object usually causes confusion and problems.\n"
0405             msg112 = "  4. Compose Sequences: newName = cms.Sequence(oldName)\n"
0406             raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
0407         object.setLabel(None)
0408         object.setLabel(newLabel)
0409 
0410     def __setattr__(self,name:str,value):
0411         # check if the name is well-formed (only _ and alphanumerics are allowed)
0412         if not name.replace('_','').isalnum():
0413             raise ValueError('The label '+name+' contains forbiden characters')
0414 
0415         if name == 'options':
0416             value = self.__updateOptions(value)
0417         if name == 'maxEvents':
0418             value = self.__updateMaxEvents(value)
0419 
0420         # private variable exempt from all this
0421         if name.startswith('_Process__'):
0422             self.__dict__[name]=value
0423             return
0424         if not isinstance(value,_ConfigureComponent):
0425             raise TypeError("can only assign labels to an object that inherits from '_ConfigureComponent'\n"
0426                             +"an instance of "+str(type(value))+" will not work - requested label is "+name)
0427         if not isinstance(value,_Labelable) and not isinstance(value,Source) and not isinstance(value,Looper) and not isinstance(value,Schedule):
0428             if name == value.type_():
0429                 if hasattr(self,name) and (getattr(self,name)!=value):
0430                     self._replaceInTasks(name, value)
0431                     self._replaceInConditionalTasks(name, value)
0432                 # Only Services get handled here
0433                 self.add_(value)
0434                 return
0435             else:
0436                 raise TypeError("an instance of "+str(type(value))+" can not be assigned the label '"+name+"'.\n"+
0437                                 "Please either use the label '"+value.type_()+" or use the 'add_' method instead.")
0438         #clone the item
0439         if self.__isStrict:
0440             newValue =value.copy()
0441             try:
0442                 newValue._filename = value._filename
0443             except:
0444                 pass
0445             value.setIsFrozen()
0446         else:
0447             newValue =value
0448         if not self._okToPlace(name, value, self.__dict__):
0449             newFile='top level config'
0450             if hasattr(value,'_filename'):
0451                 newFile = value._filename
0452             oldFile='top level config'
0453             oldValue = getattr(self,name)
0454             if hasattr(oldValue,'_filename'):
0455                 oldFile = oldValue._filename
0456             msg = "Trying to override definition of process."+name
0457             msg += "\n new object defined in: "+newFile
0458             msg += "\n existing object defined in: "+oldFile
0459             raise ValueError(msg)
0460         # remove the old object of the name (if there is one)
0461         if hasattr(self,name) and not (getattr(self,name)==newValue):
0462             # Complain if items in sequences or tasks from load() statements have
0463             # degenerate names, but if the user overwrites a name in the
0464             # main config, replace it everywhere
0465             if newValue._isTaskComponent():
0466                 if not self.__InExtendCall:
0467                     self._replaceInTasks(name, newValue)
0468                     self._replaceInConditionalTasks(name, newValue)
0469                     self._replaceInSchedule(name, newValue)
0470                 else:
0471                     if not isinstance(newValue, Task):
0472                         #should check to see if used in task before complaining
0473                         newFile='top level config'
0474                         if hasattr(value,'_filename'):
0475                             newFile = value._filename
0476                         oldFile='top level config'
0477                         oldValue = getattr(self,name)
0478                         if hasattr(oldValue,'_filename'):
0479                             oldFile = oldValue._filename
0480                         msg1 = "Trying to override definition of "+name+" while it is used by the task "
0481                         msg2 = "\n new object defined in: "+newFile
0482                         msg2 += "\n existing object defined in: "+oldFile
0483                         s = self.__findFirstUsingModule(self.tasks,oldValue)
0484                         if s is not None:
0485                             raise ValueError(msg1+s.label_()+msg2)
0486 
0487             if isinstance(newValue, _Sequenceable) or newValue._isTaskComponent() or isinstance(newValue, ConditionalTask):
0488                 if not self.__InExtendCall:
0489                     if isinstance(newValue, ConditionalTask):
0490                         self._replaceInConditionalTasks(name, newValue)
0491                     self._replaceInSequences(name, newValue)
0492                 else:
0493                     #should check to see if used in sequence before complaining
0494                     newFile='top level config'
0495                     if hasattr(value,'_filename'):
0496                         newFile = value._filename
0497                     oldFile='top level config'
0498                     oldValue = getattr(self,name)
0499                     if hasattr(oldValue,'_filename'):
0500                         oldFile = oldValue._filename
0501                     msg1 = "Trying to override definition of "+name+" while it is used by the "
0502                     msg2 = "\n new object defined in: "+newFile
0503                     msg2 += "\n existing object defined in: "+oldFile
0504                     s = self.__findFirstUsingModule(self.sequences,oldValue)
0505                     if s is not None:
0506                         raise ValueError(msg1+"sequence "+s.label_()+msg2)
0507                     s = self.__findFirstUsingModule(self.paths,oldValue)
0508                     if s is not None:
0509                         raise ValueError(msg1+"path "+s.label_()+msg2)
0510                     s = self.__findFirstUsingModule(self.endpaths,oldValue)
0511                     if s is not None:
0512                         raise ValueError(msg1+"endpath "+s.label_()+msg2)
0513 
0514             # In case of EDAlias, raise Exception always to avoid surprises
0515             if isinstance(newValue, EDAlias):
0516                 oldValue = getattr(self, name)
0517                 #should check to see if used in task/sequence before complaining
0518                 newFile='top level config'
0519                 if hasattr(value,'_filename'):
0520                     newFile = value._filename
0521                 oldFile='top level config'
0522                 if hasattr(oldValue,'_filename'):
0523                     oldFile = oldValue._filename
0524                 msg1 = "Trying to override definition of "+name+" with an EDAlias while it is used by the "
0525                 msg2 = "\n new object defined in: "+newFile
0526                 msg2 += "\n existing object defined in: "+oldFile
0527                 s = self.__findFirstUsingModule(self.tasks,oldValue)
0528                 if s is not None:
0529                     raise ValueError(msg1+"task "+s.label_()+msg2)
0530                 s = self.__findFirstUsingModule(self.sequences,oldValue)
0531                 if s is not None:
0532                     raise ValueError(msg1+"sequence "+s.label_()+msg2)
0533                 s = self.__findFirstUsingModule(self.paths,oldValue)
0534                 if s is not None:
0535                     raise ValueError(msg1+"path "+s.label_()+msg2)
0536                 s = self.__findFirstUsingModule(self.endpaths,oldValue)
0537                 if s is not None:
0538                     raise ValueError(msg1+"endpath "+s.label_()+msg2)
0539 
0540             if not self.__InExtendCall and (Schedule._itemIsValid(newValue) or isinstance(newValue, Task)):
0541                 self._replaceInScheduleDirectly(name, newValue)
0542 
0543             self._delattrFromSetattr(name)
0544         self.__injectValidValue(name, value, newValue)
0545     def __injectValidValue(self, name:str, value, newValue = None):
0546         if newValue is None:
0547             newValue = value
0548         self.__dict__[name]=newValue
0549         if isinstance(newValue,_Labelable):
0550             self.__setObjectLabel(newValue, name)
0551             self._cloneToObjectDict[id(value)] = newValue
0552             self._cloneToObjectDict[id(newValue)] = newValue
0553         #now put in proper bucket
0554         newValue._place(name,self)
0555     def __findFirstUsingModule(self, seqsOrTasks, mod):
0556         """Given a container of sequences or tasks, find the first sequence or task
0557         containing mod and return it. If none is found, return None"""
0558         from FWCore.ParameterSet.SequenceTypes import ModuleNodeVisitor
0559         l = list()
0560         for seqOrTask in seqsOrTasks.values():
0561             l[:] = []
0562             v = ModuleNodeVisitor(l)
0563             seqOrTask.visit(v)
0564             if mod in l:
0565                 return seqOrTask
0566         return None
0567 
0568     def _delHelper(self,name:str):
0569         if not hasattr(self,name):
0570             raise KeyError('process does not know about '+name)
0571         elif name.startswith('_Process__'):
0572             raise ValueError('this attribute cannot be deleted')
0573 
0574         # we have to remove it from all dictionaries/registries
0575         dicts = [item for item in self.__dict__.values() if (isinstance(item, dict) or isinstance(item, DictTypes.SortedKeysDict))]
0576         for reg in dicts:
0577             if name in reg: del reg[name]
0578         # if it was a labelable object, the label needs to be removed
0579         obj = getattr(self,name)
0580         if isinstance(obj,_Labelable):
0581             obj.setLabel(None)
0582         if isinstance(obj,Service):
0583             obj._inProcess = False
0584 
0585     def __delattr__(self,name:str):
0586         self._delHelper(name)
0587         obj = getattr(self,name)
0588         if not obj is None:
0589             if not isinstance(obj, Sequence) and not isinstance(obj, Task) and not isinstance(obj,ConditionalTask):
0590                 # For modules, ES modules and services we can also remove
0591                 # the deleted object from Sequences, Paths, EndPaths, and
0592                 # Tasks. Note that for Sequences and Tasks that cannot be done
0593                 # reliably as the places where the Sequence or Task was used
0594                 # might have been expanded so we do not even try. We considered
0595                 # raising an exception if a Sequences or Task was explicitly
0596                 # deleted, but did not because when done carefully deletion
0597                 # is sometimes OK (for example in the prune function where it
0598                 # has been checked that the deleted Sequence is not used).
0599                 if obj._isTaskComponent():
0600                     self._replaceInTasks(name, None)
0601                     self._replaceInConditionalTasks(name, None)
0602                     self._replaceInSchedule(name, None)
0603                 if isinstance(obj, _Sequenceable) or obj._isTaskComponent():
0604                     self._replaceInSequences(name, None)
0605                 if Schedule._itemIsValid(obj) or isinstance(obj, Task):
0606                     self._replaceInScheduleDirectly(name, None)
0607         # now remove it from the process itself
0608         try:
0609             del self.__dict__[name]
0610         except:
0611             pass
0612 
0613     def _delattrFromSetattr(self,name:str):
0614         """Similar to __delattr__ but we need different behavior when called from __setattr__"""
0615         self._delHelper(name)
0616         # now remove it from the process itself
0617         try:
0618             del self.__dict__[name]
0619         except:
0620             pass
0621 
0622     def add_(self,value):
0623         """Allows addition of components that do not have to have a label, e.g. Services"""
0624         if not isinstance(value,_ConfigureComponent):
0625             raise TypeError
0626         if not isinstance(value,_Unlabelable):
0627             raise TypeError
0628         #clone the item
0629         if self.__isStrict:
0630             newValue =value.copy()
0631             value.setIsFrozen()
0632         else:
0633             newValue =value
0634         newValue._place('',self)
0635 
0636     def _okToPlace(self, name:str, mod, d) -> bool:
0637         if not self.__InExtendCall:
0638             # if going
0639             return True
0640         elif not self.__isStrict:
0641             return True
0642         elif name in d:
0643             # if there's an old copy, and the new one
0644             # hasn't been modified, we're done.  Still
0645             # not quite safe if something has been defined twice.
0646             #  Need to add checks
0647             if mod._isModified:
0648                 if d[name]._isModified:
0649                     return False
0650                 else:
0651                     return True
0652             else:
0653                 return True
0654         else:
0655             return True
0656 
0657     def _place(self, name:str, mod, d):
0658         if self._okToPlace(name, mod, d):
0659             if self.__isStrict and isinstance(mod, _ModuleSequenceType):
0660                 d[name] = mod._postProcessFixup(self._cloneToObjectDict)
0661             else:
0662                 d[name] = mod
0663             if isinstance(mod,_Labelable):
0664                 self.__setObjectLabel(mod, name)
0665     def _placeOutputModule(self,name:str,mod):
0666         self._place(name, mod, self.__outputmodules)
0667     def _placeProducer(self,name:str,mod):
0668         self._place(name, mod, self.__producers)
0669     def _placeSwitchProducer(self,name:str,mod):
0670         self._place(name, mod, self.__switchproducers)
0671     def _placeFilter(self,name:str,mod):
0672         self._place(name, mod, self.__filters)
0673     def _placeAnalyzer(self,name:str,mod):
0674         self._place(name, mod, self.__analyzers)
0675     def _placePath(self,name:str,mod):
0676         self._validateSequence(mod, name)
0677         try:
0678             self._place(name, mod, self.__paths)
0679         except ModuleCloneError as msg:
0680             context = format_outerframe(4)
0681             raise Exception("%sThe module %s in path %s is unknown to the process %s." %(context, msg, name, self._Process__name))
0682     def _placeEndPath(self,name:str,mod):
0683         self._validateSequence(mod, name)
0684         try:
0685             self._place(name, mod, self.__endpaths)
0686         except ModuleCloneError as msg:
0687             context = format_outerframe(4)
0688             raise Exception("%sThe module %s in endpath %s is unknown to the process %s." %(context, msg, name, self._Process__name))
0689     def _placeSequence(self,name:str,mod):
0690         self._validateSequence(mod, name)
0691         self._place(name, mod, self.__sequences)
0692     def _placeESProducer(self,name:str,mod):
0693         self._place(name, mod, self.__esproducers)
0694     def _placeESPrefer(self,name:str,mod):
0695         self._place(name, mod, self.__esprefers)
0696     def _placeESSource(self,name:str,mod):
0697         self._place(name, mod, self.__essources)
0698     def _placeTask(self,name:str,task):
0699         self._validateTask(task, name)
0700         self._place(name, task, self.__tasks)
0701     def _placeConditionalTask(self,name:str,task):
0702         self._validateConditionalTask(task, name)
0703         self._place(name, task, self.__conditionaltasks)
0704     def _placeAlias(self,name:str,mod):
0705         self._place(name, mod, self.__aliases)
0706     def _placePSet(self,name:str,mod):
0707         self._place(name, mod, self.__psets)
0708     def _placeVPSet(self,name:str,mod):
0709         self._place(name, mod, self.__vpsets)
0710     def _placeSource(self,name:str,mod):
0711         """Allow the source to be referenced by 'source' or by type name"""
0712         if name != 'source':
0713             raise ValueError("The label '"+name+"' can not be used for a Source.  Only 'source' is allowed.")
0714         if self.__dict__['_Process__source'] is not None :
0715             del self.__dict__[self.__dict__['_Process__source'].type_()]
0716         self.__dict__['_Process__source'] = mod
0717         self.__dict__[mod.type_()] = mod
0718     def _placeLooper(self,name:str,mod):
0719         if name != 'looper':
0720             raise ValueError("The label '"+name+"' can not be used for a Looper.  Only 'looper' is allowed.")
0721         self.__dict__['_Process__looper'] = mod
0722         self.__dict__[mod.type_()] = mod
0723     def _placeService(self,typeName:str,mod):
0724         self._place(typeName, mod, self.__services)
0725         if typeName in self.__dict__:
0726             self.__dict__[typeName]._inProcess = False
0727         self.__dict__[typeName]=mod
0728     def _placeAccelerator(self,typeName:str,mod):
0729         self._place(typeName, mod, self.__accelerators)
0730         self.__dict__[typeName]=mod
0731     def load(self, moduleName:str):
0732         moduleName = moduleName.replace("/",".")
0733         module = __import__(moduleName)
0734         self.extend(sys.modules[moduleName])
0735     def extend(self,other,items=()):
0736         """Look in other and find types that we can use"""
0737         # enable explicit check to avoid overwriting of existing objects
0738         self.__dict__['_Process__InExtendCall'] = True
0739 
0740         seqs = dict()
0741         tasksToAttach = dict()
0742         mods = []
0743         for name in dir(other):
0744             #'from XX import *' ignores these, and so should we.
0745             if name.startswith('_'):
0746                 continue
0747             item = getattr(other,name)
0748             if name == "source" or name == "looper":
0749                 # In these cases 'item' could be None if the specific object was not defined
0750                 if item is not None:
0751                     self.__setattr__(name,item)
0752             elif isinstance(item,_ModuleSequenceType):
0753                 seqs[name]=item
0754             elif isinstance(item,Task) or isinstance(item, ConditionalTask):
0755                 tasksToAttach[name] = item
0756             elif isinstance(item,_Labelable):
0757                 self.__setattr__(name,item)
0758                 if not item.hasLabel_() :
0759                     item.setLabel(name)
0760             elif isinstance(item,Schedule):
0761                 self.__setattr__(name,item)
0762             elif isinstance(item,_Unlabelable):
0763                 self.add_(item)
0764             elif isinstance(item,ProcessModifier):
0765                 mods.append(item)
0766             elif isinstance(item,ProcessFragment):
0767                 self.extend(item)
0768 
0769         #now create a sequence that uses the newly made items
0770         for name,seq in seqs.items():
0771             if id(seq) not in self._cloneToObjectDict:
0772                 self.__setattr__(name,seq)
0773             else:
0774                 newSeq = self._cloneToObjectDict[id(seq)]
0775                 self.__dict__[name]=newSeq
0776                 self.__setObjectLabel(newSeq, name)
0777                 #now put in proper bucket
0778                 newSeq._place(name,self)
0779 
0780         for name, task in tasksToAttach.items():
0781             self.__setattr__(name, task)
0782 
0783         #apply modifiers now that all names have been added
0784         for item in mods:
0785             item.apply(self)
0786 
0787         self.__dict__['_Process__InExtendCall'] = False
0788 
0789     def _specialOverrideReleaseVersionOnlyForTesting(self, version):
0790         "This function is intended only for specific framework tests. Do not use for anything else."
0791         self.__specialOverrideReleaseVersionOnlyForTesting = version
0792 
0793     def _dumpConfigNamedList(self,items,typeName:str,options:PrintOptions) -> str:
0794         returnValue = ''
0795         for name,item in items:
0796             returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
0797         return returnValue
0798 
0799     def _dumpConfigUnnamedList(self,items,typeName:str,options:PrintOptions) -> str:
0800         returnValue = ''
0801         for name,item in items:
0802             returnValue +=options.indentation()+typeName+' = '+item.dumpConfig(options)
0803         return returnValue
0804 
0805     def _dumpConfigOptionallyNamedList(self,items,typeName:str,options:PrintOptions) -> str:
0806         returnValue = ''
0807         for name,item in items:
0808             if name == item.type_():
0809                 name = ''
0810             returnValue +=options.indentation()+typeName+' '+name+' = '+item.dumpConfig(options)
0811         return returnValue
0812 
0813     def dumpConfig(self, options:PrintOptions=PrintOptions()) -> str:
0814         """return a string containing the equivalent process defined using the old configuration language"""
0815         config = "process "+self.__name+" = {\n"
0816         options.indent()
0817         if self.source_():
0818             config += options.indentation()+"source = "+self.source_().dumpConfig(options)
0819         if self.looper_():
0820             config += options.indentation()+"looper = "+self.looper_().dumpConfig(options)
0821         config+=self._dumpConfigNamedList(self.producers_().items(),
0822                                   'module',
0823                                   options)
0824         config+=self._dumpConfigNamedList(self.switchProducers_().items(),
0825                                   'module',
0826                                   options)
0827         config+=self._dumpConfigNamedList(self.filters_().items(),
0828                                   'module',
0829                                   options)
0830         config+=self._dumpConfigNamedList(self.analyzers_().items(),
0831                                   'module',
0832                                   options)
0833         config+=self._dumpConfigNamedList(self.outputModules_().items(),
0834                                   'module',
0835                                   options)
0836         config+=self._dumpConfigNamedList(self.sequences_().items(),
0837                                   'sequence',
0838                                   options)
0839         config+=self._dumpConfigNamedList(self.paths_().items(),
0840                                   'path',
0841                                   options)
0842         config+=self._dumpConfigNamedList(self.endpaths_().items(),
0843                                   'endpath',
0844                                   options)
0845         config+=self._dumpConfigUnnamedList(self.services_().items(),
0846                                   'service',
0847                                   options)
0848         config+=self._dumpConfigNamedList(self.aliases_().items(),
0849                                   'alias',
0850                                   options)
0851         config+=self._dumpConfigOptionallyNamedList(
0852             self.es_producers_().items(),
0853             'es_module',
0854             options)
0855         config+=self._dumpConfigOptionallyNamedList(
0856             self.es_sources_().items(),
0857             'es_source',
0858             options)
0859         config += self._dumpConfigESPrefers(options)
0860         for name,item in self.psets.items():
0861             config +=options.indentation()+item.configTypeName()+' '+name+' = '+item.configValue(options)
0862         for name,item in self.vpsets.items():
0863             config +=options.indentation()+'VPSet '+name+' = '+item.configValue(options)
0864         if self.schedule:
0865             pathNames = [p.label_() for p in self.schedule]
0866             config +=options.indentation()+'schedule = {'+','.join(pathNames)+'}\n'
0867 
0868 #        config+=self._dumpConfigNamedList(self.vpsets.items(),
0869 #                                  'VPSet',
0870 #                                  options)
0871         config += "}\n"
0872         options.unindent()
0873         return config
0874 
0875     def _dumpConfigESPrefers(self, options:PrintOptions) -> str:
0876         result = ''
0877         for item in self.es_prefers_().values():
0878             result +=options.indentation()+'es_prefer '+item.targetLabel_()+' = '+item.dumpConfig(options)
0879         return result
0880 
0881     def _dumpPythonList(self, d, options:PrintOptions) -> str:
0882         returnValue = ''
0883         if isinstance(d, DictTypes.SortedKeysDict):
0884             for name,item in d.items():
0885                 returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
0886         else:
0887             for name,item in sorted(d.items()):
0888                 returnValue +='process.'+name+' = '+item.dumpPython(options)+'\n\n'
0889         return returnValue
0890 
0891     def _splitPythonList(self, subfolder, d, options:PrintOptions) -> str:
0892         parts = DictTypes.SortedKeysDict()
0893         for name, item in d.items() if isinstance(d, DictTypes.SortedKeysDict) else sorted(d.items()):
0894             code = ''
0895             dependencies = item.directDependencies()
0896             for module_subfolder, module in dependencies:
0897                 module = module + '_cfi'
0898                 if options.useSubdirectories and module_subfolder:
0899                     module = module_subfolder + '.' + module
0900                 if options.targetDirectory is not None:
0901                     if options.useSubdirectories and subfolder:
0902                       module = '..' + module
0903                     else:
0904                       module = '.' + module
0905                 code += 'from ' + module + ' import *\n'
0906             if dependencies:
0907                 code += '\n'
0908             code += name + ' = ' + item.dumpPython(options)
0909             parts[name] = subfolder, code
0910         return parts
0911 
0912     def _validateSequence(self, sequence, label):
0913         # See if every module has been inserted into the process
0914         try:
0915             l = set()
0916             visitor = NodeNameVisitor(l)
0917             sequence.visit(visitor)
0918         except Exception as e:
0919             raise RuntimeError("An entry in sequence {} has no label\n  Seen entries: {}\n  Error: {}".format(label, l, e))
0920 
0921     def _validateTask(self, task, label:str):
0922         # See if every module and service has been inserted into the process
0923         try:
0924             l = set()
0925             visitor = NodeNameVisitor(l)
0926             task.visit(visitor)
0927         except:
0928             raise RuntimeError("An entry in task " + label + ' has not been attached to the process')
0929     def _validateConditionalTask(self, task, label:str):
0930         # See if every module and service has been inserted into the process
0931         try:
0932             l = set()
0933             visitor = NodeNameVisitor(l)
0934             task.visit(visitor)
0935         except:
0936             raise RuntimeError("An entry in task " + label + ' has not been attached to the process')
0937 
0938     def _itemsInDependencyOrder(self, processDictionaryOfItems):
0939         # The items can be Sequences or Tasks and the input
0940         # argument should either be the dictionary of sequences
0941         # or the dictionary of tasks from the process.
0942 
0943         returnValue=DictTypes.SortedKeysDict()
0944 
0945         # For each item, see what other items it depends upon
0946         # For our purpose here, an item depends on the items it contains.
0947         dependencies = {}
0948         for label,item in processDictionaryOfItems.items():
0949             containedItems = []
0950             if isinstance(item, Task):
0951                 v = TaskVisitor(containedItems)
0952             elif isinstance(item, ConditionalTask):
0953                 v = ConditionalTaskVisitor(containedItems)
0954             else:
0955                 v = SequenceVisitor(containedItems)
0956             try:
0957                 item.visit(v)
0958             except RuntimeError:
0959                 if isinstance(item, Task):
0960                     raise RuntimeError("Failed in a Task visitor. Probably " \
0961                                        "a circular dependency discovered in Task with label " + label)
0962                 elif isinstance(item, ConditionalTask):
0963                     raise RuntimeError("Failed in a ConditionalTask visitor. Probably " \
0964                                        "a circular dependency discovered in ConditionalTask with label " + label)
0965                 else:
0966                     raise RuntimeError("Failed in a Sequence visitor. Probably a " \
0967                                        "circular dependency discovered in Sequence with label " + label)
0968             for containedItem in containedItems:
0969                 # Check for items that both have labels and are not in the process.
0970                 # This should not normally occur unless someone explicitly assigns a
0971                 # label without putting the item in the process (which should not ever
0972                 # be done). We check here because this problem could cause the code
0973                 # in the 'while' loop below to go into an infinite loop.
0974                 if containedItem.hasLabel_():
0975                     testItem = processDictionaryOfItems.get(containedItem.label_())
0976                     if testItem is None or containedItem != testItem:
0977                         if isinstance(item, Task):
0978                             raise RuntimeError("Task has a label, but using its label to get an attribute" \
0979                                                " from the process yields a different object or None\n"+
0980                                                "label = " + containedItem.label_())
0981                         if isinstance(item, ConditionalTask):
0982                             raise RuntimeError("ConditionalTask has a label, but using its label to get an attribute" \
0983                                                " from the process yields a different object or None\n"+
0984                                                "label = " + containedItem.label_())
0985                         else:
0986                             raise RuntimeError("Sequence has a label, but using its label to get an attribute" \
0987                                                " from the process yields a different object or None\n"+
0988                                                "label = " + containedItem.label_())
0989             dependencies[label]=[dep.label_() for dep in containedItems if dep.hasLabel_()]
0990 
0991         # keep looping until we get rid of all dependencies
0992         while dependencies:
0993             oldDeps = dict(dependencies)
0994             for label,deps in oldDeps.items():
0995                 if len(deps)==0:
0996                     returnValue[label]=processDictionaryOfItems[label]
0997                     #remove this as a dependency for all other tasks
0998                     del dependencies[label]
0999                     for lb2,deps2 in dependencies.items():
1000                         while deps2.count(label):
1001                             deps2.remove(label)
1002         return returnValue
1003 
1004     def _dumpPython(self, d, options:PrintOptions) -> str:
1005         result = ''
1006         for name, value in sorted(d.items()):
1007             result += value.dumpPythonAs(name,options)+'\n'
1008         return result
1009 
1010     def _splitPython(self, subfolder, d, options:PrintOptions) -> dict:
1011         result = {}
1012         for name, value in sorted(d.items()):
1013             result[name] = subfolder, value.dumpPythonAs(name, options) + '\n'
1014         return result
1015 
1016     def dumpPython(self, options=PrintOptions()) -> str:
1017         """return a string containing the equivalent process defined using python"""
1018         specialImportRegistry._reset()
1019         header = "import FWCore.ParameterSet.Config as cms"
1020         result = "process = cms.Process(\""+self.__name+"\")\n\n"
1021         if not self.source_() is None:
1022             result += "process.source = "+self.source_().dumpPython(options)
1023         if not self.looper_() is None:
1024             result += "process.looper = "+self.looper_().dumpPython()
1025         result+=self._dumpPythonList(self.psets, options)
1026         result+=self._dumpPythonList(self.vpsets, options)
1027         result+=self._dumpPythonList(self.producers_(), options)
1028         result+=self._dumpPythonList(self.switchProducers_(), options)
1029         result+=self._dumpPythonList(self.filters_() , options)
1030         result+=self._dumpPythonList(self.analyzers_(), options)
1031         result+=self._dumpPythonList(self.outputModules_(), options)
1032         result+=self._dumpPythonList(self.services_(), options)
1033         result+=self._dumpPythonList(self.processAccelerators_(), options)
1034         result+=self._dumpPythonList(self.es_producers_(), options)
1035         result+=self._dumpPythonList(self.es_sources_(), options)
1036         result+=self._dumpPython(self.es_prefers_(), options)
1037         result+=self._dumpPythonList(self._itemsInDependencyOrder(self.tasks), options)
1038         result+=self._dumpPythonList(self._itemsInDependencyOrder(self.conditionaltasks), options)
1039         result+=self._dumpPythonList(self._itemsInDependencyOrder(self.sequences), options)
1040         result+=self._dumpPythonList(self.paths_(), options)
1041         result+=self._dumpPythonList(self.endpaths_(), options)
1042         result+=self._dumpPythonList(self.aliases_(), options)
1043         if not self.schedule_() == None:
1044             result += 'process.schedule = ' + self.schedule.dumpPython(options)
1045         imports = specialImportRegistry.getSpecialImports()
1046         if len(imports) > 0:
1047             header += "\n" + "\n".join(imports)
1048         header += "\n\n"
1049         return header+result
1050 
1051     def splitPython(self, options:PrintOptions = PrintOptions()) -> dict:
1052         """return a map of file names to python configuration fragments"""
1053         specialImportRegistry._reset()
1054         # extract individual fragments
1055         options.isCfg = False
1056         header = "import FWCore.ParameterSet.Config as cms"
1057         result = ''
1058         parts = {}
1059         files = {}
1060 
1061         result = 'process = cms.Process("' + self.__name + '")\n\n'
1062 
1063         if not self.source_() is None:
1064             parts['source'] = (None, 'source = ' + self.source_().dumpPython(options))
1065 
1066         if not self.looper_() is None:
1067             parts['looper'] = (None, 'looper = ' + self.looper_().dumpPython())
1068 
1069         parts.update(self._splitPythonList('psets', self.psets, options))
1070         parts.update(self._splitPythonList('psets', self.vpsets, options))
1071         parts.update(self._splitPythonList('modules', self.producers_(), options))
1072         parts.update(self._splitPythonList('modules', self.switchProducers_(), options))
1073         parts.update(self._splitPythonList('modules', self.filters_() , options))
1074         parts.update(self._splitPythonList('modules', self.analyzers_(), options))
1075         parts.update(self._splitPythonList('modules', self.outputModules_(), options))
1076         parts.update(self._splitPythonList('services', self.services_(), options))
1077         parts.update(self._splitPythonList('eventsetup', self.es_producers_(), options))
1078         parts.update(self._splitPythonList('eventsetup', self.es_sources_(), options))
1079         parts.update(self._splitPython('eventsetup', self.es_prefers_(), options))
1080         parts.update(self._splitPythonList('tasks', self._itemsInDependencyOrder(self.tasks), options))
1081         parts.update(self._splitPythonList('sequences', self._itemsInDependencyOrder(self.sequences), options))
1082         parts.update(self._splitPythonList('paths', self.paths_(), options))
1083         parts.update(self._splitPythonList('paths', self.endpaths_(), options))
1084         parts.update(self._splitPythonList('modules', self.aliases_(), options))
1085 
1086         if options.targetDirectory is not None:
1087             files[options.targetDirectory + '/__init__.py'] = ''
1088 
1089         if options.useSubdirectories:
1090           for sub in 'psets', 'modules', 'services', 'eventsetup', 'tasks', 'sequences', 'paths':
1091             if options.targetDirectory is not None:
1092                 sub = options.targetDirectory + '/' + sub
1093             files[sub + '/__init__.py'] = ''
1094 
1095         # case insensitive sort by subfolder and module name
1096         parts = sorted(parts.items(), key = lambda nsc: (nsc[1][0].lower() if nsc[1][0] else '', nsc[0].lower()))
1097 
1098         for (name, (subfolder, code)) in parts:
1099             filename = name + '_cfi'
1100             if options.useSubdirectories and subfolder:
1101                 filename = subfolder + '/' + filename
1102             if options.targetDirectory is not None:
1103                 filename = options.targetDirectory + '/' + filename
1104             result += 'process.load("%s")\n' % filename
1105             files[filename + '.py'] = header + '\n\n' + code
1106 
1107         if self.schedule_() is not None:
1108             options.isCfg = True
1109             result += '\nprocess.schedule = ' + self.schedule.dumpPython(options)
1110 
1111         imports = specialImportRegistry.getSpecialImports()
1112         if len(imports) > 0:
1113             header += '\n' + '\n'.join(imports)
1114         files['-'] = header + '\n\n' + result
1115         return files
1116 
1117     def _replaceInSequences(self, label:str, new):
1118         old = getattr(self,label)
1119         #TODO - replace by iterator concatenation
1120         #to ovoid dependency problems between sequences, first modify
1121         # process known sequences to do a non-recursive change. Then do
1122         # a recursive change to get cases where a sub-sequence unknown to
1123         # the process has the item to be replaced
1124         for sequenceable in self.sequences.values():
1125             sequenceable._replaceIfHeldDirectly(old,new)
1126         for sequenceable in self.sequences.values():
1127             sequenceable.replace(old,new)
1128         for sequenceable in self.paths.values():
1129             sequenceable.replace(old,new)
1130         for sequenceable in self.endpaths.values():
1131             sequenceable.replace(old,new)
1132     def _replaceInTasks(self, label:str, new):
1133         old = getattr(self,label)
1134         for task in self.tasks.values():
1135             task.replace(old, new)
1136     def _replaceInConditionalTasks(self, label:str, new):
1137         old = getattr(self,label)
1138         for task in self.conditionaltasks.values():
1139             task.replace(old, new)
1140     def _replaceInSchedule(self, label:str, new):
1141         if self.schedule_() == None:
1142             return
1143         old = getattr(self,label)
1144         for task in self.schedule_()._tasks:
1145             task.replace(old, new)
1146     def _replaceInScheduleDirectly(self, label:str, new):
1147         if self.schedule_() == None:
1148             return
1149         old = getattr(self,label)
1150         self.schedule_()._replaceIfHeldDirectly(old, new)
1151     def globalReplace(self,label:str,new):
1152         """ Replace the item with label 'label' by object 'new' in the process and all sequences/paths/tasks"""
1153         if not hasattr(self,label):
1154             raise LookupError("process has no item of label "+label)
1155         setattr(self,label,new)
1156     def _insertInto(self, parameterSet, itemDict):
1157         for name,value in itemDict.items():
1158             value.insertInto(parameterSet, name)
1159     def _insertOneInto(self, parameterSet, label:str, item, tracked:bool):
1160         vitems = []
1161         if not item == None:
1162             newlabel = item.nameInProcessDesc_(label)
1163             vitems = [newlabel]
1164             item.insertInto(parameterSet, newlabel)
1165         parameterSet.addVString(tracked, label, vitems)
1166     def _insertManyInto(self, parameterSet, label:str, itemDict, tracked:bool):
1167         l = []
1168         for name,value in itemDict.items():
1169             value.appendToProcessDescList_(l, name)
1170             value.insertInto(parameterSet, name)
1171         # alphabetical order is easier to compare with old language
1172         l.sort()
1173         parameterSet.addVString(tracked, label, l)
1174     def _insertSwitchProducersInto(self, parameterSet, labelModules, labelAliases, itemDict, tracked:bool):
1175         modules = parameterSet.getVString(tracked, labelModules)
1176         aliases = parameterSet.getVString(tracked, labelAliases)
1177         accelerators = parameterSet.getVString(False, "@selected_accelerators")
1178         for name,value in itemDict.items():
1179             value.appendToProcessDescLists_(modules, aliases, name)
1180             value.insertInto(parameterSet, name, accelerators)
1181         modules.sort()
1182         aliases.sort()
1183         parameterSet.addVString(tracked, labelModules, modules)
1184         parameterSet.addVString(tracked, labelAliases, aliases)
1185     def _insertPaths(self, processPSet, nodeVisitor):
1186         scheduledPaths = []
1187         triggerPaths = []
1188         endpaths = []
1189         if self.schedule_() == None:
1190             # make one from triggerpaths & endpaths
1191             for name in self.paths_():
1192                 scheduledPaths.append(name)
1193                 triggerPaths.append(name)
1194             for name in self.endpaths_():
1195                 scheduledPaths.append(name)
1196                 endpaths.append(name)
1197         else:
1198             for path in self.schedule_():
1199                 pathname = path.label_()
1200                 scheduledPaths.append(pathname)
1201                 if pathname in self.endpaths_():
1202                     endpaths.append(pathname)
1203                 else:
1204                     triggerPaths.append(pathname)
1205             for task in self.schedule_()._tasks:
1206                 task.resolve(self.__dict__)
1207                 scheduleTaskValidator = ScheduleTaskValidator()
1208                 task.visit(scheduleTaskValidator)
1209                 task.visit(nodeVisitor)
1210             
1211         processPSet.addVString(True, "@end_paths", endpaths)
1212         processPSet.addVString(True, "@paths", scheduledPaths)
1213         # trigger_paths are a little different
1214         p = processPSet.newPSet()
1215         p.addVString(True, "@trigger_paths", triggerPaths)
1216         processPSet.addPSet(True, "@trigger_paths", p)
1217         # add all these paths
1218         pathValidator = PathValidator()
1219         endpathValidator = EndPathValidator()
1220         decoratedList = []
1221         lister = DecoratedNodeNameVisitor(decoratedList)
1222         condTaskModules = []
1223         condTaskVistor = ModuleNodeOnConditionalTaskVisitor(condTaskModules)
1224         pathCompositeVisitor = CompositeVisitor(pathValidator, nodeVisitor, lister, condTaskVistor)
1225         endpathCompositeVisitor = CompositeVisitor(endpathValidator, nodeVisitor, lister)
1226         for triggername in triggerPaths:
1227             iPath = self.paths_()[triggername]
1228             iPath.resolve(self.__dict__)
1229             pathValidator.setLabel(triggername)
1230             lister.initialize()
1231             condTaskModules[:] = []
1232             iPath.visit(pathCompositeVisitor)
1233             if condTaskModules:
1234               decoratedList.append("#")
1235               l = list({x.label_() for x in condTaskModules})
1236               l.sort()
1237               decoratedList.extend(l)
1238               decoratedList.append("@")
1239             iPath.insertInto(processPSet, triggername, decoratedList[:])
1240         for endpathname in endpaths:
1241             iEndPath = self.endpaths_()[endpathname]
1242             iEndPath.resolve(self.__dict__)
1243             endpathValidator.setLabel(endpathname)
1244             lister.initialize()
1245             iEndPath.visit(endpathCompositeVisitor)
1246             iEndPath.insertInto(processPSet, endpathname, decoratedList[:])
1247         processPSet.addVString(False, "@filters_on_endpaths", endpathValidator.filtersOnEndpaths)
1248           
1249 
1250     def resolve(self,keepUnresolvedSequencePlaceholders:bool=False):
1251         for x in self.paths.values():
1252             x.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
1253         for x in self.endpaths.values():
1254             x.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
1255         if not self.schedule_() == None:
1256             for task in self.schedule_()._tasks:
1257                 task.resolve(self.__dict__,keepUnresolvedSequencePlaceholders)
1258 
1259     def prune(self,verbose=False,keepUnresolvedSequencePlaceholders:bool=False):
1260         """ Remove clutter from the process that we think is unnecessary:
1261         tracked PSets, VPSets and unused modules and sequences. If a Schedule has been set, then Paths and EndPaths
1262         not in the schedule will also be removed, along with an modules and sequences used only by
1263         those removed Paths and EndPaths. The keepUnresolvedSequencePlaceholders keeps also unresolved TaskPlaceholders."""
1264 # need to update this to only prune psets not on refToPSets
1265 # but for now, remove the delattr
1266 #        for name in self.psets_():
1267 #            if getattr(self,name).isTracked():
1268 #                delattr(self, name)
1269         for name in self.vpsets_():
1270             delattr(self, name)
1271         #first we need to resolve any SequencePlaceholders being used
1272         self.resolve(keepUnresolvedSequencePlaceholders)
1273         usedModules = set()
1274         unneededPaths = set()
1275         tasks = list()
1276         tv = TaskVisitor(tasks)
1277         if self.schedule_():
1278             usedModules=set(self.schedule_().moduleNames())
1279             #get rid of unused paths
1280             schedNames = set(( x.label_() for x in self.schedule_()))
1281             names = set(self.paths)
1282             names.update(set(self.endpaths))
1283             unneededPaths = names - schedNames
1284             for n in unneededPaths:
1285                 delattr(self,n)
1286             for t in self.schedule_().tasks():
1287                 tv.enter(t)
1288                 t.visit(tv)
1289                 tv.leave(t)
1290         else:
1291             pths = list(self.paths.values())
1292             pths.extend(self.endpaths.values())
1293             temp = Schedule(*pths)
1294             usedModules=set(temp.moduleNames())
1295         unneededModules = self._pruneModules(self.producers_(), usedModules)
1296         unneededModules.update(self._pruneModules(self.switchProducers_(), usedModules))
1297         unneededModules.update(self._pruneModules(self.filters_(), usedModules))
1298         unneededModules.update(self._pruneModules(self.analyzers_(), usedModules))
1299         #remove sequences and tasks that do not appear in remaining paths and endpaths
1300         seqs = list()
1301         sv = SequenceVisitor(seqs)
1302         for p in self.paths.values():
1303             p.visit(sv)
1304             p.visit(tv)
1305         for p in self.endpaths.values():
1306             p.visit(sv)
1307             p.visit(tv)
1308         def removeUnneeded(seqOrTasks, allSequencesOrTasks):
1309             _keepSet = set(( s for s in seqOrTasks if s.hasLabel_()))
1310             _availableSet = set(allSequencesOrTasks.values())
1311             _unneededSet = _availableSet-_keepSet
1312             _unneededLabels = []
1313             for s in _unneededSet:
1314                 _unneededLabels.append(s.label_())
1315                 delattr(self,s.label_())
1316             return _unneededLabels
1317         unneededSeqLabels = removeUnneeded(seqs, self.sequences)
1318         unneededTaskLabels = removeUnneeded(tasks, self.tasks)
1319         if verbose:
1320             print("prune removed the following:")
1321             print("  modules:"+",".join(unneededModules))
1322             print("  tasks:"+",".join(unneededTaskLabels))
1323             print("  sequences:"+",".join(unneededSeqLabels))
1324             print("  paths/endpaths:"+",".join(unneededPaths))
1325     def _pruneModules(self, d, scheduledNames):
1326         moduleNames = set(d.keys())
1327         junk = moduleNames - scheduledNames
1328         for name in junk:
1329             delattr(self, name)
1330         return junk
1331 
1332     def fillProcessDesc(self, processPSet):
1333         """Used by the framework to convert python to C++ objects"""
1334         class ServiceInjectorAdaptor(object):
1335             def __init__(self,ppset,thelist):
1336                 self.__thelist = thelist
1337                 self.__processPSet = ppset
1338             def addService(self,pset):
1339                 self.__thelist.append(pset)
1340             def newPSet(self):
1341                 return self.__processPSet.newPSet()
1342         #This adaptor is used to 'add' the method 'getTopPSet_'
1343         # to the ProcessDesc and PythonParameterSet C++ classes.
1344         # This method is needed for the PSet refToPSet_ functionality.
1345         class TopLevelPSetAcessorAdaptor(object):
1346             def __init__(self,ppset,process):
1347                 self.__ppset = ppset
1348                 self.__process = process
1349             def __getattr__(self,attr):
1350                 return getattr(self.__ppset,attr)
1351             def getTopPSet_(self,label):
1352                 return getattr(self.__process,label)
1353             def newPSet(self):
1354                 return TopLevelPSetAcessorAdaptor(self.__ppset.newPSet(),self.__process)
1355             def addPSet(self,tracked,name,ppset):
1356                 return self.__ppset.addPSet(tracked,name,self.__extractPSet(ppset))
1357             def addVPSet(self,tracked,name,vpset):
1358                 return self.__ppset.addVPSet(tracked,name,[self.__extractPSet(x) for x in vpset])
1359             def __extractPSet(self,pset):
1360                 if isinstance(pset,TopLevelPSetAcessorAdaptor):
1361                     return pset.__ppset
1362                 return pset
1363 
1364         self.validate()
1365         processPSet.addString(True, "@process_name", self.name_())
1366         if self.__specialOverrideReleaseVersionOnlyForTesting is not None:
1367             processPSet.addString(False, "@special_override_release_version_only_for_testing", self.__specialOverrideReleaseVersionOnlyForTesting)
1368         self.handleProcessAccelerators(processPSet)
1369         all_modules = self.producers_().copy()
1370         all_modules.update(self.filters_())
1371         all_modules.update(self.analyzers_())
1372         all_modules.update(self.outputModules_())
1373         if hasattr(self.options,"modulesToCallForTryToContinue") :
1374             shouldTryToContinue = set(self.options.modulesToCallForTryToContinue)
1375             for m in all_modules:
1376                 if m in shouldTryToContinue:
1377                     setattr(getattr(self,m),"@shouldTryToContinue",untracked.bool(True))
1378             missing = shouldTryToContinue.difference(all_modules)
1379             if missing:
1380                 print("Warning: The following modules appear in options.modulesToCallForTryToContinue but are not in the Process: {} ".format(",".join(missing)))
1381         adaptor = TopLevelPSetAcessorAdaptor(processPSet,self)
1382         self._insertInto(adaptor, self.psets_())
1383         self._insertInto(adaptor, self.vpsets_())
1384         self._insertOneInto(adaptor,  "@all_sources", self.source_(), True)
1385         self._insertOneInto(adaptor,  "@all_loopers", self.looper_(), True)
1386         self._insertManyInto(adaptor, "@all_esprefers", self.es_prefers_(), True)
1387         self._insertManyInto(adaptor, "@all_aliases", self.aliases_(), True)
1388         # This will visit all the paths and endpaths that are scheduled to run,
1389         # as well as the Tasks associated to them and the schedule. It remembers
1390         # the modules, ESSources, ESProducers, and services it visits.
1391         nodeVisitor = NodeVisitor()
1392         self._insertPaths(adaptor, nodeVisitor)
1393         all_modules_onTasksOrScheduled = { key:value for key, value in all_modules.items() if value in nodeVisitor.modules }
1394         self._insertManyInto(adaptor, "@all_modules", all_modules_onTasksOrScheduled, True)
1395         all_switches = self.switchProducers_().copy()
1396         all_switches_onTasksOrScheduled = {key:value for key, value in all_switches.items() if value in nodeVisitor.modules }
1397         self._insertSwitchProducersInto(adaptor, "@all_modules", "@all_aliases", all_switches_onTasksOrScheduled, True)
1398         # Same as nodeVisitor except this one visits all the Tasks attached
1399         # to the process.
1400         processNodeVisitor = NodeVisitor()
1401         for pTask in self.tasks.values():
1402             pTask.visit(processNodeVisitor)
1403         esProducersToEnable = {}
1404         for esProducerName, esProducer in self.es_producers_().items():
1405             if esProducer in nodeVisitor.esProducers or not (esProducer in processNodeVisitor.esProducers):
1406                 esProducersToEnable[esProducerName] = esProducer
1407         self._insertManyInto(adaptor, "@all_esmodules", esProducersToEnable, True)
1408         esSourcesToEnable = {}
1409         for esSourceName, esSource in self.es_sources_().items():
1410             if esSource in nodeVisitor.esSources or not (esSource in processNodeVisitor.esSources):
1411                 esSourcesToEnable[esSourceName] = esSource
1412         self._insertManyInto(adaptor, "@all_essources", esSourcesToEnable, True)
1413         #handle services differently
1414         services = []
1415         for serviceName, serviceObject in self.services_().items():
1416             if serviceObject in nodeVisitor.services or not (serviceObject in processNodeVisitor.services):
1417                 serviceObject.insertInto(ServiceInjectorAdaptor(adaptor,services))
1418         adaptor.addVPSet(False,"services",services)
1419         return processPSet
1420 
1421     def validate(self):
1422         # check if there's some input
1423         # Breaks too many unit tests for now
1424         #if self.source_() == None and self.looper_() == None:
1425         #    raise RuntimeError("No input source was found for this process")
1426         pass
1427 
1428     def handleProcessAccelerators(self, parameterSet):
1429         # 'cpu' accelerator is always implicitly there
1430         allAccelerators = set(["cpu"])
1431         availableAccelerators = set(["cpu"])
1432         for acc in self.__dict__['_Process__accelerators'].values():
1433             allAccelerators.update(acc.labels())
1434             availableAccelerators.update(acc.enabledLabels())
1435         availableAccelerators = sorted(list(availableAccelerators))
1436         parameterSet.addVString(False, "@available_accelerators", availableAccelerators)
1437 
1438         # Resolve wildcards
1439         selectedAccelerators = []
1440         if "*" in self.options.accelerators:
1441             if len(self.options.accelerators) >= 2:
1442                 raise ValueError("process.options.accelerators may contain '*' only as the only element, now it has {} elements".format(len(self.options.accelerators)))
1443             selectedAccelerators = availableAccelerators
1444         else:
1445             import fnmatch
1446             resolved = set()
1447             invalid = []
1448             for pattern in self.options.accelerators:
1449                 acc = [a for a in availableAccelerators if fnmatch.fnmatchcase(a, pattern)]
1450                 if len(acc) == 0:
1451                     if not any(fnmatch.fnmatchcase(a, pattern) for a in allAccelerators):
1452                         invalid.append(pattern)
1453                 else:
1454                    resolved.update(acc)
1455             # Sanity check
1456             if len(invalid) != 0:
1457                 raise ValueError("Invalid pattern{} of '{}' in process.options.accelerators, valid values are '{}' or a pattern matching some of them.".format(
1458                     "s" if len(invalid) > 2 else "",
1459                     "', '".join(invalid),
1460                     "', '".join(sorted(list(allAccelerators)))))
1461             selectedAccelerators = sorted(list(resolved))
1462         parameterSet.addVString(False, "@selected_accelerators", selectedAccelerators)
1463 
1464         # Get and apply module type resolver
1465         moduleTypeResolver = None
1466         moduleTypeResolverPlugin = ""
1467         for acc in self.__dict__['_Process__accelerators'].values():
1468             resolver = acc.moduleTypeResolver(selectedAccelerators)
1469             if resolver is not None:
1470                 if moduleTypeResolver is not None:
1471                     raise RuntimeError("Module type resolver was already set to {} when {} tried to set it to {}. A job can have at most one ProcessAccelerator that sets module type resolver.".format(
1472                         moduleTypeResolver.__class__.__name__,
1473                         acc.__class__.__name__,
1474                         resolver.__class__.__name__))
1475                 moduleTypeResolver = resolver
1476         if moduleTypeResolver is not None:
1477             # Plugin name and its configuration
1478             moduleTypeResolverPlugin = moduleTypeResolver.plugin()
1479 
1480             # Customize modules
1481             for modlist in [self.producers_, self.filters_, self.analyzers_,
1482                             self.es_producers_, self.es_sources_]:
1483                 for module in modlist().values():
1484                     moduleTypeResolver.setModuleVariant(module)
1485 
1486         parameterSet.addString(False, "@module_type_resolver", moduleTypeResolverPlugin)
1487 
1488         # Customize process
1489         wrapped = ProcessForProcessAccelerator(self)
1490         for acc in self.__dict__['_Process__accelerators'].values():
1491             acc.apply(wrapped, selectedAccelerators)
1492 
1493     def prefer(self, esmodule,*args,**kargs):
1494         """Prefer this ES source or producer.  The argument can
1495            either be an object label, e.g.,
1496              process.prefer(process.juicerProducer) (not supported yet)
1497            or a name of an ESSource or ESProducer
1498              process.prefer("juicer")
1499            or a type of unnamed ESSource or ESProducer
1500              process.prefer("JuicerProducer")
1501            In addition, you can pass as a labelled arguments the name of the Record you wish to
1502            prefer where the type passed is a cms.vstring and that vstring can contain the
1503            name of the C++ types in the Record that are being preferred, e.g.,
1504               #prefer all data in record 'OrangeRecord' from 'juicer'
1505               process.prefer("juicer", OrangeRecord=cms.vstring())
1506            or
1507               #prefer only "Orange" data in "OrangeRecord" from "juicer"
1508               process.prefer("juicer", OrangeRecord=cms.vstring("Orange"))
1509            or
1510               #prefer only "Orange" data with label "ExtraPulp" in "OrangeRecord" from "juicer"
1511               ESPrefer("ESJuicerProd", OrangeRecord=cms.vstring("Orange/ExtraPulp"))
1512         """
1513         # see if this refers to a named ESProducer
1514         if isinstance(esmodule, ESSource) or isinstance(esmodule, ESProducer):
1515             raise RuntimeError("Syntax of process.prefer(process.esmodule) not supported yet")
1516         elif self._findPreferred(esmodule, self.es_producers_(),*args,**kargs) or \
1517                 self._findPreferred(esmodule, self.es_sources_(),*args,**kargs):
1518             pass
1519         else:
1520             raise RuntimeError("Cannot resolve prefer for "+repr(esmodule))
1521 
1522     def _findPreferred(self, esname:str, d,*args,**kargs) -> bool:
1523         # is esname a name in the dictionary?
1524         if esname in d:
1525             typ = d[esname].type_()
1526             if typ == esname:
1527                 self.__setattr__( esname+"_prefer", ESPrefer(typ,*args,**kargs) )
1528             else:
1529                 self.__setattr__( esname+"_prefer", ESPrefer(typ, esname,*args,**kargs) )
1530             return True
1531         else:
1532             # maybe it's an unnamed ESModule?
1533             found = False
1534             for name, value in d.items():
1535                 if value.type_() == esname:
1536                     if found:
1537                         raise RuntimeError("More than one ES module for "+esname)
1538                     found = True
1539                     self.__setattr__(esname+"_prefer",  ESPrefer(d[esname].type_()) )
1540             return found
1541 
1542 
1543 class ProcessFragment(object):
1544     def __init__(self, process: Union[Process,str]):
1545         if isinstance(process, Process):
1546             self.__process = process
1547         elif isinstance(process, str):
1548             self.__process = Process(process)
1549             #make sure we do not override the defaults
1550             del self.__process.options
1551             del self.__process.maxEvents
1552             del self.__process.maxLuminosityBlocks
1553         else:
1554             raise TypeError('a ProcessFragment can only be constructed from an existig Process or from process name')
1555     def __dir__(self):
1556         return [ x for x in dir(self.__process) if isinstance(getattr(self.__process, x), _ConfigureComponent) ]
1557     def __getattribute__(self, name:str):
1558         if name == '_ProcessFragment__process':
1559             return object.__getattribute__(self, '_ProcessFragment__process')
1560         else:
1561             return getattr(self.__process, name)
1562     def __setattr__(self, name:str, value):
1563         if name == '_ProcessFragment__process':
1564             object.__setattr__(self, name, value)
1565         else:
1566             setattr(self.__process, name, value)
1567     def __delattr__(self, name:str):
1568         if name == '_ProcessFragment__process':
1569             pass
1570         else:
1571             return delattr(self.__process, name)
1572 
1573 
1574 class FilteredStream(dict):
1575     """a dictionary with fixed keys"""
1576     def _blocked_attribute(obj):
1577         raise AttributeError("An FilteredStream defintion cannot be modified after creation.")
1578     _blocked_attribute = property(_blocked_attribute)
1579     __setattr__ = __delitem__ = __setitem__ = clear = _blocked_attribute
1580     pop = popitem = setdefault = update = _blocked_attribute
1581     def __new__(cls, *args, **kw):
1582         new = dict.__new__(cls)
1583         dict.__init__(new, *args, **kw)
1584         keys = sorted(kw.keys())
1585         if keys != ['content', 'dataTier', 'name', 'paths', 'responsible', 'selectEvents']:
1586             raise ValueError("The needed parameters are: content, dataTier, name, paths, responsible, selectEvents")
1587         if not isinstance(kw['name'],str):
1588             raise ValueError("name must be of type string")
1589         if not isinstance(kw['content'], vstring) and not isinstance(kw['content'],str):
1590             raise ValueError("content must be of type vstring or string")
1591         if not isinstance(kw['dataTier'], string):
1592             raise ValueError("dataTier must be of type string")
1593         if not isinstance(kw['selectEvents'], PSet):
1594             raise ValueError("selectEvents must be of type PSet")
1595         if not isinstance(kw['paths'],(tuple, Path)):
1596             raise ValueError("'paths' must be a tuple of paths")
1597         return new
1598     def __init__(self, *args, **kw):
1599         pass
1600     def __repr__(self) -> str:
1601         return "FilteredStream object: %s" %self["name"]
1602     def __getattr__(self,attr):
1603         return self[attr]
1604 
1605 class _ParameterModifier(object):
1606     """Helper class for Modifier that takes key/value pairs and uses them to reset parameters of the object"""
1607     def __init__(self,args):
1608         self.__args = args
1609     def __call__(self,obj):
1610         params = {}
1611         for k in self.__args.keys():
1612             if hasattr(obj,k):
1613                 params[k] = getattr(obj,k)
1614         _modifyParametersFromDict(params, self.__args, self._raiseUnknownKey)
1615         for k in self.__args.keys():
1616             if k in params:
1617                 setattr(obj,k,params[k])
1618             else:
1619                 #the parameter must have been removed
1620                 delattr(obj,k)
1621     @staticmethod
1622     def _raiseUnknownKey(key):
1623         raise KeyError("Unknown parameter name "+key+" specified while calling Modifier")
1624 
1625 class _BoolModifierBase(object):
1626     """A helper base class for _AndModifier, _InvertModifier, and _OrModifier to contain the common code"""
1627     def __init__(self, lhs, rhs=None):
1628         self._lhs = lhs
1629         if rhs is not None:
1630             self._rhs = rhs
1631     def toModify(self,obj, func=None,**kw):
1632         Modifier._toModifyCheck(obj,func,**kw)
1633         if self._isChosen():
1634             Modifier._toModify(obj,func,**kw)
1635         return self
1636     def toReplaceWith(self,toObj,fromObj):
1637         Modifier._toReplaceWithCheck(toObj,fromObj)
1638         if self._isChosen():
1639             Modifier._toReplaceWith(toObj,fromObj)
1640         return self
1641     def makeProcessModifier(self,func):
1642         """This is used to create a ProcessModifer that can perform actions on the process as a whole.
1643             This takes as argument a callable object (e.g. function) that takes as its sole argument an instance of Process.
1644             In order to work, the value returned from this function must be assigned to a uniquely named variable."""
1645         return ProcessModifier(self,func)
1646     def __and__(self, other):
1647         return _AndModifier(self,other)
1648     def __invert__(self):
1649         return _InvertModifier(self)
1650     def __or__(self, other):
1651         return _OrModifier(self,other)
1652 
1653 class _AndModifier(_BoolModifierBase):
1654     """A modifier which only applies if multiple Modifiers are chosen"""
1655     def __init__(self, lhs, rhs):
1656         super(_AndModifier,self).__init__(lhs, rhs)
1657     def _isChosen(self) -> bool:
1658         return self._lhs._isChosen() and self._rhs._isChosen()
1659 
1660 class _InvertModifier(_BoolModifierBase):
1661     """A modifier which only applies if a Modifier is not chosen"""
1662     def __init__(self, lhs):
1663         super(_InvertModifier,self).__init__(lhs)
1664     def _isChosen(self) -> bool:
1665         return not self._lhs._isChosen()
1666 
1667 class _OrModifier(_BoolModifierBase):
1668     """A modifier which only applies if at least one of multiple Modifiers is chosen"""
1669     def __init__(self, lhs, rhs):
1670         super(_OrModifier,self).__init__(lhs, rhs)
1671     def _isChosen(self) -> bool:
1672         return self._lhs._isChosen() or self._rhs._isChosen()
1673 
1674 
1675 class Modifier(object):
1676     """This class is used to define standard modifications to a Process.
1677     An instance of this class is declared to denote a specific modification,e.g. era2017 could
1678     reconfigure items in a process to match our expectation of running in 2017. Once declared,
1679     these Modifier instances are imported into a configuration and items that need to be modified
1680     are then associated with the Modifier and with the action to do the modification.
1681     The registered modifications will only occur if the Modifier was passed to 
1682     the cms.Process' constructor.
1683     """
1684     def __init__(self):
1685         self.__processModifiers = []
1686         self.__chosen = False
1687     def makeProcessModifier(self,func):
1688         """This is used to create a ProcessModifer that can perform actions on the process as a whole.
1689            This takes as argument a callable object (e.g. function) that takes as its sole argument an instance of Process.
1690            In order to work, the value returned from this function must be assigned to a uniquely named variable.
1691         """
1692         return ProcessModifier(self,func)
1693     @staticmethod
1694     def _toModifyCheck(obj,func,**kw):
1695         if func is not None and len(kw) != 0:
1696             raise TypeError("toModify takes either two arguments or one argument and key/value pairs")
1697     def toModify(self,obj, func=None,**kw):
1698         """This is used to register an action to be performed on the specific object. Two different forms are allowed
1699         Form 1: A callable object (e.g. function) can be passed as the second. This callable object is expected to take one argument
1700         that will be the object passed in as the first argument.
1701         Form 2: A list of parameter name, value pairs can be passed
1702            mod.toModify(foo, fred=cms.int32(7), barney = cms.double(3.14))
1703         This form can also be used to remove a parameter by passing the value of None
1704             #remove the parameter foo.fred       
1705             mod.toModify(foo, fred = None)
1706         Additionally, parameters embedded within PSets can also be modified using a dictionary
1707             #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
1708             mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
1709         """
1710         Modifier._toModifyCheck(obj,func,**kw)
1711         if self._isChosen():
1712             Modifier._toModify(obj,func,**kw)
1713         return self
1714     @staticmethod
1715     def _toModify(obj,func,**kw):
1716         if func is not None:
1717             func(obj)
1718         else:
1719             temp =_ParameterModifier(kw)
1720             temp(obj)
1721     @staticmethod
1722     def _toReplaceWithCheck(toObj,fromObj):
1723         if not isinstance(fromObj, type(toObj)):
1724             raise TypeError("toReplaceWith requires both arguments to be the same class type")
1725     def toReplaceWith(self,toObj,fromObj):
1726         """If the Modifier is chosen the internals of toObj will be associated with the internals of fromObj
1727         """
1728         Modifier._toReplaceWithCheck(toObj,fromObj)
1729         if self._isChosen():
1730             Modifier._toReplaceWith(toObj,fromObj)
1731         return self
1732     @staticmethod
1733     def _toReplaceWith(toObj,fromObj):
1734         if isinstance(fromObj,_ModuleSequenceType):
1735             toObj._seq = fromObj._seq
1736             toObj._tasks = fromObj._tasks
1737         elif isinstance(fromObj,Task):
1738             toObj._collection = fromObj._collection
1739         elif isinstance(fromObj,ConditionalTask):
1740             toObj._collection = fromObj._collection
1741         elif isinstance(fromObj,_Parameterizable):
1742             #clear old items just incase fromObj is not a complete superset of toObj
1743             for p in toObj.parameterNames_():
1744                 delattr(toObj,p)
1745             for p in fromObj.parameterNames_():
1746                 setattr(toObj,p,getattr(fromObj,p))
1747             if isinstance(fromObj,_TypedParameterizable):
1748                 toObj._TypedParameterizable__type = fromObj._TypedParameterizable__type
1749 
1750         else:
1751             raise TypeError("toReplaceWith does not work with type "+str(type(toObj)))
1752 
1753     def _setChosen(self):
1754         """Should only be called by cms.Process instances"""
1755         self.__chosen = True
1756     def _isChosen(self) -> bool:
1757         return self.__chosen
1758     def __and__(self, other):
1759         return _AndModifier(self,other)
1760     def __invert__(self):
1761         return _InvertModifier(self)
1762     def __or__(self, other):
1763         return _OrModifier(self,other)
1764     def _isOrContains(self, other):
1765         return self == other
1766 
1767 
1768 class ModifierChain(object):
1769     """A Modifier made up of a list of Modifiers
1770     """
1771     def __init__(self, *chainedModifiers):
1772         self.__chosen = False
1773         self.__chain = chainedModifiers
1774     def _applyNewProcessModifiers(self,process):
1775         """Should only be called by cms.Process instances
1776         applies list of accumulated changes to the process"""
1777         for m in self.__chain:
1778             m._applyNewProcessModifiers(process)
1779     def _setChosen(self):
1780         """Should only be called by cms.Process instances"""
1781         self.__chosen = True
1782         for m in self.__chain:
1783             m._setChosen()
1784     def _isChosen(self) -> bool:
1785         return self.__chosen
1786     def copyAndExclude(self, toExclude):
1787         """Creates a new ModifierChain which is a copy of
1788           this ModifierChain but excludes any Modifier or
1789           ModifierChain in the list toExclude.
1790           The exclusion is done recursively down the chain.
1791           """
1792         newMods = []
1793         for m in self.__chain:
1794             if m not in toExclude:
1795                 s = m
1796                 if isinstance(m,ModifierChain):
1797                     s = m.__copyIfExclude(toExclude)
1798                 newMods.append(s)
1799         return ModifierChain(*newMods)
1800     def __copyIfExclude(self,toExclude):
1801         shouldCopy = False
1802         for m in toExclude:
1803             if self._isOrContains(m):
1804                 shouldCopy = True
1805                 break
1806         if shouldCopy:
1807             return self.copyAndExclude(toExclude)
1808         return self
1809     def _isOrContains(self, other):
1810         if self is other:
1811             return True
1812         for m in self.__chain:
1813             if m._isOrContains(other):
1814                 return True
1815         return False
1816 
1817 class ProcessModifier(object):
1818     """A class used by a Modifier to affect an entire Process instance.
1819     When a Process 'loads' a module containing a ProcessModifier, that
1820     ProcessModifier will be applied to the Process if and only if the 
1821     Modifier passed to the constructor has been chosen.
1822     """
1823     def __init__(self, modifier, func):
1824         self.__modifier = modifier
1825         self.__func = func
1826         self.__seenProcesses = set()
1827     def apply(self,process):
1828         if self.__modifier._isChosen():
1829             if process not in self.__seenProcesses:
1830                 self.__func(process)
1831                 self.__seenProcesses.add(process)
1832 
1833 class ProcessAccelerator(_ConfigureComponent,_Unlabelable):
1834     """A class used to specify possible compute accelerators in a Process
1835     instance. It is intended to be derived for any
1836     accelerator/portability technology, and provides hooks such that a
1837     specific customization can be applied to the Process on a worker
1838     node at the point where the python configuration is serialized for C++.
1839 
1840     The customization must not change the configuration hash. To
1841     enforce this reuirement, the customization gets a
1842     ProcessForProcessAccelerator wrapper that gives access to only
1843     those parts of the configuration that can be changed. Nevertheless
1844     it would be good to have specific unit test for each deriving
1845     class to ensure that all combinations of the enabled accelerators
1846     give the same configuration hash.
1847 
1848     The deriving class must do its checks for hardware availability
1849     only in enabledLabels(), and possibly in apply() if any further
1850     fine-tuning is needed, because those two are the only functions
1851     that are guaranteed to be called at the worker node.
1852     """
1853     def __init__(self):
1854         pass
1855     def _place(self, name, proc):
1856         proc._placeAccelerator(self.type_(), self)
1857     def type_(self):
1858         return type(self).__name__
1859     def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
1860         specialImportRegistry.registerUse(self)
1861         result = self.__class__.__name__+"(" # not including cms. since the deriving classes are not in cms "namespace"
1862         options.indent()
1863         res = self.dumpPythonImpl(options)
1864         options.unindent()
1865         if len(res) > 0:
1866             result += "\n"+res+"\n"
1867         result += ")\n"
1868         return result
1869 
1870     # The following methods are hooks to be overridden (if needed) in the deriving class
1871     def dumpPythonImpl(self, options) -> str:
1872         """Override if need to add any 'body' content to dumpPython(). Returns a string."""
1873         return ""
1874     def labels(self):
1875         """Override to return a list of strings for the accelerator labels."""
1876         return []
1877     def enabledLabels(self):
1878         """Override to return a list of strings for the accelerator labels
1879         that are enabled in the system the job is being run on."""
1880         return []
1881     def moduleTypeResolver(self, accelerators):
1882         """Override to return an object that implements "module type resolver"
1883         in python. The object should have the following methods
1884         - __init__(self, accelerators)
1885           * accelerators = list of selected accelerators
1886         - plugin(self):
1887           * should return a string for the type resolver plugin name
1888         - setModuleVariant(self, module):
1889           * Called for each ED and ES module. Should act only if
1890             module.type_() contains the magic identifier
1891 
1892         At most one of the ProcessAccelerators in a job can return a
1893 non-None object
1894         """
1895         return None
1896     def apply(self, process, accelerators):
1897         """Override if need to customize the Process at worker node. The
1898         selected available accelerator labels are given in the
1899         'accelerators' argument (the patterns, e.g. '*' have been
1900         expanded to concrete labels).
1901 
1902         This function may touch only untracked parameters.
1903         """
1904         pass
1905 
1906 class ProcessForProcessAccelerator(object):
1907     """This class is inteded to wrap the Process object to constrain the
1908     available functionality for ProcessAccelerator.apply()"""
1909     def  __init__(self, process):
1910         self.__process = process
1911     def __getattr__(self, label):
1912         value = getattr(self.__process, label)
1913         if not isinstance(value, Service):
1914             raise TypeError("ProcessAccelerator.apply() can get only Services. Tried to get {} with label {}".format(str(type(value)), label))
1915         return value
1916     def __setattr__(self, label:str, value):
1917         if label == "_ProcessForProcessAccelerator__process":
1918             super().__setattr__(label, value)
1919         else:
1920             if not isinstance(value, Service):
1921                 raise TypeError("ProcessAccelerator.apply() can only set Services. Tried to set {} with label {}".format(str(type(value)), label))
1922             setattr(self.__process, label, value)
1923     def __delattr__(self, label:str):
1924         value = getattr(self.__process, label)
1925         if not isinstance(value, Service):
1926             raise TypeError("ProcessAccelerator.apply() can delete only Services. Tried to del {} with label {}".format(str(type(value)), label))
1927         delattr(self.__process, label)
1928     def add_(self, value):
1929         if not isinstance(value, Service):
1930             raise TypeError("ProcessAccelerator.apply() can only add Services. Tried to set {} with label {}".format(str(type(value)), label))
1931         self.__process.add_(value)
1932 
1933 # Need to be a module-level function for the configuration with a
1934 # SwitchProducer to be pickleable.
1935 def _switchproducer_test2_case1(accelerators):
1936     return ("test1" in accelerators, -10)
1937 def _switchproducer_test2_case2(accelerators):
1938     return ("test2" in accelerators, -9)
1939 
1940 if __name__=="__main__":
1941     import unittest
1942     import copy
1943 
1944     def _lineDiff(newString, oldString):
1945         newString = ( x for x in newString.split('\n') if len(x) > 0)
1946         oldString = [ x for x in oldString.split('\n') if len(x) > 0]
1947         diff = []
1948         oldStringLine = 0
1949         for l in newString:
1950             if oldStringLine >= len(oldString):
1951                 diff.append(l)
1952                 continue
1953             if l == oldString[oldStringLine]:
1954                 oldStringLine +=1
1955                 continue
1956             diff.append(l)
1957         return "\n".join( diff )
1958 
1959     class TestMakePSet(object):
1960         """Has same interface as the C++ object that creates PSets
1961         """
1962         def __init__(self):
1963             self.values = dict()
1964         def __insertValue(self,tracked,label,value):
1965             self.values[label]=(tracked,value)
1966         def __getValue(self,tracked,label):
1967             pair = self.values[label]
1968             if pair[0] != tracked:
1969                raise Exception("Asked for %s parameter '%s', but it is %s" % ("tracked" if tracked else "untracked",
1970                                                                               label,
1971                                                                               "tracked" if pair[0] else "untracked"))
1972             return pair[1]
1973         def addInt32(self,tracked,label,value):
1974             self.__insertValue(tracked,label,value)
1975         def addVInt32(self,tracked,label,value):
1976             self.__insertValue(tracked,label,value)
1977         def addUInt32(self,tracked,label,value):
1978             self.__insertValue(tracked,label,value)
1979         def addVUInt32(self,tracked,label,value):
1980             self.__insertValue(tracked,label,value)
1981         def addInt64(self,tracked,label,value):
1982             self.__insertValue(tracked,label,value)
1983         def addVInt64(self,tracked,label,value):
1984             self.__insertValue(tracked,label,value)
1985         def addUInt64(self,tracked,label,value):
1986             self.__insertValue(tracked,label,value)
1987         def addVUInt64(self,tracked,label,value):
1988             self.__insertValue(tracked,label,value)
1989         def addDouble(self,tracked,label,value):
1990             self.__insertValue(tracked,label,value)
1991         def addVDouble(self,tracked,label,value):
1992             self.__insertValue(tracked,label,value)
1993         def addBool(self,tracked,label,value):
1994             self.__insertValue(tracked,label,value)
1995         def addString(self,tracked,label,value):
1996             self.__insertValue(tracked,label,value)
1997         def addVString(self,tracked,label,value):
1998             self.__insertValue(tracked,label,value)
1999         def getVString(self,tracked,label):
2000             return self.__getValue(tracked, label)
2001         def addInputTag(self,tracked,label,value):
2002             self.__insertValue(tracked,label,value)
2003         def addVInputTag(self,tracked,label,value):
2004             self.__insertValue(tracked,label,value)
2005         def addESInputTag(self,tracked,label,value):
2006             self.__insertValue(tracked,label,value)
2007         def addVESInputTag(self,tracked,label,value):
2008             self.__insertValue(tracked,label,value)
2009         def addEventID(self,tracked,label,value):
2010             self.__insertValue(tracked,label,value)
2011         def addVEventID(self,tracked,label,value):
2012             self.__insertValue(tracked,label,value)
2013         def addLuminosityBlockID(self,tracked,label,value):
2014             self.__insertValue(tracked,label,value)
2015         def addLuminosityBlockID(self,tracked,label,value):
2016             self.__insertValue(tracked,label,value)
2017         def addEventRange(self,tracked,label,value):
2018             self.__insertValue(tracked,label,value)
2019         def addVEventRange(self,tracked,label,value):
2020             self.__insertValue(tracked,label,value)
2021         def addPSet(self,tracked,label,value):
2022             self.__insertValue(tracked,label,value)
2023         def addVPSet(self,tracked,label,value):
2024             self.__insertValue(tracked,label,value)
2025         def addFileInPath(self,tracked,label,value):
2026             self.__insertValue(tracked,label,value)
2027         def newPSet(self):
2028             return TestMakePSet()
2029 
2030     class SwitchProducerTest(SwitchProducer):
2031         def __init__(self, **kargs):
2032             super(SwitchProducerTest,self).__init__(
2033                 dict(
2034                     test1 = lambda accelerators: (True, -10),
2035                     test2 = lambda accelerators: (True, -9),
2036                     test3 = lambda accelerators: (True, -8),
2037                     test4 = lambda accelerators: (True, -7)
2038                 ), **kargs)
2039     specialImportRegistry.registerSpecialImportForType(SwitchProducerTest, "from test import SwitchProducerTest")
2040 
2041     class SwitchProducerTest2(SwitchProducer):
2042         def __init__(self, **kargs):
2043             super(SwitchProducerTest2,self).__init__(
2044                 dict(
2045                     test1 = _switchproducer_test2_case1,
2046                     test2 = _switchproducer_test2_case2,
2047                 ), **kargs)
2048     specialImportRegistry.registerSpecialImportForType(SwitchProducerTest2, "from test import SwitchProducerTest2")
2049 
2050     class TestModuleTypeResolver:
2051         def __init__(self, accelerators):
2052             # first element is used as the default is nothing is set
2053             self._valid_backends = []
2054             if "test1" in accelerators:
2055                 self._valid_backends.append("test1_backend")
2056             if "test2" in accelerators:
2057                 self._valid_backends.append("test2_backend")
2058             if len(self._valid_backends) == 0:
2059                 raise EDMException(edm.errors.UnavailableAccelerator, "Machine has no accelerators that Test supports (has {})".format(", ".join(accelerators)))
2060 
2061         def plugin(self):
2062             return "TestModuleTypeResolver"
2063 
2064         def setModuleVariant(self, module):
2065             if "@test" in module.type_():
2066                 defaultBackend = self._valid_backends[0]
2067                 if hasattr(module, "test"):
2068                     if hasattr(module.test, "backend"):
2069                         if module.test.backend.value() not in self._valid_backends:
2070                             raise EDMException(edm.errors.UnavailableAccelerator, "Module {} has the Test backend set explicitly, but its accelerator is not available for the job".format(module.label_()))
2071                     else:
2072                         module.test.backend = untracked.string(defaultBackend)
2073                 else:
2074                     module.test = untracked.PSet(
2075                         backend = untracked.string(defaultBackend)
2076                     )
2077 
2078     class ProcessAcceleratorTest(ProcessAccelerator):
2079         def __init__(self, enabled=["test1", "test2", "anothertest3"], moduleTypeResolverMaker=None):
2080             super().__init__()
2081             self._labels = ["test1", "test2", "anothertest3"]
2082             self.setEnabled(enabled)
2083             self._moduleTypeResolverMaker = moduleTypeResolverMaker
2084         def setEnabled(self, enabled):
2085             invalid = set(enabled).difference(set(self._labels))
2086             if len(invalid) > 0:
2087                 raise Exception("Tried to enabled nonexistent test accelerators {}".format(",".join(invalid)))
2088             self._enabled = enabled[:]
2089         def dumpPythonImpl(self,options):
2090             result = "{}enabled = [{}]".format(options.indentation(),
2091                                                ", ".join(["'{}'".format(e) for e in self._enabled]))
2092             return result
2093         def labels(self):
2094             return self._labels
2095         def enabledLabels(self):
2096             return self._enabled
2097         def moduleTypeResolver(self, accelerators):
2098             if not self._moduleTypeResolverMaker:
2099                 return super().moduleTypeResolver(accelerators)
2100             return self._moduleTypeResolverMaker(accelerators)
2101         def apply(self, process, accelerators):
2102             process.AcceleratorTestService = Service("AcceleratorTestService")
2103             if hasattr(process, "AcceleratorTestServiceRemove"):
2104                 del process.AcceleratorTestServiceRemove
2105     specialImportRegistry.registerSpecialImportForType(ProcessAcceleratorTest, "from test import ProcessAcceleratorTest")
2106 
2107     class ProcessAcceleratorTest2(ProcessAccelerator):
2108         def __init__(self, enabled=["anothertest3", "anothertest4"], moduleTypeResolverMaker=None):
2109             super().__init__()
2110             self._labels = ["anothertest3", "anothertest4"]
2111             self.setEnabled(enabled)
2112             self._moduleTypeResolverMaker = moduleTypeResolverMaker
2113         def setEnabled(self, enabled):
2114             invalid = set(enabled).difference(set(self._labels))
2115             if len(invalid) > 0:
2116                 raise Exception("Tried to enabled nonexistent test accelerators {}".format(",".join(invalid)))
2117             self._enabled = enabled[:]
2118         def dumpPythonImpl(self,options):
2119             result = "{}enabled = [{}]".format(options.indentation(),
2120                                                ", ".join(["'{}'".format(e) for e in self._enabled]))
2121             return result
2122         def labels(self):
2123             return self._labels
2124         def enabledLabels(self):
2125             return self._enabled
2126         def moduleTypeResolver(self, accelerators):
2127             if not self._moduleTypeResolverMaker:
2128                 return super().moduleTypeResolver(accelerators)
2129             return self._moduleTypeResolverMaker(accelerators)
2130         def apply(self, process, accelerators):
2131             pass
2132     specialImportRegistry.registerSpecialImportForType(ProcessAcceleratorTest2, "from test import ProcessAcceleratorTest2")
2133 
2134     class TestModuleCommand(unittest.TestCase):
2135         def setUp(self):
2136             """Nothing to do """
2137             None
2138         def testParameterizable(self):
2139             p = _Parameterizable()
2140             self.assertEqual(len(p.parameterNames_()),0)
2141             p.a = int32(1)
2142             self.assertTrue('a' in p.parameterNames_())
2143             self.assertEqual(p.a.value(), 1)
2144             p.a = 10
2145             self.assertEqual(p.a.value(), 10)
2146             p.a = untracked(int32(1))
2147             self.assertEqual(p.a.value(), 1)
2148             self.assertFalse(p.a.isTracked())
2149             p.a = untracked.int32(1)
2150             self.assertEqual(p.a.value(), 1)
2151             self.assertFalse(p.a.isTracked())
2152             p = _Parameterizable(foo=int32(10), bar = untracked(double(1.0)))
2153             self.assertEqual(p.foo.value(), 10)
2154             self.assertEqual(p.bar.value(),1.0)
2155             self.assertFalse(p.bar.isTracked())
2156             self.assertRaises(TypeError,setattr,(p,'c',1))
2157             p = _Parameterizable(a=PSet(foo=int32(10), bar = untracked(double(1.0))))
2158             self.assertEqual(p.a.foo.value(),10)
2159             self.assertEqual(p.a.bar.value(),1.0)
2160             p.b = untracked(PSet(fii = int32(1)))
2161             self.assertEqual(p.b.fii.value(),1)
2162             self.assertFalse(p.b.isTracked())
2163             #test the fact that values can be shared
2164             v = int32(10)
2165             p=_Parameterizable(a=v)
2166             v.setValue(11)
2167             self.assertEqual(p.a.value(),11)
2168             p.a = 12
2169             self.assertEqual(p.a.value(),12)
2170             self.assertEqual(v.value(),12)
2171         def testTypedParameterizable(self):
2172             p = _TypedParameterizable("blah", b=int32(1))
2173             #see if copy works deeply
2174             other = p.copy()
2175             other.b = 2
2176             self.assertNotEqual(p.b,other.b)
2177 
2178         def testProcessInsertion(self):
2179             p = Process("test")
2180             p.a = EDAnalyzer("MyAnalyzer")
2181             self.assertTrue( 'a' in p.analyzers_() )
2182             self.assertTrue( 'a' in p.analyzers)
2183             p.add_(Service("SomeService"))
2184             self.assertTrue('SomeService' in p.services_())
2185             self.assertEqual(p.SomeService.type_(), "SomeService")
2186             p.Tracer = Service("Tracer")
2187             self.assertTrue('Tracer' in p.services_())
2188             self.assertRaises(TypeError, setattr, *(p,'b',"this should fail"))
2189             self.assertRaises(TypeError, setattr, *(p,'bad',Service("MessageLogger")))
2190             self.assertRaises(ValueError, setattr, *(p,'bad',Source("PoolSource")))
2191             p.out = OutputModule("Outer")
2192             self.assertEqual(p.out.type_(), 'Outer')
2193             self.assertTrue( 'out' in p.outputModules_() )
2194 
2195             p.geom = ESSource("GeomProd")
2196             self.assertTrue('geom' in p.es_sources_())
2197             p.add_(ESSource("ConfigDB"))
2198             self.assertTrue('ConfigDB' in p.es_sources_())
2199 
2200             p.aliasfoo1 = EDAlias(foo1 = VPSet(PSet(type = string("Foo1"))))
2201             self.assertTrue('aliasfoo1' in p.aliases_())
2202 
2203         def testProcessExtend(self):
2204             class FromArg(object):
2205                 def __init__(self,*arg,**args):
2206                     for name in args.keys():
2207                         self.__dict__[name]=args[name]
2208 
2209             a=EDAnalyzer("MyAnalyzer")
2210             t=EDAnalyzer("MyAnalyzer")
2211             t.setLabel("foo")
2212             s1 = Sequence(a)
2213             s2 = Sequence(s1)
2214             s3 = Sequence(s2)
2215             d = FromArg(
2216                     a=a,
2217                     b=Service("Full"),
2218                     c=Path(a),
2219                     d=s2,
2220                     e=s1,
2221                     f=s3,
2222                     g=Sequence(s1+s2+s3)
2223                 )
2224             p = Process("Test")
2225             p.extend(d)
2226             self.assertEqual(p.a.type_(),"MyAnalyzer")
2227             self.assertEqual(p.a.label_(),"a")
2228             self.assertRaises(AttributeError,getattr,p,'b')
2229             self.assertEqual(p.Full.type_(),"Full")
2230             self.assertEqual(str(p.c),'a')
2231             self.assertEqual(str(p.d),'a')
2232 
2233             z1 = FromArg(
2234                     a=a,
2235                     b=Service("Full"),
2236                     c=Path(a),
2237                     d=s2,
2238                     e=s1,
2239                     f=s3,
2240                     s4=s3,
2241                     g=Sequence(s1+s2+s3)
2242                  )
2243 
2244             p1 = Process("Test")
2245             #p1.extend(z1)
2246             self.assertRaises(ValueError, p1.extend, z1)
2247 
2248             z2 = FromArg(
2249                     a=a,
2250                     b=Service("Full"),
2251                     c=Path(a),
2252                     d=s2,
2253                     e=s1,
2254                     f=s3,
2255                     aaa=copy.deepcopy(a),
2256                     s4=copy.deepcopy(s3),
2257                     g=Sequence(s1+s2+s3),
2258                     t=t
2259                 )
2260             p2 = Process("Test")
2261             p2.extend(z2)
2262             #self.assertRaises(ValueError, p2.extend, z2)
2263             self.assertEqual(p2.s4.label_(),"s4")
2264             #p2.s4.setLabel("foo")
2265             self.assertRaises(ValueError, p2.s4.setLabel, "foo")
2266             p2.s4.setLabel("s4")
2267             p2.s4.setLabel(None)
2268             p2.s4.setLabel("foo")
2269             p2._Process__setObjectLabel(p2.s4, "foo")
2270             p2._Process__setObjectLabel(p2.s4, None)
2271             p2._Process__setObjectLabel(p2.s4, "bar")
2272 
2273 
2274             p = Process('test')
2275             p.a = EDProducer("MyProducer")
2276             p.t = Task(p.a)
2277             p.p = Path(p.t)
2278             self.assertRaises(ValueError, p.extend, FromArg(a = EDProducer("YourProducer")))
2279             self.assertRaises(ValueError, p.extend, FromArg(a = EDAlias()))
2280             self.assertRaises(ValueError, p.__setattr__, "a", EDAlias())
2281 
2282             p = Process('test')
2283             p.a = EDProducer("MyProducer")
2284             p.t = ConditionalTask(p.a)
2285             p.p = Path(p.t)
2286             self.assertRaises(ValueError, p.extend, FromArg(a = EDProducer("YourProducer")))
2287             self.assertRaises(ValueError, p.extend, FromArg(a = EDAlias()))
2288             self.assertRaises(ValueError, p.__setattr__, "a", EDAlias())
2289 
2290             p = Process('test')
2291             p.a = EDProducer("MyProducer")
2292             p.s = Sequence(p.a)
2293             p.p = Path(p.s)
2294             self.assertRaises(ValueError, p.extend, FromArg(a = EDProducer("YourProducer")))
2295             self.assertRaises(ValueError, p.extend, FromArg(a = EDAlias()))
2296             self.assertRaises(ValueError, p.__setattr__, "a", EDAlias())
2297 
2298         def testProcessDumpPython(self):
2299             self.maxDiff = None
2300             self.assertEqual(Process("test").dumpPython(),
2301 """import FWCore.ParameterSet.Config as cms
2302 
2303 process = cms.Process("test")
2304 
2305 process.maxEvents = cms.untracked.PSet(
2306     input = cms.optional.untracked.int32,
2307     output = cms.optional.untracked.allowed(cms.int32,cms.PSet)
2308 )
2309 
2310 process.maxLuminosityBlocks = cms.untracked.PSet(
2311     input = cms.untracked.int32(-1)
2312 )
2313 
2314 process.options = cms.untracked.PSet(
2315     IgnoreCompletely = cms.untracked.vstring(),
2316     Rethrow = cms.untracked.vstring(),
2317     TryToContinue = cms.untracked.vstring(),
2318     accelerators = cms.untracked.vstring('*'),
2319     allowUnscheduled = cms.obsolete.untracked.bool,
2320     canDeleteEarly = cms.untracked.vstring(),
2321     deleteNonConsumedUnscheduledModules = cms.untracked.bool(True),
2322     dumpOptions = cms.untracked.bool(False),
2323     emptyRunLumiMode = cms.obsolete.untracked.string,
2324     eventSetup = cms.untracked.PSet(
2325         forceNumberOfConcurrentIOVs = cms.untracked.PSet(
2326             allowAnyLabel_=cms.required.untracked.uint32
2327         ),
2328         numberOfConcurrentIOVs = cms.untracked.uint32(0)
2329     ),
2330     fileMode = cms.untracked.string('FULLMERGE'),
2331     forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False),
2332     holdsReferencesToDeleteEarly = cms.untracked.VPSet(),
2333     makeTriggerResults = cms.obsolete.untracked.bool,
2334     modulesToCallForTryToContinue = cms.untracked.vstring(),
2335     modulesToIgnoreForDeleteEarly = cms.untracked.vstring(),
2336     numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(0),
2337     numberOfConcurrentRuns = cms.untracked.uint32(1),
2338     numberOfStreams = cms.untracked.uint32(0),
2339     numberOfThreads = cms.untracked.uint32(1),
2340     printDependencies = cms.untracked.bool(False),
2341     sizeOfStackForThreadsInKB = cms.optional.untracked.uint32,
2342     throwIfIllegalParameter = cms.untracked.bool(True),
2343     wantSummary = cms.untracked.bool(False)
2344 )
2345 
2346 process.MessageLogger = cms.Service("MessageLogger",
2347     cerr = cms.untracked.PSet(
2348         FwkReport = cms.untracked.PSet(
2349             limit = cms.untracked.int32(10000000),
2350             reportEvery = cms.untracked.int32(1)
2351         ),
2352         FwkSummary = cms.untracked.PSet(
2353             limit = cms.untracked.int32(10000000),
2354             reportEvery = cms.untracked.int32(1)
2355         ),
2356         INFO = cms.untracked.PSet(
2357             limit = cms.untracked.int32(0)
2358         ),
2359         Root_NoDictionary = cms.untracked.PSet(
2360             limit = cms.untracked.int32(0)
2361         ),
2362         default = cms.untracked.PSet(
2363             limit = cms.untracked.int32(10000000)
2364         ),
2365         enable = cms.untracked.bool(True),
2366         enableStatistics = cms.untracked.bool(False),
2367         lineLength = cms.optional.untracked.int32,
2368         noLineBreaks = cms.optional.untracked.bool,
2369         noTimeStamps = cms.untracked.bool(False),
2370         resetStatistics = cms.untracked.bool(False),
2371         statisticsThreshold = cms.untracked.string('WARNING'),
2372         threshold = cms.untracked.string('INFO'),
2373         allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2374             limit = cms.optional.untracked.int32,
2375             reportEvery = cms.untracked.int32(1),
2376             timespan = cms.optional.untracked.int32
2377         )
2378     ),
2379     cout = cms.untracked.PSet(
2380         enable = cms.untracked.bool(False),
2381         enableStatistics = cms.untracked.bool(False),
2382         lineLength = cms.optional.untracked.int32,
2383         noLineBreaks = cms.optional.untracked.bool,
2384         noTimeStamps = cms.optional.untracked.bool,
2385         resetStatistics = cms.untracked.bool(False),
2386         statisticsThreshold = cms.optional.untracked.string,
2387         threshold = cms.optional.untracked.string,
2388         allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2389             limit = cms.optional.untracked.int32,
2390             reportEvery = cms.untracked.int32(1),
2391             timespan = cms.optional.untracked.int32
2392         )
2393     ),
2394     debugModules = cms.untracked.vstring(),
2395     default = cms.untracked.PSet(
2396         limit = cms.optional.untracked.int32,
2397         lineLength = cms.untracked.int32(80),
2398         noLineBreaks = cms.untracked.bool(False),
2399         noTimeStamps = cms.untracked.bool(False),
2400         reportEvery = cms.untracked.int32(1),
2401         statisticsThreshold = cms.untracked.string('INFO'),
2402         threshold = cms.untracked.string('INFO'),
2403         timespan = cms.optional.untracked.int32,
2404         allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2405             limit = cms.optional.untracked.int32,
2406             reportEvery = cms.untracked.int32(1),
2407             timespan = cms.optional.untracked.int32
2408         )
2409     ),
2410     files = cms.untracked.PSet(
2411         allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2412             enableStatistics = cms.untracked.bool(False),
2413             extension = cms.optional.untracked.string,
2414             filename = cms.optional.untracked.string,
2415             lineLength = cms.optional.untracked.int32,
2416             noLineBreaks = cms.optional.untracked.bool,
2417             noTimeStamps = cms.optional.untracked.bool,
2418             output = cms.optional.untracked.string,
2419             resetStatistics = cms.untracked.bool(False),
2420             statisticsThreshold = cms.optional.untracked.string,
2421             threshold = cms.optional.untracked.string,
2422             allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2423                 limit = cms.optional.untracked.int32,
2424                 reportEvery = cms.untracked.int32(1),
2425                 timespan = cms.optional.untracked.int32
2426             )
2427         )
2428     ),
2429     suppressDebug = cms.untracked.vstring(),
2430     suppressFwkInfo = cms.untracked.vstring(),
2431     suppressInfo = cms.untracked.vstring(),
2432     suppressWarning = cms.untracked.vstring(),
2433     allowAnyLabel_=cms.optional.untracked.PSetTemplate(
2434         limit = cms.optional.untracked.int32,
2435         reportEvery = cms.untracked.int32(1),
2436         timespan = cms.optional.untracked.int32
2437     )
2438 )
2439 
2440 
2441 """)
2442             p = Process("test")
2443             p.a = EDAnalyzer("MyAnalyzer")
2444             p.p = Path(p.a)
2445             p.s = Sequence(p.a)
2446             p.r = Sequence(p.s)
2447             p.p2 = Path(p.s)
2448             p.schedule = Schedule(p.p2,p.p)
2449             d=p.dumpPython()
2450             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2451 """process.a = cms.EDAnalyzer("MyAnalyzer")
2452 process.s = cms.Sequence(process.a)
2453 process.r = cms.Sequence(process.s)
2454 process.p = cms.Path(process.a)
2455 process.p2 = cms.Path(process.s)
2456 process.schedule = cms.Schedule(*[ process.p2, process.p ])""")
2457             #Reverse order of 'r' and 's'
2458             p = Process("test")
2459             p.a = EDAnalyzer("MyAnalyzer")
2460             p.p = Path(p.a)
2461             p.r = Sequence(p.a)
2462             p.s = Sequence(p.r)
2463             p.p2 = Path(p.r)
2464             p.schedule = Schedule(p.p2,p.p)
2465             p.b = EDAnalyzer("YourAnalyzer")
2466             d=p.dumpPython()
2467             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2468 """process.a = cms.EDAnalyzer("MyAnalyzer")
2469 process.b = cms.EDAnalyzer("YourAnalyzer")
2470 process.r = cms.Sequence(process.a)
2471 process.s = cms.Sequence(process.r)
2472 process.p = cms.Path(process.a)
2473 process.p2 = cms.Path(process.r)
2474 process.schedule = cms.Schedule(*[ process.p2, process.p ])""")
2475         #use an anonymous sequence
2476             p = Process("test")
2477             p.a = EDAnalyzer("MyAnalyzer")
2478             p.p = Path(p.a)
2479             s = Sequence(p.a)
2480             p.r = Sequence(s)
2481             p.p2 = Path(p.r)
2482             p.schedule = Schedule(p.p2,p.p)
2483             d=p.dumpPython()
2484             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2485 """process.a = cms.EDAnalyzer("MyAnalyzer")
2486 process.r = cms.Sequence((process.a))
2487 process.p = cms.Path(process.a)
2488 process.p2 = cms.Path(process.r)
2489 process.schedule = cms.Schedule(*[ process.p2, process.p ])""")
2490 
2491             # include some tasks
2492             p = Process("test")
2493             p.a = EDAnalyzer("MyAnalyzer")
2494             p.b = EDProducer("bProducer")
2495             p.c = EDProducer("cProducer")
2496             p.d = EDProducer("dProducer")
2497             p.e = EDProducer("eProducer")
2498             p.f = EDProducer("fProducer")
2499             p.g = EDProducer("gProducer")
2500             p.task5 = Task()
2501             p.task3 = Task()
2502             p.task2 = Task(p.c, p.task3)
2503             p.task4 = Task(p.f, p.task2)
2504             p.task1 = Task(p.task5)
2505             p.task3.add(p.task1)
2506             p.p = Path(p.a)
2507             s = Sequence(p.a)
2508             p.r = Sequence(s)
2509             p.p2 = Path(p.r, p.task1, p.task2)
2510             p.schedule = Schedule(p.p2,p.p,tasks=[p.task3,p.task4, p.task5])
2511             d=p.dumpPython()
2512             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2513 """process.b = cms.EDProducer("bProducer")
2514 process.c = cms.EDProducer("cProducer")
2515 process.d = cms.EDProducer("dProducer")
2516 process.e = cms.EDProducer("eProducer")
2517 process.f = cms.EDProducer("fProducer")
2518 process.g = cms.EDProducer("gProducer")
2519 process.a = cms.EDAnalyzer("MyAnalyzer")
2520 process.task5 = cms.Task()
2521 process.task1 = cms.Task(process.task5)
2522 process.task3 = cms.Task(process.task1)
2523 process.task2 = cms.Task(process.c, process.task3)
2524 process.task4 = cms.Task(process.f, process.task2)
2525 process.r = cms.Sequence((process.a))
2526 process.p = cms.Path(process.a)
2527 process.p2 = cms.Path(process.r, process.task1, process.task2)
2528 process.schedule = cms.Schedule(*[ process.p2, process.p ], tasks=[process.task3, process.task4, process.task5])""")
2529             # include some conditional tasks
2530             p = Process("test")
2531             p.a = EDAnalyzer("MyAnalyzer")
2532             p.b = EDProducer("bProducer")
2533             p.c = EDProducer("cProducer")
2534             p.d = EDProducer("dProducer")
2535             p.e = EDProducer("eProducer")
2536             p.f = EDProducer("fProducer")
2537             p.g = EDProducer("gProducer")
2538             p.task5 = Task()
2539             p.task3 = Task()
2540             p.task2 = ConditionalTask(p.c, p.task3)
2541             p.task1 = ConditionalTask(p.task5)
2542             p.p = Path(p.a)
2543             s = Sequence(p.a)
2544             p.r = Sequence(s)
2545             p.p2 = Path(p.r, p.task1, p.task2)
2546             p.schedule = Schedule(p.p2,p.p,tasks=[p.task5])
2547             d=p.dumpPython()
2548             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2549 """process.b = cms.EDProducer("bProducer")
2550 process.c = cms.EDProducer("cProducer")
2551 process.d = cms.EDProducer("dProducer")
2552 process.e = cms.EDProducer("eProducer")
2553 process.f = cms.EDProducer("fProducer")
2554 process.g = cms.EDProducer("gProducer")
2555 process.a = cms.EDAnalyzer("MyAnalyzer")
2556 process.task5 = cms.Task()
2557 process.task3 = cms.Task()
2558 process.task2 = cms.ConditionalTask(process.c, process.task3)
2559 process.task1 = cms.ConditionalTask(process.task5)
2560 process.r = cms.Sequence((process.a))
2561 process.p = cms.Path(process.a)
2562 process.p2 = cms.Path(process.r, process.task1, process.task2)
2563 process.schedule = cms.Schedule(*[ process.p2, process.p ], tasks=[process.task5])""")
2564             # only tasks
2565             p = Process("test")
2566             p.d = EDProducer("dProducer")
2567             p.e = EDProducer("eProducer")
2568             p.f = EDProducer("fProducer")
2569             p.g = EDProducer("gProducer")
2570             p.task1 = Task(p.d, p.e)
2571             task2 = Task(p.f, p.g)
2572             p.schedule = Schedule(tasks=[p.task1,task2])
2573             d=p.dumpPython()
2574             self.assertEqual(_lineDiff(d,Process("test").dumpPython()),
2575 """process.d = cms.EDProducer("dProducer")
2576 process.e = cms.EDProducer("eProducer")
2577 process.f = cms.EDProducer("fProducer")
2578 process.g = cms.EDProducer("gProducer")
2579 process.task1 = cms.Task(process.d, process.e)
2580 process.schedule = cms.Schedule(tasks=[cms.Task(process.f, process.g), process.task1])""")
2581             # empty schedule
2582             p = Process("test")
2583             p.schedule = Schedule()
2584             d=p.dumpPython()
2585             self.assertEqual(_lineDiff(d,Process('test').dumpPython()),
2586 """process.schedule = cms.Schedule()""")
2587 
2588             s = Sequence()
2589             a = EDProducer("A")
2590             s2 = Sequence(a)
2591             s2 += s
2592             process = Process("DUMP")
2593             process.a = a
2594             process.s2 = s2
2595             d=process.dumpPython()
2596             self.assertEqual(_lineDiff(d,Process('DUMP').dumpPython()),
2597 """process.a = cms.EDProducer("A")
2598 process.s2 = cms.Sequence(process.a)""")
2599             s = Sequence()
2600             s1 = Sequence(s)
2601             a = EDProducer("A")
2602             s3 = Sequence(a+a)
2603             s2 = Sequence(a+s3)
2604             s2 += s1
2605             process = Process("DUMP")
2606             process.a = a
2607             process.s2 = s2
2608             d=process.dumpPython()
2609             self.assertEqual(_lineDiff(d,Process('DUMP').dumpPython()),
2610 """process.a = cms.EDProducer("A")
2611 process.s2 = cms.Sequence(process.a+(process.a+process.a))""")
2612 
2613         def testSecSource(self):
2614             p = Process('test')
2615             p.a = SecSource("MySecSource")
2616             self.assertEqual(_lineDiff(p.dumpPython(),Process('test').dumpPython()),'process.a = cms.SecSource("MySecSource")')
2617 
2618         def testGlobalReplace(self):
2619             p = Process('test')
2620             p.a = EDAnalyzer("MyAnalyzer")
2621             old = p.a
2622             p.b = EDAnalyzer("YourAnalyzer")
2623             p.c = EDAnalyzer("OurAnalyzer")
2624             p.d = EDProducer("MyProducer")
2625             old2 = p.d
2626             p.t1 = Task(p.d)
2627             t2 = Task(p.d)
2628             t3 = Task(p.d)
2629             t4 = Task(p.d)
2630             t5 = Task(p.d)
2631             t6 = Task(p.d)
2632             p.ct1 = ConditionalTask(p.d)
2633             s = Sequence(p.a*p.b)
2634             p.s4 = Sequence(p.a*p.b, p.ct1)
2635             s.associate(t2)
2636             p.s4.associate(t2)
2637             p.p = Path(p.c+s+p.a)
2638             p.p2 = Path(p.c+p.s4+p.a, p.ct1)
2639             p.e3 = EndPath(p.c+s+p.a)
2640             new = EDAnalyzer("NewAnalyzer")
2641             new2 = EDProducer("NewProducer")
2642             visitor1 = NodeVisitor()
2643             p.p.visit(visitor1)
2644             self.assertTrue(visitor1.modules == set([old,old2,p.b,p.c]))
2645             p.schedule = Schedule(tasks=[t6])
2646             p.globalReplace("a",new)
2647             p.globalReplace("d",new2)
2648             visitor2 = NodeVisitor()
2649             p.p.visit(visitor2)
2650             self.assertTrue(visitor2.modules == set([new,new2,p.b,p.c]))
2651             self.assertEqual(p.p.dumpPython()[:-1], "cms.Path(process.c+process.a+process.b+process.a, cms.Task(process.d))")
2652             visitor_p2 = NodeVisitor()
2653             p.p2.visit(visitor_p2)
2654             self.assertTrue(visitor_p2.modules == set([new,new2,p.b,p.c]))
2655             self.assertEqual(p.p2.dumpPython()[:-1], "cms.Path(process.c+process.s4+process.a, process.ct1)")
2656             visitor3 = NodeVisitor()
2657             p.e3.visit(visitor3)
2658             self.assertTrue(visitor3.modules == set([new,new2,p.b,p.c]))
2659             visitor4 = NodeVisitor()
2660             p.s4.visit(visitor4)
2661             self.assertTrue(visitor4.modules == set([new,new2,p.b]))
2662             self.assertEqual(p.s4.dumpPython()[:-1],"cms.Sequence(process.a+process.b, cms.Task(process.d), process.ct1)")
2663             visitor5 = NodeVisitor()
2664             p.t1.visit(visitor5)
2665             self.assertTrue(visitor5.modules == set([new2]))
2666             visitor6 = NodeVisitor()
2667             listOfTasks = list(p.schedule._tasks)
2668             listOfTasks[0].visit(visitor6)
2669             self.assertTrue(visitor6.modules == set([new2]))
2670             visitor7 = NodeVisitor()
2671             p.ct1.visit(visitor7)
2672             self.assertTrue(visitor7.modules == set([new2]))
2673             visitor8 = NodeVisitor()
2674             listOfConditionalTasks = list(p.conditionaltasks.values())
2675             listOfConditionalTasks[0].visit(visitor8)
2676             self.assertTrue(visitor8.modules == set([new2]))
2677 
2678 
2679             p.d2 = EDProducer("YourProducer")
2680             p.schedule = Schedule(p.p, p.p2, p.e3, tasks=[p.t1])
2681             self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
2682             p.p = Path(p.c+s)
2683             self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
2684             p.e3 = EndPath(p.c)
2685             self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
2686             p.t1 = Task(p.d2)
2687             self.assertEqual(p.schedule.dumpPython()[:-1], "cms.Schedule(*[ process.p, process.p2, process.e3 ], tasks=[process.t1])")
2688 
2689         def testSequence(self):
2690             p = Process('test')
2691             p.a = EDAnalyzer("MyAnalyzer")
2692             p.b = EDAnalyzer("YourAnalyzer")
2693             p.c = EDAnalyzer("OurAnalyzer")
2694             p.s = Sequence(p.a*p.b)
2695             self.assertEqual(str(p.s),'a+b')
2696             self.assertEqual(p.s.label_(),'s')
2697             path = Path(p.c+p.s)
2698             self.assertEqual(str(path),'c+a+b')
2699             p._validateSequence(path, 'p1')
2700             notInProcess = EDAnalyzer('NotInProcess')
2701             p2 = Path(p.c+p.s*notInProcess)
2702             self.assertRaises(RuntimeError, p._validateSequence, p2, 'p2')
2703 
2704         def testSequence2(self):
2705             p = Process('test')
2706             p.a = EDAnalyzer("MyAnalyzer")
2707             p.b = EDAnalyzer("YourAnalyzer")
2708             p.c = EDAnalyzer("OurAnalyzer")
2709             testseq = Sequence(p.a*p.b)
2710             p.s = testseq
2711             #p.y = testseq
2712             self.assertRaises(ValueError, p.__setattr__, "y", testseq) 
2713 
2714         def testServiceInProcess(self):
2715             service = Service("d")
2716             self.assertFalse(service._inProcess)
2717             process = Process("test")
2718             process.d = service
2719             self.assertTrue(service._inProcess)
2720             service2 = Service("d")
2721             process.d = service2
2722             self.assertFalse(service._inProcess)
2723             self.assertTrue(service2._inProcess)
2724             del process.d
2725             self.assertFalse(service2._inProcess)
2726 
2727         def testTask(self):
2728 
2729             # create some objects to use in tests
2730             edanalyzer = EDAnalyzer("a")
2731             edproducer = EDProducer("b")
2732             edproducer2 = EDProducer("b2")
2733             edproducer3 = EDProducer("b3")
2734             edproducer4 = EDProducer("b4")
2735             edproducer8 = EDProducer("b8")
2736             edproducer9 = EDProducer("b9")
2737             edfilter = EDFilter("c")
2738             service = Service("d")
2739             service3 = Service("d", v = untracked.uint32(3))
2740             essource = ESSource("e")
2741             esproducer = ESProducer("f")
2742             testTask2 = Task()
2743 
2744             # test adding things to Tasks
2745             testTask1 = Task(edproducer, edfilter)
2746             self.assertRaises(RuntimeError, testTask1.add, edanalyzer)
2747             testTask1.add(essource, service)
2748             testTask1.add(essource, esproducer)
2749             testTask1.add(testTask2)
2750             coll = testTask1._collection
2751             self.assertTrue(edproducer in coll)
2752             self.assertTrue(edfilter in coll)
2753             self.assertTrue(service in coll)
2754             self.assertTrue(essource in coll)
2755             self.assertTrue(esproducer in coll)
2756             self.assertTrue(testTask2 in coll)
2757             self.assertTrue(len(coll) == 6)
2758             self.assertTrue(len(testTask2._collection) == 0)
2759 
2760             taskContents = []
2761             for i in testTask1:
2762                 taskContents.append(i)
2763             self.assertTrue(taskContents == [edproducer, edfilter, essource, service, esproducer, testTask2])
2764 
2765             # test attaching Task to Process
2766             process = Process("test")
2767 
2768             process.mproducer = edproducer
2769             process.mproducer2 = edproducer2
2770             process.mfilter = edfilter
2771             process.messource = essource
2772             process.mesproducer = esproducer
2773             process.d = service
2774 
2775             testTask3 = Task(edproducer, edproducer2)
2776             testTask1.add(testTask3)
2777             process.myTask1 = testTask1
2778 
2779             # test the validation that occurs when attaching a Task to a Process
2780             # first a case that passes, then one the fails on an EDProducer
2781             # then one that fails on a service
2782             l = set()
2783             visitor = NodeNameVisitor(l)
2784             testTask1.visit(visitor)
2785             self.assertTrue(l == set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2786             l2 = testTask1.moduleNames
2787             self.assertTrue(l == set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2788 
2789             testTask4 = Task(edproducer3)
2790             l.clear()
2791             self.assertRaises(RuntimeError, testTask4.visit, visitor)
2792             try:
2793                 process.myTask4 = testTask4
2794                 self.assertTrue(False)
2795             except RuntimeError:
2796                 pass
2797 
2798             testTask5 = Task(service3)
2799             l.clear()
2800             self.assertRaises(RuntimeError, testTask5.visit, visitor)
2801             try:
2802                 process.myTask5 = testTask5
2803                 self.assertTrue(False)
2804             except RuntimeError:
2805                 pass
2806 
2807             process.d = service3
2808             process.myTask5 = testTask5
2809 
2810             # test placement into the Process and the tasks property
2811             expectedDict = { 'myTask1' : testTask1, 'myTask5' : testTask5 }
2812             expectedFixedDict = DictTypes.FixedKeysDict(expectedDict);
2813             self.assertTrue(process.tasks == expectedFixedDict)
2814             self.assertTrue(process.tasks['myTask1'] == testTask1)
2815             self.assertTrue(process.myTask1 == testTask1)
2816 
2817             # test replacing an EDProducer in a Task when calling __settattr__
2818             # for the EDProducer on the Process.
2819             process.mproducer2 = edproducer4
2820             process.d = service
2821             l = list()
2822             visitor1 = ModuleNodeVisitor(l)
2823             testTask1.visit(visitor1)
2824             l.sort(key=lambda mod: mod.__str__())
2825             expectedList = sorted([edproducer,essource,esproducer,service,edfilter,edproducer,edproducer4],key=lambda mod: mod.__str__())
2826             self.assertTrue(expectedList == l)
2827             process.myTask6 = Task()
2828             process.myTask7 = Task()
2829             process.mproducer8 = edproducer8
2830             process.myTask8 = Task(process.mproducer8)
2831             process.myTask6.add(process.myTask7)
2832             process.myTask7.add(process.myTask8)
2833             process.myTask1.add(process.myTask6)
2834             process.myTask8.add(process.myTask5)
2835 
2836             testDict = process._itemsInDependencyOrder(process.tasks)
2837             expectedLabels = ["myTask5", "myTask8", "myTask7", "myTask6", "myTask1"]
2838             expectedTasks = [process.myTask5, process.myTask8, process.myTask7, process.myTask6, process.myTask1]
2839             index = 0
2840             for testLabel, testTask in testDict.items():
2841                 self.assertTrue(testLabel == expectedLabels[index])
2842                 self.assertTrue(testTask == expectedTasks[index])
2843                 index += 1
2844 
2845             pythonDump = testTask1.dumpPython(PrintOptions())
2846 
2847 
2848             expectedPythonDump = 'cms.Task(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer, process.mproducer2, process.myTask6)\n'
2849             self.assertTrue(pythonDump == expectedPythonDump)
2850 
2851             process.myTask5 = Task()
2852             process.myTask100 = Task()
2853             process.mproducer9 = edproducer9
2854             sequence1 = Sequence(process.mproducer8, process.myTask1, process.myTask5, testTask2, testTask3)
2855             sequence2 = Sequence(process.mproducer8 + process.mproducer9)
2856             process.sequence3 = Sequence((process.mproducer8 + process.mfilter))
2857             sequence4 = Sequence()
2858             process.path1 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+sequence4)
2859             process.path1.associate(process.myTask1, process.myTask5, testTask2, testTask3)
2860             process.path11 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+ sequence4,process.myTask1, process.myTask5, testTask2, testTask3, process.myTask100)
2861             process.path2 = Path(process.mproducer)
2862             process.path3 = Path(process.mproducer9+process.mproducer8,testTask2)
2863 
2864             self.assertTrue(process.path1.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)\n')
2865 
2866             self.assertTrue(process.path11.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask100, process.myTask5)\n')
2867 
2868             # test NodeNameVisitor and moduleNames
2869             l = set()
2870             nameVisitor = NodeNameVisitor(l)
2871             process.path1.visit(nameVisitor)
2872             self.assertTrue(l == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
2873             self.assertTrue(process.path1.moduleNames() == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
2874 
2875             # test copy
2876             process.mproducer10 = EDProducer("b10")
2877             process.path21 = process.path11.copy()
2878             process.path21.replace(process.mproducer, process.mproducer10)
2879 
2880             self.assertTrue(process.path11.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer), process.myTask1, process.myTask100, process.myTask5)\n')
2881 
2882             # Some peculiarities of the way things work show up here. dumpPython sorts tasks and
2883             # removes duplication at the level of strings. The Task and Sequence objects themselves
2884             # remove duplicate tasks in their contents if the instances are the same (exact same python
2885             # object id which is not the same as the string representation being the same).
2886             # Also note that the mutating visitor replaces sequences and tasks that have
2887             # modified contents with their modified contents, it does not modify the sequence
2888             # or task itself.
2889             self.assertTrue(process.path21.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.sequence3, cms.Task(), cms.Task(process.None, process.mproducer10), cms.Task(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer10, process.mproducer2, process.mproducer8, process.myTask5), process.myTask100, process.myTask5)\n')
2890 
2891             process.path22 = process.path21.copyAndExclude([process.d, process.mesproducer, process.mfilter])
2892             self.assertTrue(process.path22.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.Task(), cms.Task(process.None, process.mproducer10), cms.Task(process.messource, process.mproducer10, process.mproducer2, process.mproducer8, process.myTask5), process.myTask100, process.myTask5)\n')
2893 
2894             process.path23 = process.path22.copyAndExclude([process.messource, process.mproducer10])
2895             self.assertTrue(process.path23.dumpPython(PrintOptions()) == 'cms.Path(process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.Task(), cms.Task(process.None), cms.Task(process.mproducer2, process.mproducer8, process.myTask5), process.myTask100, process.myTask5)\n')
2896 
2897             process.a = EDAnalyzer("MyAnalyzer")
2898             process.b = OutputModule("MyOutputModule")
2899             process.c = EDFilter("MyFilter")
2900             process.d = EDProducer("MyProducer")
2901             process.e = ESProducer("MyESProducer")
2902             process.f = ESSource("MyESSource")
2903             process.g = ESProducer("g")
2904             process.path24 = Path(process.a+process.b+process.c+process.d)
2905             process.path25 = process.path24.copyAndExclude([process.a,process.b,process.c])
2906             self.assertTrue(process.path25.dumpPython() == 'cms.Path(process.d)\n')
2907             #print process.path3
2908             #print process.dumpPython()
2909 
2910             process.path200 = EndPath(Sequence(process.c,Task(process.e)))
2911             process.path200.replace(process.c,process.b)
2912             process.path200.replace(process.e,process.f)
2913             self.assertEqual(process.path200.dumpPython(), "cms.EndPath(process.b, cms.Task(process.f))\n")
2914             process.path200.replace(process.b,process.c)
2915             process.path200.replace(process.f,process.e)
2916             self.assertEqual(process.path200.dumpPython(), "cms.EndPath(process.c, cms.Task(process.e))\n")
2917             process.path200.replace(process.c,process.a)
2918             process.path200.replace(process.e,process.g)
2919             self.assertEqual(process.path200.dumpPython(), "cms.EndPath(process.a, cms.Task(process.g))\n")
2920             process.path200.replace(process.a,process.c)
2921             process.path200.replace(process.g,process.e)
2922             self.assertEqual(process.path200.dumpPython(), "cms.EndPath(process.c, cms.Task(process.e))\n")
2923 
2924         def testConditionalTask(self):
2925 
2926             # create some objects to use in tests
2927             edanalyzer = EDAnalyzer("a")
2928             edproducer = EDProducer("b")
2929             edproducer2 = EDProducer("b2")
2930             edproducer3 = EDProducer("b3")
2931             edproducer4 = EDProducer("b4")
2932             edproducer8 = EDProducer("b8")
2933             edproducer9 = EDProducer("b9")
2934             edfilter = EDFilter("c")
2935             service = Service("d")
2936             service3 = Service("d", v = untracked.uint32(3))
2937             essource = ESSource("e")
2938             esproducer = ESProducer("f")
2939             testTask2 = Task()
2940             testCTask2 = ConditionalTask()
2941 
2942             # test adding things to Tasks
2943             testTask1 = ConditionalTask(edproducer, edfilter)
2944             self.assertRaises(RuntimeError, testTask1.add, edanalyzer)
2945             testTask1.add(essource, service)
2946             testTask1.add(essource, esproducer)
2947             testTask1.add(testTask2)
2948             testTask1.add(testCTask2)
2949             coll = testTask1._collection
2950             self.assertTrue(edproducer in coll)
2951             self.assertTrue(edfilter in coll)
2952             self.assertTrue(service in coll)
2953             self.assertTrue(essource in coll)
2954             self.assertTrue(esproducer in coll)
2955             self.assertTrue(testTask2 in coll)
2956             self.assertTrue(testCTask2 in coll)
2957             self.assertTrue(len(coll) == 7)
2958             self.assertTrue(len(testTask2._collection) == 0)
2959 
2960             taskContents = []
2961             for i in testTask1:
2962                 taskContents.append(i)
2963             self.assertEqual(taskContents, [edproducer, edfilter, essource, service, esproducer, testTask2, testCTask2])
2964 
2965             # test attaching Task to Process
2966             process = Process("test")
2967 
2968             process.mproducer = edproducer
2969             process.mproducer2 = edproducer2
2970             process.mfilter = edfilter
2971             process.messource = essource
2972             process.mesproducer = esproducer
2973             process.d = service
2974 
2975             testTask3 = ConditionalTask(edproducer, edproducer2)
2976             testTask1.add(testTask3)
2977             process.myTask1 = testTask1
2978 
2979             # test the validation that occurs when attaching a ConditionalTask to a Process
2980             # first a case that passes, then one the fails on an EDProducer
2981             # then one that fails on a service
2982             l = set()
2983             visitor = NodeNameVisitor(l)
2984             testTask1.visit(visitor)
2985             self.assertEqual(l, set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2986             l2 = testTask1.moduleNames()
2987             self.assertEqual(l2, set(['mesproducer', 'mproducer', 'mproducer2', 'mfilter', 'd', 'messource']))
2988 
2989             testTask4 = ConditionalTask(edproducer3)
2990             l.clear()
2991             self.assertRaises(RuntimeError, testTask4.visit, visitor)
2992             try:
2993                 process.myTask4 = testTask4
2994                 self.assertTrue(False)
2995             except RuntimeError:
2996                 pass
2997 
2998             testTask5 = ConditionalTask(service3)
2999             l.clear()
3000             self.assertRaises(RuntimeError, testTask5.visit, visitor)
3001             try:
3002                 process.myTask5 = testTask5
3003                 self.assertTrue(False)
3004             except RuntimeError:
3005                 pass
3006 
3007             process.d = service3
3008             process.myTask5 = testTask5
3009 
3010             # test placement into the Process and the tasks property
3011             expectedDict = { 'myTask1' : testTask1, 'myTask5' : testTask5 }
3012             expectedFixedDict = DictTypes.FixedKeysDict(expectedDict);
3013             self.assertEqual(process.conditionaltasks, expectedFixedDict)
3014             self.assertEqual(process.conditionaltasks['myTask1'], testTask1)
3015             self.assertEqual(process.myTask1, testTask1)
3016 
3017             # test replacing an EDProducer in a ConditionalTask when calling __settattr__
3018             # for the EDProducer on the Process.
3019             process.mproducer2 = edproducer4
3020             process.d = service
3021             l = list()
3022             visitor1 = ModuleNodeVisitor(l)
3023             testTask1.visit(visitor1)
3024             l.sort(key=lambda mod: mod.__str__())
3025             expectedList = sorted([edproducer,essource,esproducer,service,edfilter,edproducer,edproducer4],key=lambda mod: mod.__str__())
3026             self.assertEqual(expectedList, l)
3027             process.myTask6 = ConditionalTask()
3028             process.myTask7 = ConditionalTask()
3029             process.mproducer8 = edproducer8
3030             process.myTask8 = ConditionalTask(process.mproducer8)
3031             process.myTask6.add(process.myTask7)
3032             process.myTask7.add(process.myTask8)
3033             process.myTask1.add(process.myTask6)
3034             process.myTask8.add(process.myTask5)
3035             self.assertEqual(process.myTask8.dumpPython(), "cms.ConditionalTask(process.mproducer8, process.myTask5)\n")
3036 
3037             testDict = process._itemsInDependencyOrder(process.conditionaltasks)
3038             expectedLabels = ["myTask5", "myTask8", "myTask7", "myTask6", "myTask1"]
3039             expectedTasks = [process.myTask5, process.myTask8, process.myTask7, process.myTask6, process.myTask1]
3040             index = 0
3041             for testLabel, testTask in testDict.items():
3042                 self.assertEqual(testLabel, expectedLabels[index])
3043                 self.assertEqual(testTask, expectedTasks[index])
3044                 index += 1
3045 
3046             pythonDump = testTask1.dumpPython(PrintOptions())
3047 
3048 
3049             expectedPythonDump = 'cms.ConditionalTask(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer, process.mproducer2, process.myTask6)\n'
3050             self.assertEqual(pythonDump, expectedPythonDump)
3051 
3052             process.myTask5 = ConditionalTask()
3053             self.assertEqual(process.myTask8.dumpPython(), "cms.ConditionalTask(process.mproducer8, process.myTask5)\n")
3054             process.myTask100 = ConditionalTask()
3055             process.mproducer9 = edproducer9
3056             sequence1 = Sequence(process.mproducer8, process.myTask1, process.myTask5, testTask2, testTask3)
3057             sequence2 = Sequence(process.mproducer8 + process.mproducer9)
3058             process.sequence3 = Sequence((process.mproducer8 + process.mfilter))
3059             sequence4 = Sequence()
3060             process.path1 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+sequence4)
3061             process.path1.associate(process.myTask1, process.myTask5, testTask2, testTask3)
3062             process.path11 = Path(process.mproducer+process.mproducer8+sequence1+sequence2+process.sequence3+ sequence4,process.myTask1, process.myTask5, testTask2, testTask3, process.myTask100)
3063             process.path2 = Path(process.mproducer)
3064             process.path3 = Path(process.mproducer9+process.mproducer8,testTask2)
3065 
3066             self.assertEqual(process.path1.dumpPython(PrintOptions()), 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask5)\n')
3067 
3068             self.assertEqual(process.path11.dumpPython(PrintOptions()), 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask100, process.myTask5)\n')
3069 
3070             # test NodeNameVisitor and moduleNames
3071             l = set()
3072             nameVisitor = NodeNameVisitor(l)
3073             process.path1.visit(nameVisitor)
3074             self.assertTrue(l == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
3075             self.assertTrue(process.path1.moduleNames() == set(['mproducer', 'd', 'mesproducer', None, 'mproducer9', 'mproducer8', 'messource', 'mproducer2', 'mfilter']))
3076 
3077             # test copy
3078             process.mproducer10 = EDProducer("b10")
3079             process.path21 = process.path11.copy()
3080             process.path21.replace(process.mproducer, process.mproducer10)
3081 
3082             self.assertEqual(process.path11.dumpPython(PrintOptions()), 'cms.Path(process.mproducer+process.mproducer8+cms.Sequence(process.mproducer8, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask5)+(process.mproducer8+process.mproducer9)+process.sequence3, cms.ConditionalTask(process.None, process.mproducer), cms.Task(), process.myTask1, process.myTask100, process.myTask5)\n')
3083 
3084             # Some peculiarities of the way things work show up here. dumpPython sorts tasks and
3085             # removes duplication at the level of strings. The Task and Sequence objects themselves
3086             # remove duplicate tasks in their contents if the instances are the same (exact same python
3087             # object id which is not the same as the string representation being the same).
3088             # Also note that the mutating visitor replaces sequences and tasks that have
3089             # modified contents with their modified contents, it does not modify the sequence
3090             # or task itself.
3091             self.assertEqual(process.path21.dumpPython(PrintOptions()), 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.sequence3, cms.ConditionalTask(process.None, process.mproducer10), cms.ConditionalTask(process.d, process.mesproducer, process.messource, process.mfilter, process.mproducer10, process.mproducer2, process.mproducer8, process.myTask5), cms.Task(), process.myTask100, process.myTask5)\n')
3092 
3093             process.path22 = process.path21.copyAndExclude([process.d, process.mesproducer, process.mfilter])
3094             self.assertEqual(process.path22.dumpPython(PrintOptions()), 'cms.Path(process.mproducer10+process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.ConditionalTask(process.None, process.mproducer10), cms.ConditionalTask(process.messource, process.mproducer10, process.mproducer2, process.mproducer8, process.myTask5), cms.Task(), process.myTask100, process.myTask5)\n')
3095 
3096             process.path23 = process.path22.copyAndExclude([process.messource, process.mproducer10])
3097             self.assertEqual(process.path23.dumpPython(PrintOptions()), 'cms.Path(process.mproducer8+process.mproducer8+(process.mproducer8+process.mproducer9)+process.mproducer8, cms.ConditionalTask(process.None), cms.ConditionalTask(process.mproducer2, process.mproducer8, process.myTask5), cms.Task(), process.myTask100, process.myTask5)\n')
3098 
3099             process = Process("Test")
3100 
3101             process.b = EDProducer("b")
3102             process.b2 = EDProducer("b2")
3103             process.b3 = EDProducer("b3")
3104             process.p = Path(process.b, ConditionalTask(process.b3, process.b2))
3105             p = TestMakePSet()
3106             process.fillProcessDesc(p)
3107             self.assertEqual(p.values["@all_modules"], (True, ['b', 'b2', 'b3']))
3108             self.assertEqual(p.values["@paths"], (True, ['p']))
3109             self.assertEqual(p.values["p"], (True, ['b','#','b2','b3','@']))
3110             
3111 
3112         def testPath(self):
3113             p = Process("test")
3114             p.a = EDAnalyzer("MyAnalyzer")
3115             p.b = EDAnalyzer("YourAnalyzer")
3116             p.c = EDAnalyzer("OurAnalyzer")
3117             path = Path(p.a)
3118             path *= p.b
3119             path += p.c
3120             self.assertEqual(str(path),'a+b+c')
3121             path = Path(p.a*p.b+p.c)
3122             self.assertEqual(str(path),'a+b+c')
3123 #            path = Path(p.a)*p.b+p.c #This leads to problems with sequences
3124 #            self.assertEqual(str(path),'((a*b)+c)')
3125             path = Path(p.a+ p.b*p.c)
3126             self.assertEqual(str(path),'a+b+c')
3127             path = Path(p.a*(p.b+p.c))
3128             self.assertEqual(str(path),'a+b+c')
3129             path = Path(p.a*(p.b+~p.c))
3130             pathx = Path(p.a*(p.b+ignore(p.c)))
3131             self.assertEqual(str(path),'a+b+~c')
3132             p.es = ESProducer("AnESProducer")
3133             self.assertRaises(TypeError,Path,p.es)
3134 
3135             t = Path()
3136             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path()\n')
3137 
3138             t = Path(p.a)
3139             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(process.a)\n')
3140 
3141             t = Path(Task())
3142             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(cms.Task())\n')
3143 
3144             t = Path(p.a, Task())
3145             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(process.a, cms.Task())\n')
3146 
3147             p.prod = EDProducer("prodName")
3148             p.t1 = Task(p.prod)
3149             t = Path(p.a, p.t1, Task(), p.t1)
3150             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(process.a, cms.Task(), process.t1)\n')
3151 
3152             t = Path(ConditionalTask())
3153             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(cms.ConditionalTask())\n')
3154 
3155             t = Path(p.a, ConditionalTask())
3156             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(process.a, cms.ConditionalTask())\n')
3157 
3158             p.prod = EDProducer("prodName")
3159             p.t1 = ConditionalTask(p.prod)
3160             t = Path(p.a, p.t1, Task(), p.t1)
3161             self.assertEqual(t.dumpPython(PrintOptions()), 'cms.Path(process.a, cms.Task(), process.t1)\n')
3162 
3163         def testCloneSequence(self):
3164             p = Process("test")
3165             a = EDAnalyzer("MyAnalyzer")
3166             p.a = a
3167             a.setLabel("a")
3168             b = EDAnalyzer("YOurAnalyzer")
3169             p.b = b
3170             b.setLabel("b")
3171             path = Path(a * b)
3172             p.path = Path(p.a*p.b)
3173             lookuptable = {id(a): p.a, id(b): p.b}
3174             #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
3175             #lookuptable = p._cloneToObjectDict
3176             #self.assertEqual(str(path),str(path._postProcessFixup(lookuptable)))
3177             self.assertEqual(str(path),str(p.path))
3178 
3179         def testContains(self):
3180 
3181             a = EDProducer("a")
3182             b = EDProducer("b")
3183             c = EDProducer("c")
3184             d = EDProducer("d")
3185             e = EDProducer("e")
3186             f = EDProducer("f")
3187             g = EDProducer("g")
3188             h = EDProducer("h")
3189             i = EDProducer("i")
3190             j = EDProducer("j")
3191             k = EDProducer("k")
3192             l = EDProducer("l")
3193             m = EDProducer("m")
3194             n = EDProducer("n")
3195 
3196             seq1 = Sequence(e)
3197             task1 = Task(g)
3198             ctask1 = ConditionalTask(h)
3199             path = Path(a * c * seq1, task1, ctask1)
3200 
3201             self.assertTrue(path.contains(a))
3202             self.assertFalse(path.contains(b))
3203             self.assertTrue(path.contains(c))
3204             self.assertFalse(path.contains(d))
3205             self.assertTrue(path.contains(e))
3206             self.assertFalse(path.contains(f))
3207             self.assertTrue(path.contains(g))
3208             self.assertTrue(path.contains(h))
3209 
3210             endpath = EndPath(h * i)
3211             self.assertFalse(endpath.contains(b))
3212             self.assertTrue(endpath.contains(i))
3213 
3214             seq = Sequence(a * c)
3215             self.assertFalse(seq.contains(b))
3216             self.assertTrue(seq.contains(c))
3217 
3218             task2 = Task(l)
3219             task = Task(j, k, task2)
3220             self.assertFalse(task.contains(b))
3221             self.assertTrue(task.contains(j))
3222             self.assertTrue(task.contains(k))
3223             self.assertTrue(task.contains(l))
3224 
3225             task3 = Task(m)
3226             path2 = Path(n)
3227             sch = Schedule(path, path2, tasks=[task,task3])
3228             self.assertFalse(sch.contains(b))
3229             self.assertTrue(sch.contains(a))
3230             self.assertTrue(sch.contains(c))
3231             self.assertTrue(sch.contains(e))
3232             self.assertTrue(sch.contains(g))
3233             self.assertTrue(sch.contains(n))
3234             self.assertTrue(sch.contains(j))
3235             self.assertTrue(sch.contains(k))
3236             self.assertTrue(sch.contains(l))
3237             self.assertTrue(sch.contains(m))
3238 
3239             ctask2 = ConditionalTask(l, task1)
3240             ctask = ConditionalTask(j, k, ctask2)
3241             self.assertFalse(ctask.contains(b))
3242             self.assertTrue(ctask.contains(j))
3243             self.assertTrue(ctask.contains(k))
3244             self.assertTrue(ctask.contains(l))
3245             self.assertTrue(ctask.contains(g))
3246 
3247         def testSchedule(self):
3248             p = Process("test")
3249             p.a = EDAnalyzer("MyAnalyzer")
3250             p.b = EDAnalyzer("YourAnalyzer")
3251             p.c = EDAnalyzer("OurAnalyzer")
3252             p.d = EDAnalyzer("OurAnalyzer")
3253             p.path1 = Path(p.a)
3254             p.path2 = Path(p.b)
3255             p.path3 = Path(p.d)
3256 
3257             s = Schedule(p.path1,p.path2)
3258             self.assertEqual(s[0],p.path1)
3259             self.assertEqual(s[1],p.path2)
3260             p.schedule = s
3261             self.assertTrue('b' in p.schedule.moduleNames())
3262             self.assertTrue(hasattr(p, 'b'))
3263             self.assertTrue(hasattr(p, 'c'))
3264             self.assertTrue(hasattr(p, 'd'))
3265             self.assertTrue(hasattr(p, 'path1'))
3266             self.assertTrue(hasattr(p, 'path2'))
3267             self.assertTrue(hasattr(p, 'path3'))
3268             p.prune()
3269             self.assertTrue('b' in p.schedule.moduleNames())
3270             self.assertTrue(hasattr(p, 'b'))
3271             self.assertTrue(not hasattr(p, 'c'))
3272             self.assertTrue(not hasattr(p, 'd'))
3273             self.assertTrue(hasattr(p, 'path1'))
3274             self.assertTrue(hasattr(p, 'path2'))
3275             self.assertTrue(not hasattr(p, 'path3'))
3276 
3277             self.assertTrue(len(p.schedule._tasks) == 0)
3278 
3279             p = Process("test")
3280             p.a = EDAnalyzer("MyAnalyzer")
3281             p.b = EDAnalyzer("YourAnalyzer")
3282             p.c = EDAnalyzer("OurAnalyzer")
3283             p.d = EDAnalyzer("dAnalyzer")
3284             p.e = EDProducer("eProducer")
3285             p.f = EDProducer("fProducer")
3286             p.Tracer = Service("Tracer")
3287             p.path1 = Path(p.a)
3288             p.path2 = Path(p.b)
3289             p.path3 = Path(p.d)
3290             p.task1 = Task(p.e)
3291             p.task2 = Task(p.f, p.Tracer)
3292             s = Schedule(p.path1,p.path2,tasks=[p.task1,p.task2,p.task1])
3293             self.assertEqual(s[0],p.path1)
3294             self.assertEqual(s[1],p.path2)
3295             self.assertTrue(len(s._tasks) == 2)
3296             self.assertTrue(p.task1 in s._tasks)
3297             self.assertTrue(p.task2 in s._tasks)
3298             listOfTasks = list(s._tasks)
3299             self.assertTrue(len(listOfTasks) == 2)
3300             self.assertTrue(p.task1 == listOfTasks[0])
3301             self.assertTrue(p.task2 == listOfTasks[1])
3302             p.schedule = s
3303             self.assertTrue('b' in p.schedule.moduleNames())
3304 
3305             process2 = Process("test")
3306             process2.a = EDAnalyzer("MyAnalyzer")
3307             process2.e = EDProducer("eProducer")
3308             process2.path1 = Path(process2.a)
3309             process2.task1 = Task(process2.e)
3310             process2.schedule = Schedule(process2.path1,tasks=process2.task1)
3311             listOfTasks = list(process2.schedule._tasks)
3312             self.assertTrue(listOfTasks[0] == process2.task1)
3313 
3314             # test Schedule copy
3315             s2 = s.copy()
3316             self.assertEqual(s2[0],p.path1)
3317             self.assertEqual(s2[1],p.path2)
3318             self.assertTrue(len(s2._tasks) == 2)
3319             self.assertTrue(p.task1 in s2._tasks)
3320             self.assertTrue(p.task2 in s2._tasks)
3321             listOfTasks = list(s2._tasks)
3322             self.assertTrue(len(listOfTasks) == 2)
3323             self.assertTrue(p.task1 == listOfTasks[0])
3324             self.assertTrue(p.task2 == listOfTasks[1])
3325 
3326             names = s.moduleNames()
3327             self.assertTrue(names == set(['a', 'b', 'e', 'Tracer', 'f']))
3328             #adding a path not attached to the Process should cause an exception
3329             p = Process("test")
3330             p.a = EDAnalyzer("MyAnalyzer")
3331             path1 = Path(p.a)
3332             s = Schedule(path1)
3333             self.assertRaises(RuntimeError, lambda : p.setSchedule_(s) )
3334 
3335             #make sure anonymous sequences work
3336             p = Process("test")
3337             p.a = EDAnalyzer("MyAnalyzer")
3338             p.b = EDAnalyzer("MyOtherAnalyzer")
3339             p.c = EDProducer("MyProd")
3340             path1 = Path(p.c*Sequence(p.a+p.b))
3341             s = Schedule(path1)
3342             self.assertTrue('a' in s.moduleNames())
3343             self.assertTrue('b' in s.moduleNames())
3344             self.assertTrue('c' in s.moduleNames())
3345             p.path1 = path1
3346             p.schedule = s
3347             p.prune()
3348             self.assertTrue('a' in s.moduleNames())
3349             self.assertTrue('b' in s.moduleNames())
3350             self.assertTrue('c' in s.moduleNames())
3351 
3352         def testImplicitSchedule(self):
3353             p = Process("test")
3354             p.a = EDAnalyzer("MyAnalyzer")
3355             p.b = EDAnalyzer("YourAnalyzer")
3356             p.c = EDAnalyzer("OurAnalyzer")
3357             p.path1 = Path(p.a)
3358             p.path2 = Path(p.b)
3359             self.assertTrue(p.schedule is None)
3360             pths = p.paths
3361             keys = pths.keys()
3362             self.assertEqual(pths[keys[0]],p.path1)
3363             self.assertEqual(pths[keys[1]],p.path2)
3364             p.prune()
3365             self.assertTrue(hasattr(p, 'a'))
3366             self.assertTrue(hasattr(p, 'b'))
3367             self.assertTrue(not hasattr(p, 'c'))
3368             self.assertTrue(hasattr(p, 'path1'))
3369             self.assertTrue(hasattr(p, 'path2'))
3370 
3371 
3372             p = Process("test")
3373             p.a = EDAnalyzer("MyAnalyzer")
3374             p.b = EDAnalyzer("YourAnalyzer")
3375             p.c = EDAnalyzer("OurAnalyzer")
3376             p.path2 = Path(p.b)
3377             p.path1 = Path(p.a)
3378             self.assertTrue(p.schedule is None)
3379             pths = p.paths
3380             keys = pths.keys()
3381             self.assertEqual(pths[keys[1]],p.path1)
3382             self.assertEqual(pths[keys[0]],p.path2)
3383 
3384 
3385         def testUsing(self):
3386             p = Process('test')
3387             p.block = PSet(a = int32(1))
3388             p.modu = EDAnalyzer('Analyzer', p.block, b = int32(2))
3389             self.assertEqual(p.modu.a.value(),1)
3390             self.assertEqual(p.modu.b.value(),2)
3391 
3392         def testOverride(self):
3393             p = Process('test')
3394             a = EDProducer("A", a1=int32(0))
3395             self.assertTrue(not a.isModified())
3396             a.a1 = 1
3397             self.assertTrue(a.isModified())
3398             p.a = a
3399             self.assertEqual(p.a.a1.value(), 1)
3400             # try adding an unmodified module.
3401             # should accept it
3402             p.a = EDProducer("A", a1=int32(2))
3403             self.assertEqual(p.a.a1.value(), 2)
3404             # try adding a modified module.  Should throw
3405             # no longer, since the same (modified) say, geometry
3406             # could come from more than one cff
3407             b = EDProducer("A", a1=int32(3))
3408             b.a1 = 4
3409             #self.assertRaises(RuntimeError, setattr, *(p,'a',b))
3410             ps1 = PSet(a = int32(1))
3411             ps2 = PSet(a = int32(2))
3412             self.assertRaises(ValueError, EDProducer, 'C', ps1, ps2)
3413             self.assertRaises(ValueError, EDProducer, 'C', ps1, a=int32(3))
3414         
3415         def testOptions(self):
3416             p = Process('test')
3417             self.assertEqual(p.options.numberOfThreads.value(),1)
3418             p.options.numberOfThreads = 8
3419             self.assertEqual(p.options.numberOfThreads.value(),8)
3420             p.options = PSet()
3421             self.assertEqual(p.options.numberOfThreads.value(),1)
3422             p.options = dict(numberOfStreams =2,
3423                              numberOfThreads =2)
3424             self.assertEqual(p.options.numberOfThreads.value(),2)
3425             self.assertEqual(p.options.numberOfStreams.value(),2)
3426             del p.options
3427             self.assertRaises(TypeError, setattr, p, 'options', untracked.PSet(numberOfThreads = int32(-1)))
3428             p.options = untracked.PSet(numberOfThreads = untracked.uint32(4))
3429             self.assertEqual(p.options.numberOfThreads.value(), 4)
3430 
3431         def testMaxEvents(self):
3432             p = Process("Test")
3433             p.maxEvents.input = 10
3434             self.assertEqual(p.maxEvents.input.value(),10)
3435             p = Process("Test")
3436             p.maxEvents.output = 10
3437             self.assertEqual(p.maxEvents.output.value(),10)
3438             p = Process("Test")
3439             p.maxEvents.output = PSet(out=untracked.int32(10))
3440             self.assertEqual(p.maxEvents.output.out.value(), 10)
3441             p = Process("Test")
3442             p.maxEvents = untracked.PSet(input = untracked.int32(5))
3443             self.assertEqual(p.maxEvents.input.value(), 5)
3444             del p.maxEvents
3445             self.assertRaises(TypeError, setattr, p, 'maxEvents', untracked.PSet(input = untracked.uint32(1)))
3446             p.maxEvents = untracked.PSet(input = untracked.int32(1))
3447             self.assertEqual(p.maxEvents.input.value(), 1)
3448         
3449         def testExamples(self):
3450             p = Process("Test")
3451             p.source = Source("PoolSource",fileNames = untracked(string("file:reco.root")))
3452             p.foos = EDProducer("FooProducer")
3453             p.bars = EDProducer("BarProducer", foos=InputTag("foos"))
3454             p.out = OutputModule("PoolOutputModule",fileName=untracked(string("file:foos.root")))
3455             p.bars.foos = 'Foosball'
3456             self.assertEqual(p.bars.foos, InputTag('Foosball'))
3457             p.p = Path(p.foos*p.bars)
3458             p.e = EndPath(p.out)
3459             p.add_(Service("MessageLogger"))
3460 
3461         def testPrefers(self):
3462             p = Process("Test")
3463             p.add_(ESSource("ForceSource"))
3464             p.juicer = ESProducer("JuicerProducer")
3465             p.prefer("ForceSource")
3466             p.prefer("juicer")
3467             self.assertEqual(_lineDiff(p.dumpPython(), Process('Test').dumpPython()),
3468 """process.juicer = cms.ESProducer("JuicerProducer")
3469 process.ForceSource = cms.ESSource("ForceSource")
3470 process.prefer("ForceSource")
3471 process.prefer("juicer")""")
3472             p.prefer("juicer",fooRcd=vstring("Foo"))
3473             self.assertEqual(_lineDiff(p.dumpPython(), Process('Test').dumpPython()),
3474 """process.juicer = cms.ESProducer("JuicerProducer")
3475 process.ForceSource = cms.ESSource("ForceSource")
3476 process.prefer("ForceSource")
3477 process.prefer("juicer",
3478     fooRcd = cms.vstring('Foo')
3479 )""")
3480 
3481         def testFreeze(self):
3482             process = Process("Freeze")
3483             m = EDProducer("M", p=PSet(i = int32(1)))
3484             m.p.i = 2
3485             process.m = m
3486             # should be frozen
3487             #self.assertRaises(ValueError, setattr, m.p, 'i', 3)
3488             #self.assertRaises(ValueError, setattr, m, 'p', PSet(i=int32(1)))
3489             #self.assertRaises(ValueError, setattr, m.p, 'j', 1)
3490             #self.assertRaises(ValueError, setattr, m, 'j', 1)
3491             # But OK to change through the process
3492             process.m.p.i = 4
3493             self.assertEqual(process.m.p.i.value(), 4)
3494             process.m.p = PSet(j=int32(1))
3495             # should work to clone it, though
3496             m2 = m.clone(p = PSet(i = int32(5)), j = int32(8))
3497             m2.p.i = 6
3498             m2.j = 8
3499         def testRefToPSet(self):
3500             proc = Process("test")
3501             proc.top = PSet(a = int32(1))
3502             proc.ref = PSet(refToPSet_ = string("top"))
3503             proc.ref2 = PSet( a = int32(1), b = PSet( refToPSet_ = string("top")))
3504             proc.ref3 = PSet(refToPSet_ = string("ref"))
3505             proc.ref4 = VPSet(PSet(refToPSet_ = string("top")),
3506                               PSet(refToPSet_ = string("ref2")))
3507             p = TestMakePSet()
3508             proc.fillProcessDesc(p)
3509             self.assertEqual((True,1),p.values["ref"][1].values["a"])
3510             self.assertEqual((True,1),p.values["ref3"][1].values["a"])
3511             self.assertEqual((True,1),p.values["ref2"][1].values["a"])
3512             self.assertEqual((True,1),p.values["ref2"][1].values["b"][1].values["a"])
3513             self.assertEqual((True,1),p.values["ref4"][1][0].values["a"])
3514             self.assertEqual((True,1),p.values["ref4"][1][1].values["a"])
3515         def testSwitchProducer(self):
3516             proc = Process("test")
3517             proc.sp = SwitchProducerTest(test2 = EDProducer("Foo",
3518                                                             a = int32(1),
3519                                                             b = PSet(c = int32(2))),
3520                                          test1 = EDProducer("Bar",
3521                                                             aa = int32(11),
3522                                                             bb = PSet(cc = int32(12))))
3523             self.assertEqual(proc.sp.label_(), "sp")
3524             self.assertEqual(proc.sp.test1.label_(), "sp@test1")
3525             self.assertEqual(proc.sp.test2.label_(), "sp@test2")
3526 
3527             proc.a = EDProducer("A")
3528             proc.s = Sequence(proc.a + proc.sp)
3529             proc.t = Task(proc.a, proc.sp)
3530             proc.p = Path()
3531             proc.p.associate(proc.t)
3532             p = TestMakePSet()
3533             proc.fillProcessDesc(p)
3534             self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
3535             self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
3536             self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
3537             all_cases = copy.deepcopy(p.values["sp"][1].values["@all_cases"])
3538             all_cases[1].sort() # names of all cases come via dict, i.e. their order is undefined
3539             self.assertEqual((True, ["sp@test1", "sp@test2"]), all_cases)
3540             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
3541             self.assertEqual(["a", "sp", "sp@test1", "sp@test2"], p.values["@all_modules"][1])
3542             self.assertEqual((True,"EDProducer"), p.values["sp@test1"][1].values["@module_edm_type"])
3543             self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["@module_type"])
3544             self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"])
3545             self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"])
3546             dump = proc.dumpPython()
3547             self.assertEqual(dump.find('@'), -1)
3548             self.assertEqual(specialImportRegistry.getSpecialImports(), ["from test import SwitchProducerTest"])
3549             self.assertTrue(dump.find("\nfrom test import SwitchProducerTest\n") != -1)
3550 
3551             # EDAlias as non-chosen case
3552             proc = Process("test")
3553             proc.sp = SwitchProducerTest(test2 = EDProducer("Foo",
3554                                                             a = int32(1),
3555                                                             b = PSet(c = int32(2))),
3556                                          test1 = EDAlias(a = VPSet(PSet(type = string("Bar")))))
3557             proc.a = EDProducer("A")
3558             proc.s = Sequence(proc.a + proc.sp)
3559             proc.t = Task(proc.a, proc.sp)
3560             proc.p = Path()
3561             proc.p.associate(proc.t)
3562             p = TestMakePSet()
3563             proc.fillProcessDesc(p)
3564             self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
3565             self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
3566             self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
3567             all_cases = copy.deepcopy(p.values["sp"][1].values["@all_cases"])
3568             all_cases[1].sort()
3569             self.assertEqual((True, ["sp@test1", "sp@test2"]), all_cases)
3570             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
3571             self.assertEqual(["a", "sp", "sp@test2"], p.values["@all_modules"][1])
3572             self.assertEqual(["sp@test1"], p.values["@all_aliases"][1])
3573             self.assertEqual((True,"EDProducer"), p.values["sp@test2"][1].values["@module_edm_type"])
3574             self.assertEqual((True,"Foo"), p.values["sp@test2"][1].values["@module_type"])
3575             self.assertEqual((True,"EDAlias"), p.values["sp@test1"][1].values["@module_edm_type"])
3576             self.assertEqual((True,"Bar"), p.values["sp@test1"][1].values["a"][1][0].values["type"])
3577 
3578             # EDAlias as chosen case
3579             proc = Process("test")
3580             proc.sp = SwitchProducerTest(test1 = EDProducer("Foo",
3581                                                             a = int32(1),
3582                                                             b = PSet(c = int32(2))),
3583                                          test2 = EDAlias(a = VPSet(PSet(type = string("Bar")))))
3584             proc.a = EDProducer("A")
3585             proc.s = Sequence(proc.a + proc.sp)
3586             proc.t = Task(proc.a, proc.sp)
3587             proc.p = Path()
3588             proc.p.associate(proc.t)
3589             p = TestMakePSet()
3590             proc.fillProcessDesc(p)
3591             self.assertEqual((True,"EDProducer"), p.values["sp"][1].values["@module_edm_type"])
3592             self.assertEqual((True, "SwitchProducer"), p.values["sp"][1].values["@module_type"])
3593             self.assertEqual((True, "sp"), p.values["sp"][1].values["@module_label"])
3594             self.assertEqual((True, ["sp@test1", "sp@test2"]), p.values["sp"][1].values["@all_cases"])
3595             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
3596             self.assertEqual(["a", "sp", "sp@test1"], p.values["@all_modules"][1])
3597             self.assertEqual(["sp@test2"], p.values["@all_aliases"][1])
3598             self.assertEqual((True,"EDProducer"), p.values["sp@test1"][1].values["@module_edm_type"])
3599             self.assertEqual((True,"Foo"), p.values["sp@test1"][1].values["@module_type"])
3600             self.assertEqual((True,"EDAlias"), p.values["sp@test2"][1].values["@module_edm_type"])
3601             self.assertEqual((True,"Bar"), p.values["sp@test2"][1].values["a"][1][0].values["type"])
3602 
3603             # ConditionalTask
3604             proc = Process("test")
3605             proc.spct = SwitchProducerTest(test2 = EDProducer("Foo",
3606                                                               a = int32(1),
3607                                                               b = PSet(c = int32(2))),
3608                                            test1 = EDProducer("Bar",
3609                                                               aa = int32(11),
3610                                                               bb = PSet(cc = int32(12))),
3611                                            test3 = EDAlias(a = VPSet(PSet(type = string("Bar")))))
3612             proc.spp = proc.spct.clone()
3613             proc.a = EDProducer("A")
3614             proc.ct = ConditionalTask(proc.spct)
3615             proc.p = Path(proc.a, proc.ct)
3616             proc.pp = Path(proc.a + proc.spp)
3617             p = TestMakePSet()
3618             proc.fillProcessDesc(p)
3619             self.assertEqual(["a", "spct", "spct@test1", "spct@test2", "spp", "spp@test1", "spp@test2"], p.values["@all_modules"][1])
3620             self.assertEqual(["a", "#", "spct", "spct@test1", "spct@test2", "@"], p.values["p"][1])
3621             self.assertEqual(["a", "spp", "#", "spp@test1", "spp@test2", "@"], p.values["pp"][1])
3622 
3623         def testPrune(self):
3624             p = Process("test")
3625             p.a = EDAnalyzer("MyAnalyzer")
3626             p.b = EDAnalyzer("YourAnalyzer")
3627             p.c = EDAnalyzer("OurAnalyzer")
3628             p.d = EDAnalyzer("OurAnalyzer")
3629             p.e = EDProducer("MyProducer")
3630             p.f = EDProducer("YourProducer")
3631             p.g = EDProducer("TheirProducer")
3632             p.h = EDProducer("OnesProducer")
3633             p.s = Sequence(p.d)
3634             p.t1 = Task(p.e)
3635             p.t2 = Task(p.f)
3636             p.t3 = Task(p.g, p.t1)
3637             p.ct1 = ConditionalTask(p.h)
3638             p.ct2 = ConditionalTask(p.f)
3639             p.ct3 = ConditionalTask(p.ct1)
3640             p.path1 = Path(p.a, p.t3, p.ct3)
3641             p.path2 = Path(p.b)
3642             self.assertTrue(p.schedule is None)
3643             pths = p.paths
3644             keys = pths.keys()
3645             self.assertEqual(pths[keys[0]],p.path1)
3646             self.assertEqual(pths[keys[1]],p.path2)
3647             p.pset1 = PSet(parA = string("pset1"))
3648             p.pset2 = untracked.PSet(parA = string("pset2"))
3649             p.vpset1 = VPSet()
3650             p.vpset2 = untracked.VPSet()
3651             p.prune()
3652             self.assertTrue(hasattr(p, 'a'))
3653             self.assertTrue(hasattr(p, 'b'))
3654             self.assertTrue(not hasattr(p, 'c'))
3655             self.assertTrue(not hasattr(p, 'd'))
3656             self.assertTrue(hasattr(p, 'e'))
3657             self.assertTrue(not hasattr(p, 'f'))
3658             self.assertTrue(hasattr(p, 'g'))
3659             self.assertTrue(hasattr(p, 'h'))
3660             self.assertTrue(not hasattr(p, 's'))
3661             self.assertTrue(hasattr(p, 't1'))
3662             self.assertTrue(not hasattr(p, 't2'))
3663             self.assertTrue(hasattr(p, 't3'))
3664             self.assertTrue(hasattr(p, 'path1'))
3665             self.assertTrue(hasattr(p, 'path2'))
3666 #            self.assertTrue(not hasattr(p, 'pset1'))
3667 #            self.assertTrue(hasattr(p, 'pset2'))
3668 #            self.assertTrue(not hasattr(p, 'vpset1'))
3669 #            self.assertTrue(not hasattr(p, 'vpset2'))
3670 
3671             p = Process("test")
3672             p.a = EDAnalyzer("MyAnalyzer")
3673             p.b = EDAnalyzer("YourAnalyzer")
3674             p.c = EDAnalyzer("OurAnalyzer")
3675             p.d = EDAnalyzer("OurAnalyzer")
3676             p.e = EDAnalyzer("OurAnalyzer")
3677             p.f = EDProducer("MyProducer")
3678             p.g = EDProducer("YourProducer")
3679             p.h = EDProducer("TheirProducer")
3680             p.i = EDProducer("OurProducer")
3681             p.j = EDProducer("OurProducer")
3682             p.k = EDProducer("OurProducer")
3683             p.l = EDProducer("OurProducer")
3684             p.t1 = Task(p.f)
3685             p.t2 = Task(p.g)
3686             p.t3 = Task(p.h)
3687             p.t4 = Task(p.i)
3688             p.ct1 = Task(p.f)
3689             p.ct2 = Task(p.j)
3690             p.ct3 = Task(p.k)
3691             p.ct4 = Task(p.l)
3692             p.s = Sequence(p.d, p.t1, p.ct1)
3693             p.s2 = Sequence(p.b, p.t2, p.ct2)
3694             p.s3 = Sequence(p.e)
3695             p.path1 = Path(p.a, p.t3, p.ct3)
3696             p.path2 = Path(p.b)
3697             p.path3 = Path(p.b+p.s2)
3698             p.path4 = Path(p.b+p.s3)
3699             p.schedule = Schedule(p.path1,p.path2,p.path3)
3700             p.schedule.associate(p.t4)
3701             pths = p.paths
3702             keys = pths.keys()
3703             self.assertEqual(pths[keys[0]],p.path1)
3704             self.assertEqual(pths[keys[1]],p.path2)
3705             p.prune()
3706             self.assertTrue(hasattr(p, 'a'))
3707             self.assertTrue(hasattr(p, 'b'))
3708             self.assertTrue(not hasattr(p, 'c'))
3709             self.assertTrue(not hasattr(p, 'd'))
3710             self.assertTrue(not hasattr(p, 'e'))
3711             self.assertTrue(not hasattr(p, 'f'))
3712             self.assertTrue(hasattr(p, 'g'))
3713             self.assertTrue(hasattr(p, 'h'))
3714             self.assertTrue(hasattr(p, 'i'))
3715             self.assertTrue(hasattr(p, 'j'))
3716             self.assertTrue(hasattr(p, 'k'))
3717             self.assertTrue(not hasattr(p, 'l'))
3718             self.assertTrue(not hasattr(p, 't1'))
3719             self.assertTrue(hasattr(p, 't2'))
3720             self.assertTrue(hasattr(p, 't3'))
3721             self.assertTrue(hasattr(p, 't4'))
3722             self.assertTrue(not hasattr(p, 'ct1'))
3723             self.assertTrue(hasattr(p, 'ct2'))
3724             self.assertTrue(hasattr(p, 'ct3'))
3725             self.assertTrue(not hasattr(p, 'ct4'))
3726             self.assertTrue(not hasattr(p, 's'))
3727             self.assertTrue(hasattr(p, 's2'))
3728             self.assertTrue(not hasattr(p, 's3'))
3729             self.assertTrue(hasattr(p, 'path1'))
3730             self.assertTrue(hasattr(p, 'path2'))
3731             self.assertTrue(hasattr(p, 'path3'))
3732             self.assertTrue(not hasattr(p, 'path4'))
3733             #test SequencePlaceholder
3734             p = Process("test")
3735             p.a = EDAnalyzer("MyAnalyzer")
3736             p.b = EDAnalyzer("YourAnalyzer")
3737             p.s = Sequence(SequencePlaceholder("a")+p.b)
3738             p.pth = Path(p.s)
3739             p.prune()
3740             self.assertTrue(hasattr(p, 'a'))
3741             self.assertTrue(hasattr(p, 'b'))
3742             self.assertTrue(hasattr(p, 's'))
3743             self.assertTrue(hasattr(p, 'pth'))
3744             #test unresolved SequencePlaceholder
3745             p = Process("test")
3746             p.b = EDAnalyzer("YourAnalyzer")
3747             p.s = Sequence(SequencePlaceholder("a")+p.b)
3748             p.pth = Path(p.s)
3749             p.prune(keepUnresolvedSequencePlaceholders=True)
3750             self.assertTrue(hasattr(p, 'b'))
3751             self.assertTrue(hasattr(p, 's'))
3752             self.assertTrue(hasattr(p, 'pth'))
3753             self.assertEqual(p.s.dumpPython(),'cms.Sequence(cms.SequencePlaceholder("a")+process.b)\n')
3754             #test TaskPlaceholder
3755             p = Process("test")
3756             p.a = EDProducer("MyProducer")
3757             p.b = EDProducer("YourProducer")
3758             p.s = Task(TaskPlaceholder("a"),p.b)
3759             p.pth = Path(p.s)
3760             p.prune()
3761             self.assertTrue(hasattr(p, 'a'))
3762             self.assertTrue(hasattr(p, 'b'))
3763             self.assertTrue(hasattr(p, 's'))
3764             self.assertTrue(hasattr(p, 'pth'))
3765             #test ConditionalTaskPlaceholder
3766             p = Process("test")
3767             p.a = EDProducer("MyProducer")
3768             p.b = EDProducer("YourProducer")
3769             p.s = ConditionalTask(ConditionalTaskPlaceholder("a"),p.b)
3770             p.pth = Path(p.s)
3771             p.prune()
3772             self.assertTrue(hasattr(p, 'a'))
3773             self.assertTrue(hasattr(p, 'b'))
3774             self.assertTrue(hasattr(p, 's'))
3775             self.assertTrue(hasattr(p, 'pth'))
3776             #test unresolved SequencePlaceholder
3777             p = Process("test")
3778             p.b = EDProducer("YourAnalyzer")
3779             p.s = Task(TaskPlaceholder("a"),p.b)
3780             p.pth = Path(p.s)
3781             p.prune(keepUnresolvedSequencePlaceholders=True)
3782             self.assertTrue(hasattr(p, 'b'))
3783             self.assertTrue(hasattr(p, 's'))
3784             self.assertTrue(hasattr(p, 'pth'))
3785             self.assertEqual(p.s.dumpPython(),'cms.Task(cms.TaskPlaceholder("a"), process.b)\n')
3786         def testTaskPlaceholder(self):
3787             p = Process("test")
3788             p.a = EDProducer("ma")
3789             p.b = EDAnalyzer("mb")
3790             p.t1 = Task(TaskPlaceholder("c"))
3791             p.t2 = Task(p.a, TaskPlaceholder("d"), p.t1)
3792             p.t3 = Task(TaskPlaceholder("e"))
3793             p.path1 = Path(p.b, p.t2, p.t3)
3794             p.t5 = Task(p.a, TaskPlaceholder("g"), TaskPlaceholder("t4"))
3795             p.t4 = Task(TaskPlaceholder("f"))
3796             p.endpath1 = EndPath(p.b, p.t5)
3797             p.t6 = Task(TaskPlaceholder("h"))
3798             p.t7 = Task(p.a, TaskPlaceholder("i"), p.t6)
3799             p.t8 = Task(TaskPlaceholder("j"))
3800             p.schedule = Schedule(p.path1, p.endpath1,tasks=[p.t7,p.t8])
3801             p.c = EDProducer("mc")
3802             p.d = EDProducer("md")
3803             p.e = EDProducer("me")
3804             p.f = EDProducer("mf")
3805             p.g = EDProducer("mg")
3806             p.h = EDProducer("mh")
3807             p.i = EDProducer("mi")
3808             p.j = EDProducer("mj")
3809             self.assertEqual(_lineDiff(p.dumpPython(),Process('test').dumpPython()),
3810 """process.a = cms.EDProducer("ma")
3811 process.c = cms.EDProducer("mc")
3812 process.d = cms.EDProducer("md")
3813 process.e = cms.EDProducer("me")
3814 process.f = cms.EDProducer("mf")
3815 process.g = cms.EDProducer("mg")
3816 process.h = cms.EDProducer("mh")
3817 process.i = cms.EDProducer("mi")
3818 process.j = cms.EDProducer("mj")
3819 process.b = cms.EDAnalyzer("mb")
3820 process.t1 = cms.Task(cms.TaskPlaceholder("c"))
3821 process.t2 = cms.Task(cms.TaskPlaceholder("d"), process.a, process.t1)
3822 process.t3 = cms.Task(cms.TaskPlaceholder("e"))
3823 process.t5 = cms.Task(cms.TaskPlaceholder("g"), cms.TaskPlaceholder("t4"), process.a)
3824 process.t4 = cms.Task(cms.TaskPlaceholder("f"))
3825 process.t6 = cms.Task(cms.TaskPlaceholder("h"))
3826 process.t7 = cms.Task(cms.TaskPlaceholder("i"), process.a, process.t6)
3827 process.t8 = cms.Task(cms.TaskPlaceholder("j"))
3828 process.path1 = cms.Path(process.b, process.t2, process.t3)
3829 process.endpath1 = cms.EndPath(process.b, process.t5)
3830 process.schedule = cms.Schedule(*[ process.path1, process.endpath1 ], tasks=[process.t7, process.t8])""")
3831             p.resolve()
3832             self.assertEqual(_lineDiff(p.dumpPython(),Process('test').dumpPython()),
3833 """process.a = cms.EDProducer("ma")
3834 process.c = cms.EDProducer("mc")
3835 process.d = cms.EDProducer("md")
3836 process.e = cms.EDProducer("me")
3837 process.f = cms.EDProducer("mf")
3838 process.g = cms.EDProducer("mg")
3839 process.h = cms.EDProducer("mh")
3840 process.i = cms.EDProducer("mi")
3841 process.j = cms.EDProducer("mj")
3842 process.b = cms.EDAnalyzer("mb")
3843 process.t1 = cms.Task(process.c)
3844 process.t2 = cms.Task(process.a, process.d, process.t1)
3845 process.t3 = cms.Task(process.e)
3846 process.t4 = cms.Task(process.f)
3847 process.t6 = cms.Task(process.h)
3848 process.t7 = cms.Task(process.a, process.i, process.t6)
3849 process.t8 = cms.Task(process.j)
3850 process.t5 = cms.Task(process.a, process.g, process.t4)
3851 process.path1 = cms.Path(process.b, process.t2, process.t3)
3852 process.endpath1 = cms.EndPath(process.b, process.t5)
3853 process.schedule = cms.Schedule(*[ process.path1, process.endpath1 ], tasks=[process.t7, process.t8])""")
3854         def testConditionalTaskPlaceholder(self):
3855             p = Process("test")
3856             p.a = EDProducer("ma")
3857             p.b = EDAnalyzer("mb")
3858             p.t1 = ConditionalTask(ConditionalTaskPlaceholder("c"))
3859             p.t2 = ConditionalTask(p.a, ConditionalTaskPlaceholder("d"), p.t1)
3860             p.t3 = ConditionalTask(ConditionalTaskPlaceholder("e"))
3861             p.path1 = Path(p.b, p.t2, p.t3)
3862             p.t5 = ConditionalTask(p.a, ConditionalTaskPlaceholder("g"), ConditionalTaskPlaceholder("t4"))
3863             p.t4 = ConditionalTask(ConditionalTaskPlaceholder("f"))
3864             p.path2 = Path(p.b, p.t5)
3865             p.schedule = Schedule(p.path1, p.path2)
3866             p.c = EDProducer("mc")
3867             p.d = EDProducer("md")
3868             p.e = EDProducer("me")
3869             p.f = EDProducer("mf")
3870             p.g = EDProducer("mg")
3871             p.h = EDProducer("mh")
3872             p.i = EDProducer("mi")
3873             p.j = EDProducer("mj")
3874             self.assertEqual(_lineDiff(p.dumpPython(),Process('test').dumpPython()),
3875 """process.a = cms.EDProducer("ma")
3876 process.c = cms.EDProducer("mc")
3877 process.d = cms.EDProducer("md")
3878 process.e = cms.EDProducer("me")
3879 process.f = cms.EDProducer("mf")
3880 process.g = cms.EDProducer("mg")
3881 process.h = cms.EDProducer("mh")
3882 process.i = cms.EDProducer("mi")
3883 process.j = cms.EDProducer("mj")
3884 process.b = cms.EDAnalyzer("mb")
3885 process.t1 = cms.ConditionalTask(cms.ConditionalTaskPlaceholder("c"))
3886 process.t2 = cms.ConditionalTask(cms.ConditionalTaskPlaceholder("d"), process.a, process.t1)
3887 process.t3 = cms.ConditionalTask(cms.ConditionalTaskPlaceholder("e"))
3888 process.t5 = cms.ConditionalTask(cms.ConditionalTaskPlaceholder("g"), cms.ConditionalTaskPlaceholder("t4"), process.a)
3889 process.t4 = cms.ConditionalTask(cms.ConditionalTaskPlaceholder("f"))
3890 process.path1 = cms.Path(process.b, process.t2, process.t3)
3891 process.path2 = cms.Path(process.b, process.t5)
3892 process.schedule = cms.Schedule(*[ process.path1, process.path2 ])""")
3893             p.resolve()
3894             self.assertEqual(_lineDiff(p.dumpPython(),Process('test').dumpPython()),
3895 """process.a = cms.EDProducer("ma")
3896 process.c = cms.EDProducer("mc")
3897 process.d = cms.EDProducer("md")
3898 process.e = cms.EDProducer("me")
3899 process.f = cms.EDProducer("mf")
3900 process.g = cms.EDProducer("mg")
3901 process.h = cms.EDProducer("mh")
3902 process.i = cms.EDProducer("mi")
3903 process.j = cms.EDProducer("mj")
3904 process.b = cms.EDAnalyzer("mb")
3905 process.t1 = cms.ConditionalTask(process.c)
3906 process.t2 = cms.ConditionalTask(process.a, process.d, process.t1)
3907 process.t3 = cms.ConditionalTask(process.e)
3908 process.t4 = cms.ConditionalTask(process.f)
3909 process.t5 = cms.ConditionalTask(process.a, process.g, process.t4)
3910 process.path1 = cms.Path(process.b, process.t2, process.t3)
3911 process.path2 = cms.Path(process.b, process.t5)
3912 process.schedule = cms.Schedule(*[ process.path1, process.path2 ])""")
3913 
3914         def testDelete(self):
3915             p = Process("test")
3916             p.a = EDAnalyzer("MyAnalyzer")
3917             p.b = EDAnalyzer("YourAnalyzer")
3918             p.c = EDAnalyzer("OurAnalyzer")
3919             p.d = EDAnalyzer("OurAnalyzer")
3920             p.e = EDAnalyzer("OurAnalyzer")
3921             p.f = EDAnalyzer("OurAnalyzer")
3922             p.g = EDProducer("OurProducer")
3923             p.h = EDProducer("YourProducer")
3924             p.i = SwitchProducerTest(
3925                 test1 = EDProducer("OneProducer"),
3926                 test2 = EDProducer("TwoProducer")
3927             )
3928             p.t1 = Task(p.g, p.h, p.i)
3929             t2 = Task(p.g, p.h, p.i)
3930             t3 = Task(p.g, p.h)
3931             p.t4 = Task(p.h)
3932             p.ct1 = ConditionalTask(p.g, p.h, p.i)
3933             ct2 = ConditionalTask(p.g, p.h)
3934             ct3 = ConditionalTask(p.g, p.h)
3935             p.ct4 = ConditionalTask(p.h)
3936             p.s = Sequence(p.d+p.e)
3937             p.path1 = Path(p.a+p.f+p.s,t2,ct2)
3938             p.path2 = Path(p.a)
3939             p.path3 = Path(ct3, p.ct4)
3940             p.endpath2 = EndPath(p.b)
3941             p.endpath1 = EndPath(p.b+p.f)
3942             p.schedule = Schedule(p.path2, p.path3, p.endpath2, tasks=[t3, p.t4])
3943             self.assertTrue(hasattr(p, 'f'))
3944             self.assertTrue(hasattr(p, 'g'))
3945             self.assertTrue(hasattr(p, 'i'))
3946             del p.e
3947             del p.f
3948             del p.g
3949             del p.i
3950             self.assertFalse(hasattr(p, 'f'))
3951             self.assertFalse(hasattr(p, 'g'))
3952             self.assertEqual(p.t1.dumpPython(), 'cms.Task(process.h)\n')
3953             self.assertEqual(p.ct1.dumpPython(), 'cms.ConditionalTask(process.h)\n')
3954             self.assertEqual(p.s.dumpPython(), 'cms.Sequence(process.d)\n')
3955             self.assertEqual(p.path1.dumpPython(), 'cms.Path(process.a+process.s, cms.ConditionalTask(process.h), cms.Task(process.h))\n')
3956             self.assertEqual(p.endpath1.dumpPython(), 'cms.EndPath(process.b)\n')
3957             self.assertEqual(p.path3.dumpPython(), 'cms.Path(cms.ConditionalTask(process.h), process.ct4)\n')
3958             del p.s
3959             self.assertEqual(p.path1.dumpPython(), 'cms.Path(process.a+(process.d), cms.ConditionalTask(process.h), cms.Task(process.h))\n')
3960             self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(*[ process.path2, process.path3, process.endpath2 ], tasks=[cms.Task(process.h), process.t4])\n')
3961             del p.path2
3962             self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(*[ process.path3, process.endpath2 ], tasks=[cms.Task(process.h), process.t4])\n')
3963             del p.path3
3964             self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(*[ process.endpath2 ], tasks=[cms.Task(process.h), process.t4])\n')
3965             del p.endpath2
3966             self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(tasks=[cms.Task(process.h), process.t4])\n')
3967             del p.t4
3968             self.assertEqual(p.schedule_().dumpPython(), 'cms.Schedule(tasks=[cms.Task(process.h)])\n')
3969         def testModifier(self):
3970             m1 = Modifier()
3971             Process._firstProcess = True
3972             p = Process("test")
3973             self.assertRaises(RuntimeError, lambda: Process("test2", m1))
3974             m1 = Modifier()
3975             Process._firstProcess = True
3976             p = Process("test",m1)
3977             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
3978             def _mod_fred(obj):
3979                 obj.fred = 2
3980             m1.toModify(p.a,_mod_fred)
3981             self.assertEqual(p.a.fred.value(),2)
3982             p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
3983             m1.toModify(p.b, wilma = 2)
3984             self.assertEqual(p.b.wilma.value(),2)
3985             self.assertTrue(p.isUsingModifier(m1))
3986             #check that Modifier not attached to a process doesn't run
3987             m1 = Modifier()
3988             Process._firstProcess = True
3989             p = Process("test")
3990             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
3991             m1.toModify(p.a,_mod_fred)
3992             p.b = EDAnalyzer("YourAnalyzer", wilma = int32(1))
3993             m1.toModify(p.b, wilma = 2)
3994             self.assertEqual(p.a.fred.value(),1)
3995             self.assertEqual(p.b.wilma.value(),1)
3996             self.assertEqual(p.isUsingModifier(m1),False)
3997             #make sure clones get the changes
3998             m1 = Modifier()
3999             Process._firstProcess = True
4000             p = Process("test",m1)
4001             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4002             m1.toModify(p.a, fred = int32(2))
4003             p.b = p.a.clone(wilma = int32(3))
4004             self.assertEqual(p.a.fred.value(),2)
4005             self.assertEqual(p.a.wilma.value(),1)
4006             self.assertEqual(p.b.fred.value(),2)
4007             self.assertEqual(p.b.wilma.value(),3)
4008             #test removal of parameter
4009             m1 = Modifier()
4010             Process._firstProcess = True
4011             p = Process("test",m1)
4012             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1), fintstones = PSet(fred = int32(1)))
4013             m1.toModify(p.a, fred = None, fintstones = dict(fred = None))
4014             self.assertEqual(hasattr(p.a, "fred"), False)
4015             self.assertEqual(hasattr(p.a.fintstones, "fred"), False)
4016             self.assertEqual(p.a.wilma.value(),1)
4017             #test adding a parameter
4018             m1 = Modifier()
4019             Process._firstProcess = True
4020             p = Process("test",m1)
4021             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1))
4022             m1.toModify(p.a, wilma = int32(2))
4023             self.assertEqual(p.a.fred.value(), 1)
4024             self.assertEqual(p.a.wilma.value(),2)
4025             #test setting of value in PSet
4026             m1 = Modifier()
4027             Process._firstProcess = True
4028             p = Process("test",m1)
4029             p.a = EDAnalyzer("MyAnalyzer", flintstones = PSet(fred = int32(1), wilma = int32(1)))
4030             m1.toModify(p.a, flintstones = dict(fred = int32(2)))
4031             self.assertEqual(p.a.flintstones.fred.value(),2)
4032             self.assertEqual(p.a.flintstones.wilma.value(),1)
4033             #test proper exception from nonexisting parameter name
4034             m1 = Modifier()
4035             Process._firstProcess = True
4036             p = Process("test",m1)
4037             p.a = EDAnalyzer("MyAnalyzer", flintstones = PSet(fred = PSet(wilma = int32(1))))
4038             self.assertRaises(KeyError, lambda: m1.toModify(p.a, flintstones = dict(imnothere = dict(wilma=2))))
4039             self.assertRaises(KeyError, lambda: m1.toModify(p.a, foo = 1))
4040             #test setting a value in a VPSet
4041             m1 = Modifier()
4042             Process._firstProcess = True
4043             p = Process("test",m1)
4044             p.a = EDAnalyzer("MyAnalyzer", flintstones = VPSet(PSet(fred = int32(1)), PSet(wilma = int32(1))))
4045             m1.toModify(p.a, flintstones = {1:dict(wilma = int32(2))})
4046             self.assertEqual(p.a.flintstones[0].fred.value(),1)
4047             self.assertEqual(p.a.flintstones[1].wilma.value(),2)
4048             #test setting a value in a list of values
4049             m1 = Modifier()
4050             Process._firstProcess = True
4051             p = Process("test",m1)
4052             p.a = EDAnalyzer("MyAnalyzer", fred = vuint32(1,2,3))
4053             m1.toModify(p.a, fred = {1:7})
4054             self.assertEqual(p.a.fred[0],1)
4055             self.assertEqual(p.a.fred[1],7)
4056             self.assertEqual(p.a.fred[2],3)
4057             #test IndexError setting a value in a list to an item key not in the list
4058             m1 = Modifier()
4059             Process._firstProcess = True
4060             p = Process("test",m1)
4061             p.a = EDAnalyzer("MyAnalyzer", fred = vuint32(1,2,3))
4062             raised = False
4063             try: m1.toModify(p.a, fred = {5:7})
4064             except IndexError as e: raised = True
4065             self.assertEqual(raised, True)
4066             #test TypeError setting a value in a list using a key that is not an int
4067             m1 = Modifier()
4068             Process._firstProcess = True
4069             p = Process("test",m1)
4070             p.a = EDAnalyzer("MyAnalyzer", flintstones = VPSet(PSet(fred = int32(1)), PSet(wilma = int32(1))))
4071             raised = False
4072             try: m1.toModify(p.a, flintstones = dict(bogus = int32(37)))
4073             except TypeError as e: raised = True
4074             self.assertEqual(raised, True)
4075             #test that load causes process wide methods to run
4076             def _rem_a(proc):
4077                 del proc.a
4078             class ProcModifierMod(object):
4079                 def __init__(self,modifier,func):
4080                     self.proc_mod_ = modifier.makeProcessModifier(func)
4081             class DummyMod(object):
4082                 def __init__(self):
4083                     self.a = EDAnalyzer("Dummy")
4084             testMod = DummyMod()
4085             p.extend(testMod)
4086             self.assertTrue(hasattr(p,"a"))
4087             m1 = Modifier()
4088             Process._firstProcess = True
4089             p = Process("test",m1)
4090             testProcMod = ProcModifierMod(m1,_rem_a)
4091             p.extend(testMod)
4092             p.extend(testProcMod)
4093             self.assertTrue(not hasattr(p,"a"))
4094             #test ModifierChain
4095             m1 = Modifier()
4096             mc = ModifierChain(m1)
4097             Process._firstProcess = True
4098             p = Process("test",mc)
4099             self.assertTrue(p.isUsingModifier(m1))
4100             self.assertTrue(p.isUsingModifier(mc))
4101             testMod = DummyMod()
4102             p.b = EDAnalyzer("Dummy2", fred = int32(1))
4103             m1.toModify(p.b, fred = int32(3))
4104             p.extend(testMod)
4105             testProcMod = ProcModifierMod(m1,_rem_a)
4106             p.extend(testProcMod)
4107             self.assertTrue(not hasattr(p,"a"))
4108             self.assertEqual(p.b.fred.value(),3)
4109             #check cloneAndExclude
4110             m1 = Modifier()
4111             m2 = Modifier()
4112             mc = ModifierChain(m1,m2)
4113             mclone = mc.copyAndExclude([m2])
4114             self.assertTrue(not mclone._isOrContains(m2))
4115             self.assertTrue(mclone._isOrContains(m1))
4116             m3 = Modifier()
4117             mc2 = ModifierChain(mc,m3)
4118             mclone = mc2.copyAndExclude([m2])
4119             self.assertTrue(not mclone._isOrContains(m2))
4120             self.assertTrue(mclone._isOrContains(m1))
4121             self.assertTrue(mclone._isOrContains(m3))
4122             #check combining
4123             m1 = Modifier()
4124             m2 = Modifier()
4125             Process._firstProcess = True
4126             p = Process("test",m1)
4127             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4128             (m1 & m2).toModify(p.a, fred = int32(2))
4129             self.assertRaises(TypeError, lambda: (m1 & m2).toModify(p.a, 1, wilma=2))
4130             self.assertEqual(p.a.fred, 1)
4131             m1 = Modifier()
4132             m2 = Modifier()
4133             Process._firstProcess = True
4134             p = Process("test",m1,m2)
4135             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4136             (m1 & m2).toModify(p.a, fred = int32(2))
4137             self.assertEqual(p.a.fred, 2)
4138             m1 = Modifier()
4139             m2 = Modifier()
4140             m3 = Modifier()
4141             Process._firstProcess = True
4142             p = Process("test",m1,m2,m3)
4143             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4144             (m1 & m2 & m3).toModify(p.a, fred = int32(2))
4145             self.assertEqual(p.a.fred, 2)
4146             (m1 & (m2 & m3)).toModify(p.a, fred = int32(3))
4147             self.assertEqual(p.a.fred, 3)
4148             ((m1 & m2) & m3).toModify(p.a, fred = int32(4))
4149             self.assertEqual(p.a.fred, 4)
4150             #check inverse
4151             m1 = Modifier()
4152             m2 = Modifier()
4153             Process._firstProcess = True
4154             p = Process("test", m1)
4155             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4156             (~m1).toModify(p.a, fred=2)
4157             self.assertEqual(p.a.fred, 1)
4158             (~m2).toModify(p.a, wilma=2)
4159             self.assertEqual(p.a.wilma, 2)
4160             self.assertRaises(TypeError, lambda: (~m1).toModify(p.a, 1, wilma=2))
4161             self.assertRaises(TypeError, lambda: (~m2).toModify(p.a, 1, wilma=2))
4162             # check or
4163             m1 = Modifier()
4164             m2 = Modifier()
4165             m3 = Modifier()
4166             Process._firstProcess = True
4167             p = Process("test", m1)
4168             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4169             (m1 | m2).toModify(p.a, fred=2)
4170             self.assertEqual(p.a.fred, 2)
4171             (m1 | m2 | m3).toModify(p.a, fred=3)
4172             self.assertEqual(p.a.fred, 3)
4173             (m3 | m2 | m1).toModify(p.a, fred=4)
4174             self.assertEqual(p.a.fred, 4)
4175             ((m1 | m2) | m3).toModify(p.a, fred=5)
4176             self.assertEqual(p.a.fred, 5)
4177             (m1 | (m2 | m3)).toModify(p.a, fred=6)
4178             self.assertEqual(p.a.fred, 6)
4179             (m2 | m3).toModify(p.a, fred=7)
4180             self.assertEqual(p.a.fred, 6)
4181             self.assertRaises(TypeError, lambda: (m1 | m2).toModify(p.a, 1, wilma=2))
4182             self.assertRaises(TypeError, lambda: (m2 | m3).toModify(p.a, 1, wilma=2))
4183             # check combinations
4184             m1 = Modifier()
4185             m2 = Modifier()
4186             m3 = Modifier()
4187             m4 = Modifier()
4188             Process._firstProcess = True
4189             p = Process("test", m1, m2)
4190             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4191             (m1 & ~m2).toModify(p.a, fred=2)
4192             self.assertEqual(p.a.fred, 1)
4193             (m1 & ~m3).toModify(p.a, fred=2)
4194             self.assertEqual(p.a.fred, 2)
4195             (m1 | ~m2).toModify(p.a, fred=3)
4196             self.assertEqual(p.a.fred, 3)
4197             (~m1 | ~m2).toModify(p.a, fred=4)
4198             self.assertEqual(p.a.fred, 3)
4199             (~m3 & ~m4).toModify(p.a, fred=4)
4200             self.assertEqual(p.a.fred, 4)
4201             ((m1 & m3) | ~m4).toModify(p.a, fred=5)
4202             self.assertEqual(p.a.fred, 5)
4203             #check toReplaceWith
4204             m1 = Modifier()
4205             Process._firstProcess = True
4206             p = Process("test",m1)
4207             p.a =EDAnalyzer("MyAnalyzer", fred = int32(1))
4208             m1.toReplaceWith(p.a, EDAnalyzer("YourAnalyzer", wilma = int32(3)))
4209             self.assertRaises(TypeError, lambda: m1.toReplaceWith(p.a, EDProducer("YourProducer")))
4210             #Task
4211             p.b =EDAnalyzer("BAn")
4212             p.c =EDProducer("c")
4213             p.d =EDProducer("d")
4214             p.tc = Task(p.c)
4215             p.td = Task(p.d)
4216             p.s = Sequence(p.a, p.tc)
4217             m1.toReplaceWith(p.s, Sequence(p.a+p.b, p.td))
4218             self.assertEqual(p.a.wilma.value(),3)
4219             self.assertEqual(p.a.type_(),"YourAnalyzer")
4220             self.assertEqual(hasattr(p,"fred"),False)
4221             self.assertTrue(p.s.dumpPython() == "cms.Sequence(process.a+process.b, process.td)\n")
4222             p.e =EDProducer("e")
4223             m1.toReplaceWith(p.td, Task(p.e))
4224             self.assertTrue(p.td._collection == OrderedSet([p.e]))
4225             #ConditionalTask
4226             p.b =EDAnalyzer("BAn")
4227             p.c =EDProducer("c")
4228             p.d =EDProducer("d")
4229             del p.tc
4230             del p.td
4231             p.tc = ConditionalTask(p.c)
4232             p.td = ConditionalTask(p.d)
4233             p.s = Sequence(p.a, p.tc)
4234             m1.toReplaceWith(p.s, Sequence(p.a+p.b, p.td))
4235             self.assertEqual(p.a.wilma.value(),3)
4236             self.assertEqual(p.a.type_(),"YourAnalyzer")
4237             self.assertEqual(hasattr(p,"fred"),False)
4238             self.assertTrue(p.s.dumpPython() == "cms.Sequence(process.a+process.b, process.td)\n")
4239             p.e =EDProducer("e")
4240             m1.toReplaceWith(p.td, ConditionalTask(p.e))
4241             self.assertTrue(p.td._collection == OrderedSet([p.e]))
4242             #check toReplaceWith doesn't activate not chosen
4243             m1 = Modifier()
4244             Process._firstProcess = True
4245             p = Process("test")
4246             p.a =EDAnalyzer("MyAnalyzer", fred = int32(1))
4247             m1.toReplaceWith(p.a, EDAnalyzer("YourAnalyzer", wilma = int32(3)))
4248             self.assertEqual(p.a.type_(),"MyAnalyzer")
4249             #check toReplaceWith and and/not/or combinations
4250             m1 = Modifier()
4251             m2 = Modifier()
4252             m3 = Modifier()
4253             m4 = Modifier()
4254             Process._firstProcess = True
4255             p = Process("test", m1, m2)
4256             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4257             self.assertRaises(TypeError, lambda: (m1 & m2).toReplaceWith(p.a, EDProducer("YourProducer")))
4258             self.assertRaises(TypeError, lambda: (m3 & m4).toReplaceWith(p.a, EDProducer("YourProducer")))
4259             self.assertRaises(TypeError, lambda: (~m3).toReplaceWith(p.a, EDProducer("YourProducer")))
4260             self.assertRaises(TypeError, lambda: (~m1).toReplaceWith(p.a, EDProducer("YourProducer")))
4261             self.assertRaises(TypeError, lambda: (m1 | m3).toReplaceWith(p.a, EDProducer("YourProducer")))
4262             self.assertRaises(TypeError, lambda: (m3 | m4).toReplaceWith(p.a, EDProducer("YourProducer")))
4263             (m1 & m2).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer1"))
4264             self.assertEqual(p.a.type_(), "YourAnalyzer1")
4265             (m1 & m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
4266             self.assertEqual(p.a.type_(), "YourAnalyzer1")
4267             (~m1).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
4268             self.assertEqual(p.a.type_(), "YourAnalyzer1")
4269             (~m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer2"))
4270             self.assertEqual(p.a.type_(), "YourAnalyzer2")
4271             (m1 | m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer3"))
4272             self.assertEqual(p.a.type_(), "YourAnalyzer3")
4273             (m3 | m4).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer4"))
4274             self.assertEqual(p.a.type_(), "YourAnalyzer3")
4275             #check chaining of toModify and toReplaceWith
4276             m1 = Modifier()
4277             m2 = Modifier()
4278             m3 = Modifier()
4279             Process._firstProcess = True
4280             p = Process("test", m1, m2)
4281             p.a = EDAnalyzer("MyAnalyzer", fred = int32(1), wilma = int32(1))
4282             p.b = EDProducer("MyProducer", barney = int32(1), betty = int32(1))
4283             (m1 & m2).toModify(p.a, fred = 2).toModify(p.b, betty = 3)
4284             self.assertEqual(p.a.fred, 2)
4285             self.assertEqual(p.a.wilma, 1)
4286             self.assertEqual(p.b.barney, 1)
4287             self.assertEqual(p.b.betty, 3)
4288             (m1 | m3).toModify(p.a, wilma = 4).toModify(p.b, barney = 5)
4289             self.assertEqual(p.a.fred, 2)
4290             self.assertEqual(p.a.wilma, 4)
4291             self.assertEqual(p.b.barney, 5)
4292             self.assertEqual(p.b.betty, 3)
4293             (m2 & ~m3).toReplaceWith(p.a, EDAnalyzer("YourAnalyzer")).toModify(p.b, barney = 6)
4294             self.assertEqual(p.a.type_(), "YourAnalyzer")
4295             self.assertEqual(p.b.barney, 6)
4296             self.assertEqual(p.b.betty, 3)
4297             (m1 & ~m3).toModify(p.a, param=int32(42)).toReplaceWith(p.b, EDProducer("YourProducer"))
4298             self.assertEqual(p.a.type_(), "YourAnalyzer")
4299             self.assertEqual(p.a.param, 42)
4300             self.assertEqual(p.b.type_(), "YourProducer")
4301 
4302             # EDAlias
4303             a = EDAlias(foo2 = VPSet(PSet(type = string("Foo2"))))
4304             m = Modifier()
4305             m._setChosen()
4306             # Modify parameters
4307             m.toModify(a, foo2 = {0: dict(type = "Foo3")})
4308             self.assertEqual(a.foo2[0].type, "Foo3")
4309             # Add an alias
4310             m.toModify(a, foo4 = VPSet(PSet(type = string("Foo4"))))
4311             self.assertEqual(a.foo2[0].type, "Foo3")
4312             self.assertEqual(a.foo4[0].type, "Foo4")
4313             # Remove an alias
4314             m.toModify(a, foo2 = None)
4315             self.assertFalse(hasattr(a, "foo2"))
4316             self.assertEqual(a.foo4[0].type, "Foo4")
4317             # Replace (doesn't work out of the box because EDAlias is not _Parameterizable
4318             m.toReplaceWith(a, EDAlias(bar = VPSet(PSet(type = string("Bar")))))
4319             self.assertFalse(hasattr(a, "foo2"))
4320             self.assertFalse(hasattr(a, "foo4"))
4321             self.assertTrue(hasattr(a, "bar"))
4322             self.assertEqual(a.bar[0].type, "Bar")
4323 
4324             # SwitchProducer
4325             sp = SwitchProducerTest(test1 = EDProducer("Foo",
4326                                                        a = int32(1),
4327                                                        b = PSet(c = int32(2))),
4328                                     test2 = EDProducer("Bar",
4329                                                        aa = int32(11),
4330                                                        bb = PSet(cc = int32(12))))
4331             m = Modifier()
4332             m._setChosen()
4333             # Modify parameters
4334             m.toModify(sp,
4335                        test1 = dict(a = 4, b = dict(c = None)),
4336                        test2 = dict(aa = 15, bb = dict(cc = 45, dd = string("foo"))))
4337             self.assertEqual(sp.test1.a.value(), 4)
4338             self.assertEqual(sp.test1.b.hasParameter("c"), False)
4339             self.assertEqual(sp.test2.aa.value(), 15)
4340             self.assertEqual(sp.test2.bb.cc.value(), 45)
4341             self.assertEqual(sp.test2.bb.dd.value(), "foo")
4342             # Replace a producer
4343             m.toReplaceWith(sp.test1, EDProducer("Fred", x = int32(42)))
4344             self.assertEqual(sp.test1.type_(), "Fred")
4345             self.assertEqual(sp.test1.x.value(), 42)
4346             self.assertRaises(TypeError, lambda: m.toReplaceWith(sp.test1, EDAnalyzer("Foo")))
4347             # Alternative way (only to be allow same syntax to be used as for adding)
4348             m.toModify(sp, test2 = EDProducer("Xyzzy", x = int32(24)))
4349             self.assertEqual(sp.test2.type_(), "Xyzzy")
4350             self.assertEqual(sp.test2.x.value(), 24)
4351             self.assertRaises(TypeError, lambda: m.toModify(sp, test2 = EDAnalyzer("Foo")))
4352             # Add a producer
4353             m.toModify(sp, test3 = EDProducer("Wilma", y = int32(24)))
4354             self.assertEqual(sp.test3.type_(), "Wilma")
4355             self.assertEqual(sp.test3.y.value(), 24)
4356             self.assertRaises(TypeError, lambda: m.toModify(sp, test4 = EDAnalyzer("Foo")))
4357             # Remove a producer
4358             m.toModify(sp, test2 = None)
4359             self.assertEqual(hasattr(sp, "test2"), False)
4360             # Add an alias
4361             m.toModify(sp, test2 = EDAlias(foo = VPSet(PSet(type = string("int")))))
4362             self.assertTrue(hasattr(sp.test2, "foo"))
4363             # Replace an alias
4364             m.toReplaceWith(sp.test2, EDAlias(bar = VPSet(PSet(type = string("int")))))
4365             self.assertTrue(hasattr(sp.test2, "bar"))
4366             # Alternative way
4367             m.toModify(sp, test2 = EDAlias(xyzzy = VPSet(PSet(type = string("int")))))
4368             self.assertTrue(hasattr(sp.test2, "xyzzy"))
4369             # Replace an alias with EDProducer
4370             self.assertRaises(TypeError, lambda: m.toReplaceWith(sp.test2, EDProducer("Foo")))
4371             m.toModify(sp, test2 = EDProducer("Foo"))
4372         def testProcessFragment(self):
4373             #check defaults are not overwritten
4374             f = ProcessFragment('Fragment')
4375             p = Process('PROCESS')
4376             p.maxEvents.input = 10
4377             p.options.numberOfThreads = 4
4378             p.maxLuminosityBlocks.input = 2
4379             p.extend(f)
4380             self.assertEqual(p.maxEvents.input.value(),10)
4381             self.assertEqual(p.options.numberOfThreads.value(), 4)
4382             self.assertEqual(p.maxLuminosityBlocks.input.value(),2)
4383             #general checks
4384             f = ProcessFragment("Fragment")
4385             f.fltr = EDFilter("Foo")
4386             p = Process('PROCESS')
4387             p.extend(f)
4388             self.assertTrue(hasattr(p,'fltr'))
4389         def testProcessForProcessAccelerator(self):
4390             proc = Process("TEST")
4391             p = ProcessForProcessAccelerator(proc)
4392             p.TestService = Service("TestService")
4393             self.assertTrue(hasattr(proc, "TestService"))
4394             self.assertEqual(proc.TestService.type_(), "TestService")
4395             self.assertRaises(TypeError, setattr, p, "a", EDProducer("Foo"))
4396             p.add_(Service("TestServiceTwo"))
4397             self.assertTrue(hasattr(proc, "TestServiceTwo"))
4398             self.assertEqual(proc.TestServiceTwo.type_(), "TestServiceTwo")
4399             p.TestService.foo = untracked.uint32(42)
4400             self.assertEqual(proc.TestService.foo.value(), 42)
4401             proc.mod = EDProducer("Producer")
4402             self.assertRaises(TypeError, getattr, p, "mod")
4403         def testProcessAccelerator(self):
4404             proc = Process("TEST")
4405             p = TestMakePSet()
4406             proc.fillProcessDesc(p)
4407             self.assertTrue(["cpu"], p.values["@available_accelerators"][1])
4408             self.assertFalse(p.values["@selected_accelerators"][0])
4409             self.assertTrue(["cpu"], p.values["@selected_accelerators"][1])
4410             self.assertFalse(p.values["@module_type_resolver"][0])
4411             self.assertEqual("", p.values["@module_type_resolver"][1])
4412 
4413             proc = Process("TEST")
4414             self.assertRaises(TypeError, setattr, proc, "processAcceleratorTest", ProcessAcceleratorTest())
4415             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4416             del proc.MessageLogger # remove boilerplate unnecessary for this test case
4417             self.maxDiff = None
4418             self.assertEqual(proc.dumpPython(),
4419 """import FWCore.ParameterSet.Config as cms
4420 from test import ProcessAcceleratorTest
4421 
4422 process = cms.Process("TEST")
4423 
4424 process.maxEvents = cms.untracked.PSet(
4425     input = cms.optional.untracked.int32,
4426     output = cms.optional.untracked.allowed(cms.int32,cms.PSet)
4427 )
4428 
4429 process.maxLuminosityBlocks = cms.untracked.PSet(
4430     input = cms.untracked.int32(-1)
4431 )
4432 
4433 process.options = cms.untracked.PSet(
4434     IgnoreCompletely = cms.untracked.vstring(),
4435     Rethrow = cms.untracked.vstring(),
4436     TryToContinue = cms.untracked.vstring(),
4437     accelerators = cms.untracked.vstring('*'),
4438     allowUnscheduled = cms.obsolete.untracked.bool,
4439     canDeleteEarly = cms.untracked.vstring(),
4440     deleteNonConsumedUnscheduledModules = cms.untracked.bool(True),
4441     dumpOptions = cms.untracked.bool(False),
4442     emptyRunLumiMode = cms.obsolete.untracked.string,
4443     eventSetup = cms.untracked.PSet(
4444         forceNumberOfConcurrentIOVs = cms.untracked.PSet(
4445             allowAnyLabel_=cms.required.untracked.uint32
4446         ),
4447         numberOfConcurrentIOVs = cms.untracked.uint32(0)
4448     ),
4449     fileMode = cms.untracked.string('FULLMERGE'),
4450     forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False),
4451     holdsReferencesToDeleteEarly = cms.untracked.VPSet(),
4452     makeTriggerResults = cms.obsolete.untracked.bool,
4453     modulesToCallForTryToContinue = cms.untracked.vstring(),
4454     modulesToIgnoreForDeleteEarly = cms.untracked.vstring(),
4455     numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(0),
4456     numberOfConcurrentRuns = cms.untracked.uint32(1),
4457     numberOfStreams = cms.untracked.uint32(0),
4458     numberOfThreads = cms.untracked.uint32(1),
4459     printDependencies = cms.untracked.bool(False),
4460     sizeOfStackForThreadsInKB = cms.optional.untracked.uint32,
4461     throwIfIllegalParameter = cms.untracked.bool(True),
4462     wantSummary = cms.untracked.bool(False)
4463 )
4464 
4465 process.ProcessAcceleratorTest = ProcessAcceleratorTest(
4466     enabled = ['test1', 'test2', 'anothertest3']
4467 )
4468 
4469 
4470 """)
4471             p = TestMakePSet()
4472             proc.fillProcessDesc(p)
4473             self.assertEqual(["*"], p.values["options"][1].values["accelerators"][1])
4474             self.assertFalse(p.values["options"][1].values["accelerators"][0])
4475             self.assertTrue(["anothertest3", "cpu", "test1", "test2"], p.values["@selected_accelerators"][1])
4476             self.assertEqual("AcceleratorTestService", p.values["services"][1][0].values["@service_type"][1])
4477             self.assertFalse(p.values["@available_accelerators"][0])
4478             self.assertTrue(["anothertest3", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4479             self.assertFalse(p.values["@module_type_resolver"][0])
4480             self.assertEqual("", p.values["@module_type_resolver"][1])
4481 
4482             proc = Process("TEST")
4483             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4484             proc.add_(Service("AcceleratorTestServiceRemove"))
4485             p = TestMakePSet()
4486             proc.fillProcessDesc(p)
4487             services = [x.values["@service_type"][1] for x in p.values["services"][1]]
4488             self.assertTrue("AcceleratorTestService" in services)
4489             self.assertFalse("AcceleratorTestServiceRemove" in services)
4490 
4491             proc = Process("TEST")
4492             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(enabled=["test1"])
4493             p = TestMakePSet()
4494             proc.fillProcessDesc(p)
4495             self.assertEqual(["cpu", "test1"], p.values["@selected_accelerators"][1])
4496             self.assertEqual(["cpu", "test1"], p.values["@available_accelerators"][1])
4497 
4498             proc = Process("TEST")
4499             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4500             proc.options.accelerators = ["test2"]
4501             p = TestMakePSet()
4502             proc.fillProcessDesc(p)
4503             self.assertEqual(["test2"], p.values["@selected_accelerators"][1])
4504             self.assertEqual(["anothertest3", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4505 
4506             proc = Process("TEST")
4507             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4508             proc.options.accelerators = ["test*"]
4509             proc.fillProcessDesc(p)
4510             self.assertEqual(["test1", "test2"], p.values["@selected_accelerators"][1])
4511             self.assertEqual(["anothertest3", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4512 
4513             proc = Process("TEST")
4514             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(enabled=["test1"])
4515             proc.options.accelerators = ["test2"]
4516             p = TestMakePSet()
4517             proc.fillProcessDesc(p)
4518             self.assertEqual([], p.values["@selected_accelerators"][1])
4519             self.assertEqual(["cpu", "test1"], p.values["@available_accelerators"][1])
4520 
4521             proc = Process("TEST")
4522             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4523             proc.options.accelerators = ["cpu*"]
4524             p = TestMakePSet()
4525             proc.fillProcessDesc(p)
4526             self.assertEqual(["cpu"], p.values["@selected_accelerators"][1])
4527             self.assertEqual(["anothertest3", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4528 
4529             proc = Process("TEST")
4530             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4531             proc.options.accelerators = ["test3"]
4532             p = TestMakePSet()
4533             self.assertRaises(ValueError, proc.fillProcessDesc, p)
4534 
4535             proc = Process("TEST")
4536             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4537             proc.options.accelerators = ["*", "test1"]
4538             p = TestMakePSet()
4539             self.assertRaises(ValueError, proc.fillProcessDesc, p)
4540 
4541             proc = Process("TEST")
4542             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4543             proc.ProcessAcceleratorTest2 = ProcessAcceleratorTest2()
4544             p = TestMakePSet()
4545             proc.fillProcessDesc(p)
4546             self.assertEqual(["anothertest3", "anothertest4", "cpu", "test1", "test2"], p.values["@selected_accelerators"][1])
4547             self.assertEqual(["anothertest3", "anothertest4", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4548 
4549             proc = Process("TEST")
4550             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4551             proc.ProcessAcceleratorTest2 = ProcessAcceleratorTest2()
4552             proc.options.accelerators = ["*test3", "c*"]
4553             p = TestMakePSet()
4554             proc.fillProcessDesc(p)
4555             self.assertEqual(["anothertest3", "cpu"], p.values["@selected_accelerators"][1])
4556             self.assertEqual(["anothertest3", "anothertest4", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4557 
4558             proc = Process("TEST")
4559             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4560             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4561                                                              a = int32(1),
4562                                                              b = PSet(c = int32(2))),
4563                                           test1 = EDProducer("Bar",
4564                                                              aa = int32(11),
4565                                                              bb = PSet(cc = int32(12))))
4566             proc.p = Path(proc.sp)
4567             p = TestMakePSet()
4568             proc.fillProcessDesc(p)
4569             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
4570 
4571             proc = Process("TEST")
4572             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(enabled=["test1"])
4573             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4574                                                              a = int32(1),
4575                                                              b = PSet(c = int32(2))),
4576                                           test1 = EDProducer("Bar",
4577                                                              aa = int32(11),
4578                                                              bb = PSet(cc = int32(12))))
4579             proc.p = Path(proc.sp)
4580             p = TestMakePSet()
4581             proc.fillProcessDesc(p)
4582             self.assertEqual((False, "sp@test1"), p.values["sp"][1].values["@chosen_case"])
4583 
4584             proc = Process("TEST")
4585             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4586             proc.options.accelerators = ["test1"]
4587             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4588                                                              a = int32(1),
4589                                                              b = PSet(c = int32(2))),
4590                                           test1 = EDProducer("Bar",
4591                                                              aa = int32(11),
4592                                                              bb = PSet(cc = int32(12))))
4593             proc.p = Path(proc.sp)
4594             p = TestMakePSet()
4595             proc.fillProcessDesc(p)
4596             self.assertEqual((False, "sp@test1"), p.values["sp"][1].values["@chosen_case"])
4597 
4598             proc = Process("TEST")
4599             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4600             proc.options.accelerators = ["test*"]
4601             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4602                                                              a = int32(1),
4603                                                              b = PSet(c = int32(2))),
4604                                           test1 = EDProducer("Bar",
4605                                                              aa = int32(11),
4606                                                              bb = PSet(cc = int32(12))))
4607             proc.p = Path(proc.sp)
4608             p = TestMakePSet()
4609             proc.fillProcessDesc(p)
4610             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
4611 
4612             proc = Process("TEST")
4613             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4614             proc.options.accelerators = ["anothertest3"]
4615             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4616                                                              a = int32(1),
4617                                                              b = PSet(c = int32(2))),
4618                                           test1 = EDProducer("Bar",
4619                                                              aa = int32(11),
4620                                                              bb = PSet(cc = int32(12))))
4621             proc.p = Path(proc.sp)
4622             p = TestMakePSet()
4623             self.assertRaises(RuntimeError, proc.fillProcessDesc, p)
4624 
4625             proc = Process("TEST")
4626             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(
4627                 moduleTypeResolverMaker=lambda accelerators: TestModuleTypeResolver(accelerators))
4628             proc.ProcessAcceleratorTest2 = ProcessAcceleratorTest2()
4629             proc.normalProducer = EDProducer("FooProducer")
4630             proc.testProducer = EDProducer("BarProducer@test")
4631             proc.test2Producer = EDProducer("BarProducer@test", test=untracked.PSet(backend=untracked.string("test2_backend")))
4632             proc.testAnalyzer = EDAnalyzer("Analyzer@test")
4633             proc.testFilter = EDAnalyzer("Filter@test")
4634             proc.testESProducer = ESProducer("ESProducer@test")
4635             proc.testESSource = ESSource("ESSource@test")
4636             proc.p = Path(proc.normalProducer+proc.testProducer+proc.test2Producer+proc.testAnalyzer+proc.testFilter)
4637             p = TestMakePSet()
4638             proc.fillProcessDesc(p)
4639             self.assertEqual("TestModuleTypeResolver", p.values["@module_type_resolver"][1])
4640             self.assertEqual("FooProducer", p.values["normalProducer"][1].values["@module_type"][1])
4641             self.assertEqual(len(list(filter(lambda x: not "@" in x, p.values["normalProducer"][1].values.keys()))), 0)
4642             self.assertEqual("BarProducer@test", p.values["testProducer"][1].values["@module_type"][1])
4643             self.assertEqual(False, p.values["testProducer"][1].values["test"][0])
4644             self.assertEqual(False, p.values["testProducer"][1].values["test"][1].values["backend"][0])
4645             self.assertEqual("test1_backend", p.values["testProducer"][1].values["test"][1].values["backend"][1])
4646             self.assertEqual("BarProducer@test", p.values["test2Producer"][1].values["@module_type"][1])
4647             self.assertEqual("test2_backend", p.values["test2Producer"][1].values["test"][1].values["backend"][1])
4648             self.assertEqual("Analyzer@test", p.values["testAnalyzer"][1].values["@module_type"][1])
4649             self.assertEqual("test1_backend", p.values["testAnalyzer"][1].values["test"][1].values["backend"][1])
4650             self.assertEqual("Filter@test", p.values["testFilter"][1].values["@module_type"][1])
4651             self.assertEqual("test1_backend", p.values["testFilter"][1].values["test"][1].values["backend"][1])
4652             self.assertEqual("ESProducer@test", p.values["ESProducer@test@testESProducer"][1].values["@module_type"][1])
4653             self.assertEqual("test1_backend", p.values["ESProducer@test@testESProducer"][1].values["test"][1].values["backend"][1])
4654             self.assertEqual("ESSource@test", p.values["ESSource@test@testESSource"][1].values["@module_type"][1])
4655             self.assertEqual("test1_backend", p.values["ESSource@test@testESSource"][1].values["test"][1].values["backend"][1])
4656 
4657             # No required accelerators available
4658             proc = Process("Test")
4659             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(
4660                 moduleTypeResolverMaker=lambda accelerators: TestModuleTypeResolver(accelerators))
4661             proc.options.accelerators = []
4662             self.assertRaises(EDMException, proc.fillProcessDesc, p)
4663 
4664             proc = Process("Test")
4665             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(
4666                 moduleTypeResolverMaker=lambda accelerators: TestModuleTypeResolver(accelerators))
4667             proc.options.accelerators = ["test1"]
4668             proc.test2Producer = EDProducer("BarProducer@test", test=untracked.PSet(backend=untracked.string("test2_backend")))
4669             proc.p = Path(proc.test2Producer)
4670             self.assertRaises(EDMException, proc.fillProcessDesc, p)
4671 
4672             # Two ProcessAccelerators return type resolver
4673             proc = Process("TEST")
4674             proc.ProcessAcceleratorTest = ProcessAcceleratorTest(
4675                 moduleTypeResolverMaker=lambda accelerators: TestModuleTypeResolver(accelerators))
4676             proc.ProcessAcceleratorTest2 = ProcessAcceleratorTest2(
4677                 moduleTypeResolverMaker=lambda accelerators: TestModuleTypeResolver(accelerators))
4678             p = TestMakePSet()
4679             self.assertRaises(RuntimeError, proc.fillProcessDesc, p)
4680 
4681             import pickle
4682             proc = Process("TEST")
4683             proc.ProcessAcceleratorTest = ProcessAcceleratorTest()
4684             proc.sp = SwitchProducerTest2(test2 = EDProducer("Foo",
4685                                                              a = int32(1),
4686                                                              b = PSet(c = int32(2))),
4687                                           test1 = EDProducer("Bar",
4688                                                              aa = int32(11),
4689                                                              bb = PSet(cc = int32(12))))
4690             proc.p = Path(proc.sp)
4691             pkl = pickle.dumps(proc)
4692             unpkl = pickle.loads(pkl)
4693             p = TestMakePSet()
4694             unpkl.fillProcessDesc(p)
4695             self.assertEqual((False, "sp@test2"), p.values["sp"][1].values["@chosen_case"])
4696             self.assertEqual(["anothertest3", "cpu", "test1", "test2"], p.values["@available_accelerators"][1])
4697             unpkl = pickle.loads(pkl)
4698             unpkl.ProcessAcceleratorTest.setEnabled(["test1"])
4699             p = TestMakePSet()
4700             unpkl.fillProcessDesc(p)
4701             self.assertEqual((False, "sp@test1"), p.values["sp"][1].values["@chosen_case"])
4702             self.assertEqual(["cpu", "test1"], p.values["@available_accelerators"][1])
4703 
4704         def testProcessSpecialOverrideReleaseVersion(self):
4705             proc = Process("TEST")
4706             p = TestMakePSet()
4707             proc.fillProcessDesc(p)
4708             self.assertFalse("@special_override_release_version_only_for_testing" in p.values)
4709 
4710             proc = Process("TEST")
4711             proc._specialOverrideReleaseVersionOnlyForTesting("CMSSW_15_0_0")
4712             p = TestMakePSet()
4713             proc.fillProcessDesc(p)
4714             self.assertEqual((False, "CMSSW_15_0_0"), p.values["@special_override_release_version_only_for_testing"])
4715 
4716     unittest.main()