File indexing completed on 2023-05-16 00:57:56
0001 from __future__ import print_function
0002 from builtins import range, object
0003 import inspect
0004
0005 class _ConfigureComponent(object):
0006 """Denotes a class that can be used by the Processes class"""
0007 def _isTaskComponent(self):
0008 return False
0009
0010 class PrintOptions(object):
0011 def __init__(self, indent = 0, deltaIndent = 4, process = True, targetDirectory = None, useSubdirectories = False):
0012 self.indent_= indent
0013 self.deltaIndent_ = deltaIndent
0014 self.isCfg = process
0015 self.targetDirectory = targetDirectory
0016 self.useSubdirectories = useSubdirectories
0017 def indentation(self):
0018 return ' '*self.indent_
0019 def indent(self):
0020 self.indent_ += self.deltaIndent_
0021 def unindent(self):
0022 self.indent_ -= self.deltaIndent_
0023
0024 class _SpecialImportRegistry(object):
0025 """This class collects special import statements of configuration types"""
0026 def __init__(self):
0027 self._registry = {}
0028
0029 def _reset(self):
0030 for lst in self._registry.values():
0031 lst[1] = False
0032
0033 def registerSpecialImportForType(self, cls, impStatement):
0034 className = cls.__name__
0035 if className in self._registry:
0036 raise RuntimeError("Error: the configuration type '%s' already has an import statement registered '%s'" % (className, self._registry[className][0]))
0037 self._registry[className] = [impStatement, False]
0038
0039 def registerUse(self, obj):
0040 className = obj.__class__.__name__
0041 try:
0042 self._registry[className][1] = True
0043 except KeyError:
0044 pass
0045
0046 def getSpecialImports(self):
0047 coll = set()
0048 for (imp, used) in self._registry.values():
0049 if used:
0050 coll.add(imp)
0051 return sorted(coll)
0052
0053 specialImportRegistry = _SpecialImportRegistry()
0054
0055 class _ParameterTypeBase(object):
0056 """base class for classes which are used as the 'parameters' for a ParameterSet"""
0057 def __init__(self):
0058 self.__dict__["_isFrozen"] = False
0059 self.__isTracked = True
0060 self._isModified = False
0061 def isModified(self):
0062 return self._isModified
0063 def resetModified(self):
0064 self._isModified=False
0065 def configTypeName(self):
0066 if self.isTracked():
0067 return type(self).__name__
0068 return 'untracked '+type(self).__name__
0069 def pythonTypeName(self):
0070 if self.isTracked():
0071 return 'cms.'+type(self).__name__
0072 return 'cms.untracked.'+type(self).__name__
0073 def dumpPython(self, options=PrintOptions()):
0074 specialImportRegistry.registerUse(self)
0075 return self.pythonTypeName()+"("+self.pythonValue(options)+")"
0076 def __repr__(self):
0077 return self.dumpPython()
0078 def isTracked(self):
0079 return self.__isTracked
0080 def setIsTracked(self,trackness):
0081 self.__isTracked = trackness
0082 def isFrozen(self):
0083 return self._isFrozen
0084 def setIsFrozen(self):
0085 self._isFrozen = True
0086 def isCompatibleCMSType(self,aType):
0087 return isinstance(self,aType)
0088 def _checkAndReturnValueWithType(self, valueWithType):
0089 if isinstance(valueWithType, type(self)):
0090 return valueWithType
0091 raise TypeError("Attempted to assign type {from_} to type {to}".format(from_ = str(type(valueWithType)), to = str(type(self))) )
0092
0093
0094 class _SimpleParameterTypeBase(_ParameterTypeBase):
0095 """base class for parameter classes which only hold a single value"""
0096 def __init__(self,value):
0097 super(_SimpleParameterTypeBase,self).__init__()
0098 self._value = value
0099 if not self._isValid(value):
0100 raise ValueError(str(value)+" is not a valid "+str(type(self)))
0101 def value(self):
0102 return self._value
0103 def setValue(self,value):
0104 if not self._isValid(value):
0105 raise ValueError(str(value)+" is not a valid "+str(type(self)))
0106 if value!=self._value:
0107 self._isModified=True
0108 self._value=value
0109 def configValue(self, options=PrintOptions()):
0110 return str(self._value)
0111 def pythonValue(self, options=PrintOptions()):
0112 return self.configValue(options)
0113 def __eq__(self,other):
0114 if isinstance(other,_SimpleParameterTypeBase):
0115 return self._value == other._value
0116 return self._value == other
0117 def __ne__(self,other):
0118 if isinstance(other,_SimpleParameterTypeBase):
0119 return self._value != other._value
0120 return self._value != other
0121 def __lt__(self,other):
0122 if isinstance(other,_SimpleParameterTypeBase):
0123 return self._value < other._value
0124 return self._value < other
0125 def __le__(self,other):
0126 if isinstance(other,_SimpleParameterTypeBase):
0127 return self._value <= other._value
0128 return self._value <= other
0129 def __gt__(self,other):
0130 if isinstance(other,_SimpleParameterTypeBase):
0131 return self._value > other._value
0132 return self._value > other
0133 def __ge__(self,other):
0134 if isinstance(other,_SimpleParameterTypeBase):
0135 return self._value >= other._value
0136 return self._value >= other
0137
0138
0139 class UsingBlock(_SimpleParameterTypeBase):
0140 """For injection purposes, pretend this is a new parameter type
0141 then have a post process step which strips these out
0142 """
0143 def __init__(self,value, s='', loc=0, file=''):
0144 super(UsingBlock,self).__init__(value)
0145 self.s = s
0146 self.loc = loc
0147 self.file = file
0148 self.isResolved = False
0149 @staticmethod
0150 def _isValid(value):
0151 return isinstance(value,str)
0152 def _valueFromString(value):
0153 """only used for cfg-parsing"""
0154 return string(value)
0155 def insertInto(self, parameterSet, myname):
0156 value = self.value()
0157
0158
0159
0160 parameterSet.addString(self.isTracked(), myname, value)
0161 def dumpPython(self, options=PrintOptions()):
0162 if options.isCfg:
0163 return "process."+self.value()
0164 else:
0165 return self.value()
0166
0167
0168 class _Parameterizable(object):
0169 """Base class for classes which allow addition of _ParameterTypeBase data"""
0170 def __init__(self,*arg,**kargs):
0171 self.__dict__['_Parameterizable__parameterNames'] = []
0172 self.__dict__["_isFrozen"] = False
0173 self.__dict__['_Parameterizable__validator'] = None
0174 """The named arguments are the 'parameters' which are added as 'python attributes' to the object"""
0175 if len(arg) != 0:
0176
0177 for block in arg:
0178
0179 if type(block).__name__ not in ["PSet", "__PSet"]:
0180 raise ValueError("Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
0181 self.__setParameters(block.parameters_())
0182 self.__setParameters(kargs)
0183 self._isModified = False
0184
0185 def parameterNames_(self):
0186 """Returns the name of the parameters"""
0187 return self.__parameterNames[:]
0188 def isModified(self):
0189 if self._isModified:
0190 return True
0191 for name in self.parameterNames_():
0192 param = self.__dict__[name]
0193 if isinstance(param, _Parameterizable) and param.isModified():
0194 self._isModified = True
0195 return True
0196 return False
0197
0198 def hasParameter(self, params):
0199 """
0200 _hasParameter_
0201
0202 check that pset provided has the attribute chain
0203 specified.
0204
0205 Eg, if params is [ 'attr1', 'attr2', 'attr3' ]
0206 check for pset.attr1.attr2.attr3
0207
0208 returns True if parameter exists, False if not
0209 """
0210 return (self.getParameter(params) != None)
0211
0212 def getParameter(self, params):
0213 """
0214 _getParameter_
0215
0216 Retrieve the specified parameter from the PSet Provided
0217 given the attribute chain
0218
0219 returns None if not found
0220 """
0221 lastParam = self
0222
0223 if type(params).__name__ == 'str':
0224 return getattr(self, params, None)
0225 for param in params:
0226 lastParam = getattr(lastParam, param, None)
0227 if lastParam == None:
0228 return None
0229 return lastParam
0230
0231 def parameters_(self):
0232 """Returns a dictionary of copies of the user-set parameters"""
0233 import copy
0234 result = dict()
0235 for name in self.parameterNames_():
0236 result[name]=copy.deepcopy(self.__dict__[name])
0237 return result
0238
0239 def __addParameter(self, name, value):
0240 if name == 'allowAnyLabel_':
0241 self.__validator = value
0242 self._isModified = True
0243 return
0244 if not isinstance(value,_ParameterTypeBase):
0245 if self.__validator is not None:
0246 value = self.__validator.convert_(value)
0247 else:
0248 self.__raiseBadSetAttr(name)
0249 if name in self.__dict__:
0250 message = "Duplicate insert of member " + name
0251 message += "\nThe original parameters are:\n"
0252 message += self.dumpPython() + '\n'
0253 raise ValueError(message)
0254 self.__dict__[name]=value
0255 self.__parameterNames.append(name)
0256 self._isModified = True
0257
0258 def __setParameters(self,parameters):
0259 v = None
0260 for name,value in parameters.items():
0261 if name == 'allowAnyLabel_':
0262 v = value
0263 continue
0264 self.__addParameter(name, value)
0265 if v is not None:
0266 self.__validator=v
0267 def __setattr__(self,name,value):
0268
0269
0270 if self.isFrozen() and not (name in ["_Labelable__label","_isFrozen"] or name.startswith('_')):
0271 message = "Object already added to a process. It is read only now\n"
0272 message += " %s = %s" %(name, value)
0273 message += "\nThe original parameters are:\n"
0274 message += self.dumpPython() + '\n'
0275 raise ValueError(message)
0276
0277 if name[0]=='_':
0278 super(_Parameterizable,self).__setattr__(name,value)
0279 elif not name in self.__dict__:
0280 self.__addParameter(name, value)
0281 self._isModified = True
0282 else:
0283
0284 if isinstance(value,_ParameterTypeBase):
0285 self.__dict__[name] = self.__dict__[name]._checkAndReturnValueWithType(value)
0286 else:
0287 self.__dict__[name].setValue(value)
0288 self._isModified = True
0289
0290 def isFrozen(self):
0291 return self._isFrozen
0292 def setIsFrozen(self):
0293 self._isFrozen = True
0294 for name in self.parameterNames_():
0295 self.__dict__[name].setIsFrozen()
0296 def __delattr__(self,name):
0297 if self.isFrozen():
0298 raise ValueError("Object already added to a process. It is read only now")
0299 super(_Parameterizable,self).__delattr__(name)
0300 self.__parameterNames.remove(name)
0301 @staticmethod
0302 def __raiseBadSetAttr(name):
0303 raise TypeError(name+" does not already exist, so it can only be set to a CMS python configuration type")
0304 def dumpPython(self, options=PrintOptions()):
0305 specialImportRegistry.registerUse(self)
0306 sortedNames = sorted(self.parameterNames_())
0307 if len(sortedNames) > 200:
0308
0309
0310
0311
0312
0313
0314 others = []
0315 usings = []
0316 for name in sortedNames:
0317 param = self.__dict__[name]
0318
0319 name2 = name.replace('-','_')
0320 options.indent()
0321
0322 if name.startswith("using_"):
0323 usings.append(options.indentation()+param.dumpPython(options))
0324 else:
0325 others.append((name2, param.dumpPython(options)))
0326 options.unindent()
0327
0328 resultList = ',\n'.join(usings)
0329 longOthers = options.indentation()+"**dict(\n"
0330 options.indent()
0331 longOthers += options.indentation()+"[\n"
0332 entriesInList = 0
0333 options.indent()
0334 for n,v in others:
0335 entriesInList +=1
0336 if entriesInList > 200:
0337
0338 options.unindent()
0339 longOthers += options.indentation()+"] +\n"+options.indentation()+"[\n"
0340 entriesInList = 0
0341 options.indent()
0342 longOthers += options.indentation()+'("'+n+'" , '+v+' ),\n'
0343
0344 longOthers += options.indentation()+"]\n"
0345 options.unindent()
0346 longOthers +=options.indentation()+")\n"
0347 options.unindent()
0348 ret = []
0349 if resultList:
0350 ret.append(resultList)
0351 if longOthers:
0352 ret.append(longOthers)
0353 return ",\n".join(ret)
0354
0355 others = []
0356 usings = []
0357 for name in sortedNames:
0358 param = self.__dict__[name]
0359
0360 name2 = name.replace('-','_')
0361 options.indent()
0362
0363 if name.startswith("using_"):
0364 usings.append(options.indentation()+param.dumpPython(options))
0365 else:
0366 others.append(options.indentation()+name2+' = '+param.dumpPython(options))
0367 options.unindent()
0368
0369 resultList = usings
0370 resultList.extend(others)
0371 if self.__validator is not None:
0372 options.indent()
0373 resultList.append(options.indentation()+"allowAnyLabel_="+self.__validator.dumpPython(options))
0374 options.unindent()
0375 return ',\n'.join(resultList)+'\n'
0376 def __repr__(self):
0377 return self.dumpPython()
0378 def insertContentsInto(self, parameterSet):
0379 for name in self.parameterNames_():
0380 param = getattr(self,name)
0381 param.insertInto(parameterSet, name)
0382
0383
0384 class _TypedParameterizable(_Parameterizable):
0385 """Base class for classes which are Parameterizable and have a 'type' assigned"""
0386 def __init__(self,type_,*arg,**kargs):
0387 self.__dict__['_TypedParameterizable__type'] = type_
0388
0389
0390
0391
0392
0393 super(_TypedParameterizable,self).__init__(*arg,**kargs)
0394 saveOrigin(self, 1)
0395 def _place(self,name,proc):
0396 self._placeImpl(name,proc)
0397 def type_(self):
0398 """returns the type of the object, e.g. 'FooProducer'"""
0399 return self.__type
0400 def copy(self):
0401 returnValue =_TypedParameterizable.__new__(type(self))
0402 params = self.parameters_()
0403 returnValue.__init__(self.__type,**params)
0404 returnValue._isModified = self._isModified
0405 return returnValue
0406 def clone(self, *args, **params):
0407 """Copies the object and allows one to modify the parameters of the clone.
0408 New parameters may be added by specify the exact type
0409 Modifying existing parameters can be done by just specifying the new
0410 value without having to specify the type.
0411 A parameter may be removed from the clone using the value None.
0412 #remove the parameter foo.fred
0413 mod.toModify(foo, fred = None)
0414 A parameter embedded within a PSet may be changed via a dictionary
0415 #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
0416 mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
0417 """
0418 returnValue =_TypedParameterizable.__new__(type(self))
0419 myparams = self.parameters_()
0420
0421
0422 for block in args:
0423
0424 if type(block).__name__ not in ["PSet", "__PSet"]:
0425 raise ValueError("Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
0426 for name in block.parameterNames_():
0427 try:
0428 del myparams[name]
0429 except KeyError:
0430 pass
0431
0432 _modifyParametersFromDict(myparams, params, self._Parameterizable__raiseBadSetAttr)
0433 if self._Parameterizable__validator is not None:
0434 myparams["allowAnyLabel_"] = self._Parameterizable__validator
0435
0436 returnValue.__init__(self.__type,*args,
0437 **myparams)
0438 returnValue._isModified = False
0439 returnValue._isFrozen = False
0440 saveOrigin(returnValue, 1)
0441 return returnValue
0442
0443 @staticmethod
0444 def __findDefaultsFor(label,type):
0445
0446 import sys
0447 import glob
0448 choices = list()
0449 for d in sys.path:
0450 choices.extend(glob.glob(d+'/*/*/'+label+'.py'))
0451 if not choices:
0452 return None
0453
0454
0455
0456 for c in choices:
0457
0458 name='.'.join(c[:-3].split('/')[-3:])
0459
0460 mod = __import__(name)
0461 components = name.split('.')
0462 for comp in components[1:]:
0463 mod = getattr(mod,comp)
0464 if hasattr(mod,label):
0465 default = getattr(mod,label)
0466 if isinstance(default,_TypedParameterizable):
0467 if(default.type_() == type):
0468 params = dict()
0469 for name in default.parameterNames_():
0470 params[name] = getattr(default,name)
0471 return params
0472 return None
0473
0474 def directDependencies(self):
0475 return []
0476
0477 def dumpConfig(self, options=PrintOptions()):
0478 config = self.__type +' { \n'
0479 for name in self.parameterNames_():
0480 param = self.__dict__[name]
0481 options.indent()
0482 config+=options.indentation()+param.configTypeName()+' '+name+' = '+param.configValue(options)+'\n'
0483 options.unindent()
0484 config += options.indentation()+'}\n'
0485 return config
0486
0487 def dumpPython(self, options=PrintOptions()):
0488 specialImportRegistry.registerUse(self)
0489 result = "cms."+str(type(self).__name__)+'("'+self.type_()+'"'
0490 nparam = len(self.parameterNames_())
0491 if nparam == 0:
0492 result += ")\n"
0493 else:
0494 result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() + ")\n"
0495 return result
0496
0497 def dumpPythonAttributes(self, myname, options):
0498 """ dumps the object with all attributes declared after the constructor"""
0499 result = ""
0500 for name in sorted(self.parameterNames_()):
0501 param = self.__dict__[name]
0502 result += options.indentation() + myname + "." + name + " = " + param.dumpPython(options) + "\n"
0503 return result
0504
0505 def nameInProcessDesc_(self, myname):
0506 return myname;
0507 def moduleLabel_(self, myname):
0508 return myname
0509 def appendToProcessDescList_(self, lst, myname):
0510 lst.append(self.nameInProcessDesc_(myname))
0511 def insertInto(self, parameterSet, myname):
0512 newpset = parameterSet.newPSet()
0513 newpset.addString(True, "@module_label", self.moduleLabel_(myname))
0514 newpset.addString(True, "@module_type", self.type_())
0515 newpset.addString(True, "@module_edm_type", type(self).__name__)
0516 self.insertContentsInto(newpset)
0517 parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset)
0518
0519
0520
0521 class _Labelable(object):
0522 """A 'mixin' used to denote that the class can be paired with a label (e.g. an EDProducer)"""
0523 def label_(self):
0524 if not hasattr(self, "_Labelable__label"):
0525 raise RuntimeError("module has no label. Perhaps it wasn't inserted into the process?")
0526 return self.__label
0527 def hasLabel_(self):
0528 return hasattr(self, "_Labelable__label") and self.__label is not None
0529 def setLabel(self,label):
0530 if self.hasLabel_() :
0531 if self.label_() != label and label is not None :
0532 msg100 = "Attempting to change the label of a Labelable object, possibly an attribute of the Process\n"
0533 msg101 = "Old label = "+self.label_()+" New label = "+label+"\n"
0534 msg102 = "Type = "+str(type(self))+"\n"
0535 msg103 = "Some possible solutions:\n"
0536 msg104 = " 1. Clone modules instead of using simple assignment. Cloning is\n"
0537 msg105 = " also preferred for other types when possible.\n"
0538 msg106 = " 2. Declare new names starting with an underscore if they are\n"
0539 msg107 = " for temporaries you do not want propagated into the Process. The\n"
0540 msg108 = " underscore tells \"from x import *\" and process.load not to import\n"
0541 msg109 = " the name.\n"
0542 msg110 = " 3. Reorganize so the assigment is not necessary. Giving a second\n"
0543 msg111 = " name to the same object usually causes confusion and problems.\n"
0544 msg112 = " 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
0545 raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
0546 self.__label = label
0547 def label(self):
0548
0549 return self.__label
0550 def __str__(self):
0551
0552
0553
0554 return str(self.__label)
0555 def dumpSequenceConfig(self):
0556 return str(self.__label)
0557 def dumpSequencePython(self, options=PrintOptions()):
0558 if options.isCfg:
0559 return 'process.'+str(self.__label)
0560 else:
0561 return str(self.__label)
0562 def _findDependencies(self,knownDeps,presentDeps):
0563
0564 myDeps=knownDeps.get(self.label_(),None)
0565 if myDeps!=None:
0566 if presentDeps != myDeps:
0567 raise RuntimeError("the module "+self.label_()+" has two dependencies \n"
0568 +str(presentDeps)+"\n"
0569 +str(myDeps)+"\n"
0570 +"Please modify sequences to rectify this inconsistency")
0571 else:
0572 myDeps=set(presentDeps)
0573 knownDeps[self.label_()]=myDeps
0574 presentDeps.add(self.label_())
0575
0576
0577 class _Unlabelable(object):
0578 """A 'mixin' used to denote that the class can be used without a label (e.g. a Service)"""
0579 pass
0580
0581 class _ValidatingListBase(list):
0582 """Base class for a list which enforces that its entries pass a 'validity' test"""
0583 def __init__(self,*arg,**args):
0584 super(_ValidatingListBase,self).__init__(arg)
0585 if 0 != len(args):
0586 raise SyntaxError("named arguments ("+','.join([x for x in args])+") passsed to "+str(type(self)))
0587 if not type(self)._isValid(iter(self)):
0588 raise TypeError("wrong types ("+','.join([str(type(value)) for value in iter(self)])+
0589 ") added to "+str(type(self)))
0590 def __setitem__(self,key,value):
0591 if isinstance(key,slice):
0592 if not self._isValid(value):
0593 raise TypeError("wrong type being inserted into this container "+self._labelIfAny())
0594 else:
0595 if not self._itemIsValid(value):
0596 raise TypeError("can not insert the type "+str(type(value))+" in container "+self._labelIfAny())
0597 super(_ValidatingListBase,self).__setitem__(key,value)
0598 @classmethod
0599 def _isValid(cls,seq):
0600
0601 if isinstance(seq, str):
0602 return False
0603 for item in seq:
0604 if not cls._itemIsValid(item):
0605 return False
0606 return True
0607 def _itemFromArgument(self, x):
0608 return x
0609 def _convertArguments(self, seq):
0610 if isinstance(seq, str):
0611 yield seq
0612 for x in seq:
0613 yield self._itemFromArgument(x)
0614 def append(self,x):
0615 if not self._itemIsValid(x):
0616 raise TypeError("wrong type being appended to container "+self._labelIfAny())
0617 super(_ValidatingListBase,self).append(self._itemFromArgument(x))
0618 def extend(self,x):
0619 if not self._isValid(x):
0620 raise TypeError("wrong type being extended to container "+self._labelIfAny())
0621 super(_ValidatingListBase,self).extend(self._convertArguments(x))
0622 def __add__(self,rhs):
0623 if not self._isValid(rhs):
0624 raise TypeError("wrong type being added to container "+self._labelIfAny())
0625 import copy
0626 value = copy.copy(self)
0627 value.extend(rhs)
0628 return value
0629 def insert(self,i,x):
0630 if not self._itemIsValid(x):
0631 raise TypeError("wrong type being inserted to container "+self._labelIfAny())
0632 super(_ValidatingListBase,self).insert(i,self._itemFromArgument(x))
0633 def _labelIfAny(self):
0634 result = type(self).__name__
0635 if hasattr(self, '__label'):
0636 result += ' ' + self.__label
0637 return result
0638
0639 class _ValidatingParameterListBase(_ValidatingListBase,_ParameterTypeBase):
0640 def __init__(self,*arg,**args):
0641 _ParameterTypeBase.__init__(self)
0642 if len (arg) == 1 and not isinstance(arg[0],str):
0643 try:
0644 arg = iter(arg[0])
0645 except TypeError:
0646 pass
0647 super(_ValidatingParameterListBase,self).__init__(*arg,**args)
0648 def value(self):
0649 return list(self)
0650 def setValue(self,v):
0651 self[:] = []
0652 self.extend(v)
0653 self._isModified=True
0654 def configValue(self, options=PrintOptions()):
0655 config = '{\n'
0656 first = True
0657 for value in iter(self):
0658 options.indent()
0659 config += options.indentation()
0660 if not first:
0661 config+=', '
0662 config+= self.configValueForItem(value, options)+'\n'
0663 first = False
0664 options.unindent()
0665 config += options.indentation()+'}\n'
0666 return config
0667 def configValueForItem(self,item, options):
0668 return str(item)
0669 def pythonValueForItem(self,item, options):
0670 return self.configValueForItem(item, options)
0671 def __repr__(self):
0672 return self.dumpPython()
0673 def dumpPython(self, options=PrintOptions()):
0674 specialImportRegistry.registerUse(self)
0675 result = self.pythonTypeName()+"("
0676 n = len(self)
0677 if hasattr(self, "_nPerLine"):
0678 nPerLine = self._nPerLine
0679 else:
0680 nPerLine = 5
0681 if n>nPerLine: options.indent()
0682 if n>=256:
0683
0684 result+=" ("
0685 for i, v in enumerate(self):
0686 if i == 0:
0687 if n>nPerLine: result += '\n'+options.indentation()
0688 else:
0689 if i % nPerLine == 0:
0690 result += ',\n'+options.indentation()
0691 else:
0692 result += ', '
0693 result += self.pythonValueForItem(v,options)
0694 if n>nPerLine:
0695 options.unindent()
0696 result += '\n'+options.indentation()
0697 if n>=256:
0698 result +=' ) '
0699 result += ')'
0700 return result
0701 def directDependencies(self):
0702 return []
0703 @staticmethod
0704 def _itemsFromStrings(strings,converter):
0705 return (converter(x).value() for x in strings)
0706
0707 def saveOrigin(obj, level):
0708 import sys
0709 fInfo = inspect.getframeinfo(sys._getframe(level+1))
0710 obj._filename = fInfo.filename
0711 obj._lineNumber =fInfo.lineno
0712
0713 def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth=""):
0714 if len(newParams):
0715
0716 for key,value in newParams.items():
0717 if key in params:
0718 if value is None:
0719 del params[key]
0720 elif isinstance(value, dict):
0721 if isinstance(params[key],_Parameterizable):
0722 pset = params[key]
0723 p =pset.parameters_()
0724 oldkeys = set(p.keys())
0725 _modifyParametersFromDict(p,
0726 value,errorRaiser,
0727 ("%s.%s" if isinstance(key, str) else "%s[%s]")%(keyDepth,key))
0728 for k,v in p.items():
0729 setattr(pset,k,v)
0730 oldkeys.discard(k)
0731 for k in oldkeys:
0732 delattr(pset,k)
0733 elif isinstance(params[key],_ValidatingParameterListBase):
0734 if any(not isinstance(k, int) for k in value.keys()):
0735 raise TypeError("Attempted to change a list using a dict whose keys are not integers")
0736 plist = params[key]
0737 if any((k < 0 or k >= len(plist)) for k in value.keys()):
0738 raise IndexError("Attempted to set an index which is not in the list")
0739 p = dict(enumerate(plist))
0740 _modifyParametersFromDict(p,
0741 value,errorRaiser,
0742 ("%s.%s" if isinstance(key, str) else "%s[%s]")%(keyDepth,key))
0743 for k,v in p.items():
0744 plist[k] = v
0745 else:
0746 raise ValueError("Attempted to change non PSet value "+keyDepth+" using a dictionary")
0747 elif isinstance(value,_ParameterTypeBase) or (isinstance(key, int)) or isinstance(value, _Parameterizable):
0748 params[key] = value
0749 else:
0750 params[key].setValue(value)
0751 else:
0752 if isinstance(value,_ParameterTypeBase) or isinstance(value, _Parameterizable):
0753 params[key]=value
0754 else:
0755 errorRaiser(key)
0756
0757
0758 if __name__ == "__main__":
0759
0760 import unittest
0761 class TestList(_ValidatingParameterListBase):
0762 @classmethod
0763 def _itemIsValid(cls,item):
0764 return True
0765 class testMixins(unittest.TestCase):
0766 def testListConstruction(self):
0767 t = TestList(1)
0768 self.assertEqual(t,[1])
0769 t = TestList((1,))
0770 self.assertEqual(t,[1])
0771 t = TestList("one")
0772 self.assertEqual(t,["one"])
0773 t = TestList( [1,])
0774 self.assertEqual(t,[1])
0775 t = TestList( (x for x in [1]) )
0776 self.assertEqual(t,[1])
0777
0778 t = TestList(1,2)
0779 self.assertEqual(t,[1,2])
0780 t = TestList((1,2))
0781 self.assertEqual(t,[1,2])
0782 t = TestList("one","two")
0783 self.assertEqual(t,["one","two"])
0784 t = TestList(("one","two"))
0785 self.assertEqual(t,["one","two"])
0786 t = TestList( [1,2])
0787 self.assertEqual(t,[1,2])
0788 t = TestList( (x for x in [1,2]) )
0789 self.assertEqual(t,[1,2])
0790 t = TestList( iter((1,2)) )
0791 self.assertEqual(t,[1,2])
0792
0793
0794 def testLargeList(self):
0795
0796
0797 args = [i for i in range(0,300)]
0798
0799 t = TestList(*args)
0800 pdump= t.dumpPython()
0801 class cms(object):
0802 def __init__(self):
0803 self.TestList = TestList
0804 pythonized = eval( pdump, globals(),{'cms':cms()} )
0805 self.assertEqual(t,pythonized)
0806 def testUsingBlock(self):
0807 a = UsingBlock("a")
0808 self.assertTrue(isinstance(a, _ParameterTypeBase))
0809 def testConstruction(self):
0810 class __Test(_TypedParameterizable):
0811 pass
0812 class __TestType(_SimpleParameterTypeBase):
0813 def _isValid(self,value):
0814 return True
0815 class __PSet(_ParameterTypeBase,_Parameterizable):
0816 def __init__(self,*arg,**args):
0817
0818 _ParameterTypeBase.__init__(self)
0819 _Parameterizable.__init__(self,*arg,**args)
0820
0821 a = __Test("MyType", __PSet(a=__TestType(1)))
0822 self.assertEqual(a.a.value(), 1)
0823 b = __Test("MyType", __PSet(a=__TestType(1)), __PSet(b=__TestType(2)))
0824 self.assertEqual(b.a.value(), 1)
0825 self.assertEqual(b.b.value(), 2)
0826 self.assertRaises(ValueError, lambda: __Test("MyType", __PSet(a=__TestType(1)), __PSet(a=__TestType(2))))
0827
0828 def testCopy(self):
0829 class __Test(_TypedParameterizable):
0830 pass
0831 class __TestType(_SimpleParameterTypeBase):
0832 def _isValid(self,value):
0833 return True
0834 a = __Test("MyType",t=__TestType(1), u=__TestType(2))
0835 b = a.copy()
0836 self.assertEqual(b.t.value(),1)
0837 self.assertEqual(b.u.value(),2)
0838
0839 c = __Test("MyType")
0840 self.assertEqual(len(c.parameterNames_()), 0)
0841 d = c.copy()
0842 self.assertEqual(len(d.parameterNames_()), 0)
0843 def testClone(self):
0844 class __Test(_TypedParameterizable):
0845 pass
0846 class __TestType(_SimpleParameterTypeBase):
0847 def _isValid(self,value):
0848 return True
0849 class __PSet(_ParameterTypeBase,_Parameterizable):
0850 def __init__(self,*arg,**args):
0851
0852 _ParameterTypeBase.__init__(self)
0853 _Parameterizable.__init__(self,*arg,**args)
0854 def dumpPython(self,options=PrintOptions()):
0855 return "__PSet(\n"+_Parameterizable.dumpPython(self, options)+options.indentation()+")"
0856
0857 a = __Test("MyType",
0858 t=__TestType(1),
0859 u=__TestType(2),
0860 w = __TestType(3),
0861 x = __PSet(a = __TestType(4),
0862 b = __TestType(6),
0863 c = __PSet(gamma = __TestType(5))))
0864 b = a.clone(t=3,
0865 v=__TestType(4),
0866 w= None,
0867 x = dict(a = 7,
0868 c = dict(gamma = 8),
0869 d = __TestType(9)))
0870 c = a.clone(x = dict(a=None, c=None))
0871 self.assertEqual(a.t.value(),1)
0872 self.assertEqual(a.u.value(),2)
0873 self.assertEqual(b.t.value(),3)
0874 self.assertEqual(b.u.value(),2)
0875 self.assertEqual(b.v.value(),4)
0876 self.assertEqual(b.x.a.value(),7)
0877 self.assertEqual(b.x.b.value(),6)
0878 self.assertEqual(b.x.c.gamma.value(),8)
0879 self.assertEqual(b.x.d.value(),9)
0880 self.assertEqual(hasattr(b,"w"), False)
0881 self.assertEqual(hasattr(c.x,"a"), False)
0882 self.assertEqual(hasattr(c.x,"c"), False)
0883 self.assertRaises(TypeError,a.clone,**{"v":1})
0884 d = a.clone(__PSet(k=__TestType(42)))
0885 self.assertEqual(d.t.value(), 1)
0886 self.assertEqual(d.k.value(), 42)
0887 d2 = a.clone(__PSet(t=__TestType(42)))
0888 self.assertEqual(d2.t.value(), 42)
0889 d3 = a.clone(__PSet(t=__TestType(42)),
0890 __PSet(u=__TestType(56)))
0891 self.assertEqual(d3.t.value(), 42)
0892 self.assertEqual(d3.u.value(), 56)
0893 self.assertRaises(ValueError,a.clone,
0894 __PSet(t=__TestType(42)),
0895 __PSet(t=__TestType(56)))
0896 d4 = a.clone(__PSet(t=__TestType(43)), u = 57)
0897 self.assertEqual(d4.t.value(), 43)
0898 self.assertEqual(d4.u.value(), 57)
0899 self.assertRaises(TypeError,a.clone,t=__TestType(43),**{"doesNotExist":57})
0900
0901 e = __Test("MyType")
0902 self.assertEqual(len(e.parameterNames_()), 0)
0903 f = e.clone(__PSet(a = __TestType(1)), b = __TestType(2))
0904 self.assertEqual(f.a.value(), 1)
0905 self.assertEqual(f.b.value(), 2)
0906 g = e.clone()
0907 self.assertEqual(len(g.parameterNames_()), 0)
0908
0909 def testModified(self):
0910 class __TestType(_SimpleParameterTypeBase):
0911 def _isValid(self,value):
0912 return True
0913 a = __TestType(1)
0914 self.assertEqual(a.isModified(),False)
0915 a.setValue(1)
0916 self.assertEqual(a.isModified(),False)
0917 a.setValue(2)
0918 self.assertEqual(a.isModified(),True)
0919 a.resetModified()
0920 self.assertEqual(a.isModified(),False)
0921 def testLargeParameterizable(self):
0922 class tLPTest(_TypedParameterizable):
0923 pass
0924 class tLPTestType(_SimpleParameterTypeBase):
0925 def _isValid(self,value):
0926 return True
0927 class __DummyModule(object):
0928 def __init__(self):
0929 self.tLPTest = tLPTest
0930 self.tLPTestType = tLPTestType
0931 p = tLPTest("MyType",** dict( [ ("a"+str(x), tLPTestType(x)) for x in range(0,300) ] ) )
0932
0933 self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{"cms": __DummyModule()}).dumpPython())
0934 def testSpecialImportRegistry(self):
0935 reg = _SpecialImportRegistry()
0936 reg.registerSpecialImportForType(int, "import foo")
0937 self.assertRaises(RuntimeError, lambda: reg.registerSpecialImportForType(int, "import bar"))
0938 reg.registerSpecialImportForType(str, "import bar")
0939 self.assertEqual(reg.getSpecialImports(), [])
0940 reg.registerUse([1])
0941 self.assertEqual(reg.getSpecialImports(), [])
0942 reg.registerUse(1)
0943 self.assertEqual(reg.getSpecialImports(), ["import foo"])
0944 reg.registerUse(1)
0945 self.assertEqual(reg.getSpecialImports(), ["import foo"])
0946 reg.registerUse("a")
0947 self.assertEqual(reg.getSpecialImports(), ["import bar", "import foo"])
0948 def testInvalidTypeChange(self):
0949 class __Test(_TypedParameterizable):
0950 pass
0951 class __TestTypeA(_SimpleParameterTypeBase):
0952 def _isValid(self,value):
0953 return True
0954 class __TestTypeB(_SimpleParameterTypeBase):
0955 def _isValid(self,value):
0956 return True
0957 pass
0958 a = __Test("MyType",
0959 t=__TestTypeA(1))
0960 self.assertRaises(TypeError, lambda : setattr(a,'t',__TestTypeB(2)))
0961
0962
0963 unittest.main()