CMS 3D CMS Logo

Mixins.py
Go to the documentation of this file.
1 from __future__ import print_function
2 from builtins import range, object
3 import inspect
4 from typing import Union
5 
7  """Denotes a class that can be used by the Processes class"""
8  def _isTaskComponent(self) -> bool:
9  return False
10 
12  def __init__(self, indent:int = 0, deltaIndent:int = 4, process:bool = True, targetDirectory: Union[str, None] = None, useSubdirectories:bool = False):
13  self.indent_= indent
14  self.deltaIndent_ = deltaIndent
15  self.isCfg = process
16  self.targetDirectory = targetDirectory
17  self.useSubdirectories = useSubdirectories
18  def indentation(self) -> str:
19  return ' '*self.indent_
20  def indent(self):
21  self.indent_ += self.deltaIndent_
22  def unindent(self):
23  self.indent_ -= self.deltaIndent_
24 
26  """This class collects special import statements of configuration types"""
27  def __init__(self):
28  self._registry = {}
29 
30  def _reset(self):
31  for lst in self._registry.values():
32  lst[1] = False
33 
34  def registerSpecialImportForType(self, cls, impStatement):
35  className = cls.__name__
36  if className in self._registry:
37  raise RuntimeError("Error: the configuration type '%s' already has an import statement registered '%s'" % (className, self._registry[className][0]))
38  self._registry[className] = [impStatement, False]
39 
40  def registerUse(self, obj):
41  className = obj.__class__.__name__
42  try:
43  self._registry[className][1] = True
44  except KeyError:
45  pass
46 
47  def getSpecialImports(self):
48  coll = set()
49  for (imp, used) in self._registry.values():
50  if used:
51  coll.add(imp)
52  return sorted(coll)
53 
54 specialImportRegistry = _SpecialImportRegistry()
55 
57  """base class for classes which are used as the 'parameters' for a ParameterSet"""
58  def __init__(self):
59  self.__dict__["_isFrozen"] = False
60  self.__isTracked = True
61  self._isModified = False
62  def isModified(self) -> bool:
63  return self._isModified
64  def resetModified(self):
65  self._isModified=False
66  def configTypeName(self) -> str:
67  if self.isTracked():
68  return type(self).__name__
69  return 'untracked '+type(self).__name__
70  def pythonTypeName(self) -> str:
71  if self.isTracked():
72  return 'cms.'+type(self).__name__
73  return 'cms.untracked.'+type(self).__name__
74  def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
75  specialImportRegistry.registerUse(self)
76  return self.pythonTypeName()+"("+self.pythonValue(options)+")"
77  def __repr__(self) -> str:
78  return self.dumpPython()
79  def isTracked(self) -> bool:
80  return self.__isTracked
81  def setIsTracked(self,trackness:bool):
82  self.__isTracked = trackness
83  def isFrozen(self) -> bool:
84  return self._isFrozen
85  def setIsFrozen(self):
86  self._isFrozen = True
87  def isCompatibleCMSType(self,aType) -> bool:
88  return isinstance(self,aType)
89  def _checkAndReturnValueWithType(self, valueWithType):
90  if isinstance(valueWithType, type(self)):
91  return valueWithType
92  raise TypeError("Attempted to assign type {from_} to type {to}".format(from_ = str(type(valueWithType)), to = str(type(self))) )
93 
94 
96  """base class for parameter classes which only hold a single value"""
97  def __init__(self,value):
98  super(_SimpleParameterTypeBase,self).__init__()
99  self._value = value
100  if not self._isValid(value):
101  raise ValueError(str(value)+" is not a valid "+str(type(self)))
102  def value(self):
103  return self._value
104  def setValue(self,value):
105  if not self._isValid(value):
106  raise ValueError(str(value)+" is not a valid "+str(type(self)))
107  if value!=self._value:
108  self._isModified=True
109  self._value=value
110  def configValue(self, options:PrintOptions=PrintOptions()) -> str:
111  return str(self._value)
112  def pythonValue(self, options:PrintOptions=PrintOptions()) -> str:
113  return self.configValue(options)
114  def __eq__(self,other) -> bool:
115  if isinstance(other,_SimpleParameterTypeBase):
116  return self._value == other._value
117  return self._value == other
118  def __ne__(self,other) -> bool:
119  if isinstance(other,_SimpleParameterTypeBase):
120  return self._value != other._value
121  return self._value != other
122  def __lt__(self,other) -> bool:
123  if isinstance(other,_SimpleParameterTypeBase):
124  return self._value < other._value
125  return self._value < other
126  def __le__(self,other) -> bool:
127  if isinstance(other,_SimpleParameterTypeBase):
128  return self._value <= other._value
129  return self._value <= other
130  def __gt__(self,other) -> bool:
131  if isinstance(other,_SimpleParameterTypeBase):
132  return self._value > other._value
133  return self._value > other
134  def __ge__(self,other) -> bool:
135  if isinstance(other,_SimpleParameterTypeBase):
136  return self._value >= other._value
137  return self._value >= other
138 
139 
141  """For injection purposes, pretend this is a new parameter type
142  then have a post process step which strips these out
143  """
144  def __init__(self,value, s:str='', loc:int=0, file:str=''):
145  super(UsingBlock,self).__init__(value)
146  self.s = s
147  self.loc = loc
148  self.file = file
149  self.isResolved = False
150  @staticmethod
151  def _isValid(value) -> bool:
152  return isinstance(value,str)
153  def _valueFromString(value) -> str:
154  """only used for cfg-parsing"""
155  return str(value)
156  def insertInto(self, parameterSet, myname:str):
157  value = self.value()
158  # doesn't seem to handle \0 correctly
159  #if value == '\0':
160  # value = ''
161  parameterSet.addString(self.isTracked(), myname, value)
162  def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
163  if options.isCfg:
164  return "process."+self.value()
165  else:
166  return self.value()
167 
168 
170  """Base class for classes which allow addition of _ParameterTypeBase data"""
171  def __init__(self,*arg,**kargs):
172  self.__dict__['_Parameterizable__parameterNames'] = []
173  self.__dict__["_isFrozen"] = False
174  self.__dict__['_Parameterizable__validator'] = None
175  """The named arguments are the 'parameters' which are added as 'python attributes' to the object"""
176  if len(arg) != 0:
177  self.__setParametersFromArg(*arg)
178  self.__setParameters(kargs)
179  self._isModified = False
180 
181  def parameterNames_(self):
182  """Returns the name of the parameters"""
183  return self.__parameterNames[:]
184  def isModified(self) -> bool:
185  if self._isModified:
186  return True
187  for name in self.parameterNames_():
188  param = self.__dict__[name]
189  if isinstance(param, _Parameterizable) and param.isModified():
190  self._isModified = True
191  return True
192  return False
193 
194  def hasParameter(self, params) -> bool:
195  """
196  _hasParameter_
197 
198  check that pset provided has the attribute chain
199  specified.
200 
201  Eg, if params is [ 'attr1', 'attr2', 'attr3' ]
202  check for pset.attr1.attr2.attr3
203 
204  returns True if parameter exists, False if not
205  """
206  return (self.getParameter(params) != None)
207 
208  def getParameter(self, params):
209  """
210  _getParameter_
211 
212  Retrieve the specified parameter from the PSet Provided
213  given the attribute chain
214 
215  returns None if not found
216  """
217  lastParam = self
218  # Don't accidentally iterate over letters in a string
219  if type(params).__name__ == 'str':
220  return getattr(self, params, None)
221  for param in params:
222  lastParam = getattr(lastParam, param, None)
223  if lastParam == None:
224  return None
225  return lastParam
226 
227  def parameters_(self):
228  """Returns a dictionary of copies of the user-set parameters"""
229  import copy
230  result = dict()
231  for name in self.parameterNames_():
232  result[name]=copy.deepcopy(self.__dict__[name])
233  return result
234 
235  def __addParameter(self, name:str, value):
236  if name == 'allowAnyLabel_':
237  self.__validator = value
238  self._isModified = True
239  return
240  if not isinstance(value,_ParameterTypeBase):
241  if self.__validator is not None:
242  value = self.__validator.convert_(value)
243  else:
244  self.__raiseBadSetAttr(name)
245  if name in self.__dict__:
246  message = "Duplicate insert of member " + name
247  message += "\nThe original parameters are:\n"
248  message += self.dumpPython() + '\n'
249  raise ValueError(message)
250  self.__dict__[name]=value
251  self.__parameterNames.append(name)
252  self._isModified = True
253  def __setParametersFromArg(self, *arg):
254  for block in arg:
255  # Allow __PSet for testing
256  if type(block).__name__ not in ["PSet", "__PSet", "dict"]:
257  raise ValueError("Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
258  if isinstance(block,dict):
259  self.__setParameters(block)
260  else:
261  self.__setParameters(block.parameters_())
262 
263  def __setParameters(self,parameters):
264  v = None
265  for name,value in parameters.items():
266  if name == 'allowAnyLabel_':
267  v = value
268  continue
269  self.__addParameter(name, value)
270  if v is not None:
271  self.__validator=v
272  def __setattr__(self,name:str,value):
273  #since labels are not supposed to have underscores at the beginning
274  # I will assume that if we have such then we are setting an internal variable
275  if self.isFrozen() and not (name in ["_Labelable__label","_isFrozen"] or name.startswith('_')):
276  message = "Object already added to a process. It is read only now\n"
277  message += " %s = %s" %(name, value)
278  message += "\nThe original parameters are:\n"
279  message += self.dumpPython() + '\n'
280  raise ValueError(message)
281  # underscored names bypass checking for _ParameterTypeBase
282  if name[0]=='_':
283  super(_Parameterizable,self).__setattr__(name,value)
284  elif not name in self.__dict__:
285  self.__addParameter(name, value)
286  self._isModified = True
287  else:
288  # handle the case where users just replace with a value, a = 12, rather than a = cms.int32(12)
289  if isinstance(value,_ParameterTypeBase):
290  self.__dict__[name] = self.__dict__[name]._checkAndReturnValueWithType(value)
291  else:
292  self.__dict__[name].setValue(value)
293  self._isModified = True
294  def update_(self, d):
295  """"Takes a PSet or dict and adds the entries as parameters. Already existing parameters will be overwritten.
296  """
297  if type(d).__name__ not in ["PSet", "__PSet", "dict"]:
298  raise ValueError("Only PSets or dicts can be passed to update_. This is a "+type(d).__name__)
299 
300  items = d.items() if isinstance(d, dict) else d.parameters_().items()
301  for k,v in items:
302  setattr(self, k, v)
303 
304 
305 
306  def isFrozen(self) -> bool:
307  return self._isFrozen
308  def setIsFrozen(self):
309  self._isFrozen = True
310  for name in self.parameterNames_():
311  self.__dict__[name].setIsFrozen()
312  def __delattr__(self,name:str):
313  if self.isFrozen():
314  raise ValueError("Object already added to a process. It is read only now")
315  super(_Parameterizable,self).__delattr__(name)
316  self.__parameterNames.remove(name)
317  @staticmethod
318  def __raiseBadSetAttr(name:str):
319  raise TypeError(name+" does not already exist, so it can only be set to a CMS python configuration type")
320  def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
321  specialImportRegistry.registerUse(self)
322  sortedNames = sorted(self.parameterNames_())
323  if len(sortedNames) > 200:
324  #Too many parameters for a python function call
325  # The solution is to create a temporary dictionary which
326  # is constructed by concatenating long lists (with maximum
327  # 200 entries each) together.
328  # This looks like
329  # **dict( [(...,...), ...] + [...] + ... )
330  others = []
331  usings = []
332  for name in sortedNames:
333  param = self.__dict__[name]
334  # we don't want minuses in names
335  name2 = name.replace('-','_')
336  options.indent()
337  #_UsingNodes don't get assigned variables
338  if name.startswith("using_"):
339  usings.append(options.indentation()+param.dumpPython(options))
340  else:
341  others.append((name2, param.dumpPython(options)))
342  options.unindent()
343 
344  resultList = ',\n'.join(usings)
345  longOthers = options.indentation()+"**dict(\n"
346  options.indent()
347  longOthers += options.indentation()+"[\n"
348  entriesInList = 0
349  options.indent()
350  for n,v in others:
351  entriesInList +=1
352  if entriesInList > 200:
353  #need to start a new list
354  options.unindent()
355  longOthers += options.indentation()+"] +\n"+options.indentation()+"[\n"
356  entriesInList = 0
357  options.indent()
358  longOthers += options.indentation()+'("'+n+'" , '+v+' ),\n'
359 
360  longOthers += options.indentation()+"]\n"
361  options.unindent()
362  longOthers +=options.indentation()+")\n"
363  options.unindent()
364  ret = []
365  if resultList:
366  ret.append(resultList)
367  if longOthers:
368  ret.append(longOthers)
369  return ",\n".join(ret)
370  #Standard case, small number of parameters
371  others = []
372  usings = []
373  for name in sortedNames:
374  param = self.__dict__[name]
375  # we don't want minuses in names
376  name2 = name.replace('-','_')
377  options.indent()
378  #_UsingNodes don't get assigned variables
379  if name.startswith("using_"):
380  usings.append(options.indentation()+param.dumpPython(options))
381  else:
382  others.append(options.indentation()+name2+' = '+param.dumpPython(options))
383  options.unindent()
384  # usings need to go first
385  resultList = usings
386  resultList.extend(others)
387  if self.__validator is not None:
388  options.indent()
389  resultList.append(options.indentation()+"allowAnyLabel_="+self.__validator.dumpPython(options))
390  options.unindent()
391  return ',\n'.join(resultList)+'\n'
392  def __repr__(self) -> str:
393  return self.dumpPython()
394  def insertContentsInto(self, parameterSet):
395  for name in self.parameterNames_():
396  param = getattr(self,name)
397  param.insertInto(parameterSet, name)
398 
399 
401  """Base class for classes which are Parameterizable and have a 'type' assigned"""
402  def __init__(self,type_,*arg,**kargs):
403  self.__dict__['_TypedParameterizable__type'] = type_
404  #the 'type' is also placed in the 'arg' list and we need to remove it
405  #if 'type_' not in kargs:
406  # arg = arg[1:]
407  #else:
408  # del args['type_']
409  super(_TypedParameterizable,self).__init__(*arg,**kargs)
410  saveOrigin(self, 1)
411  def _place(self,name:str,proc):
412  self._placeImpl(name,proc)
413  def type_(self):
414  """returns the type of the object, e.g. 'FooProducer'"""
415  return self.__type
416  def copy(self):
417  returnValue =_TypedParameterizable.__new__(type(self))
418  params = self.parameters_()
419  returnValue.__init__(self.__type,**params)
420  returnValue._isModified = self._isModified
421  return returnValue
422  def clone(self, *args, **params):
423  """Copies the object and allows one to modify the parameters of the clone.
424  New parameters may be added by specify the exact type
425  Modifying existing parameters can be done by just specifying the new
426  value without having to specify the type.
427  A parameter may be removed from the clone using the value None.
428  #remove the parameter foo.fred
429  mod.toModify(foo, fred = None)
430  A parameter embedded within a PSet may be changed via a dictionary
431  #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
432  mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
433  """
434  returnValue =_TypedParameterizable.__new__(type(self))
435  myparams = self.parameters_()
436 
437  # Prefer parameters given in PSet blocks over those in clone-from module
438  for block in args:
439  # Allow __PSet for testing
440  if type(block).__name__ not in ["PSet", "__PSet"]:
441  raise ValueError("Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
442  for name in block.parameterNames_():
443  try:
444  del myparams[name]
445  except KeyError:
446  pass
447 
448  _modifyParametersFromDict(myparams, params, self._Parameterizable__raiseBadSetAttr)
449  if self._Parameterizable__validator is not None:
450  myparams["allowAnyLabel_"] = self._Parameterizable__validator
451 
452  returnValue.__init__(self.__type,*args,
453  **myparams)
454  returnValue._isModified = False
455  returnValue._isFrozen = False
456  saveOrigin(returnValue, 1)
457  return returnValue
458 
459  @staticmethod
460  def __findDefaultsFor(label:str,type):
461  #This routine is no longer used, but I might revive it in the future
462  import sys
463  import glob
464  choices = list()
465  for d in sys.path:
466  choices.extend(glob.glob(d+'/*/*/'+label+'.py'))
467  if not choices:
468  return None
469  #now see if any of them have what we want
470  #the use of __import__ is taken from an example
471  # from the www.python.org documentation on __import__
472  for c in choices:
473  #print " found file "+c
474  name='.'.join(c[:-3].split('/')[-3:])
475  #name = c[:-3].replace('/','.')
476  mod = __import__(name)
477  components = name.split('.')
478  for comp in components[1:]:
479  mod = getattr(mod,comp)
480  if hasattr(mod,label):
481  default = getattr(mod,label)
482  if isinstance(default,_TypedParameterizable):
483  if(default.type_() == type):
484  params = dict()
485  for name in default.parameterNames_():
486  params[name] = getattr(default,name)
487  return params
488  return None
489 
491  return []
492 
493  def dumpConfig(self, options:PrintOptions=PrintOptions()) -> str:
494  config = self.__type +' { \n'
495  for name in self.parameterNames_():
496  param = self.__dict__[name]
497  options.indent()
498  config+=options.indentation()+param.configTypeName()+' '+name+' = '+param.configValue(options)+'\n'
499  options.unindent()
500  config += options.indentation()+'}\n'
501  return config
502 
503  def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
504  specialImportRegistry.registerUse(self)
505  result = "cms."+str(type(self).__name__)+'("'+self.type_()+'"'
506  nparam = len(self.parameterNames_())
507  if nparam == 0:
508  result += ")\n"
509  else:
510  result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() + ")\n"
511  return result
512 
513  def dumpPythonAttributes(self, myname:str, options:PrintOptions) -> str:
514  """ dumps the object with all attributes declared after the constructor"""
515  result = ""
516  for name in sorted(self.parameterNames_()):
517  param = self.__dict__[name]
518  result += options.indentation() + myname + "." + name + " = " + param.dumpPython(options) + "\n"
519  return result
520 
521  def nameInProcessDesc_(self, myname:str):
522  return myname;
523  def moduleLabel_(self, myname:str):
524  return myname
525  def appendToProcessDescList_(self, lst, myname:str):
526  lst.append(self.nameInProcessDesc_(myname))
527  def insertInto(self, parameterSet, myname:str):
528  newpset = parameterSet.newPSet()
529  newpset.addString(True, "@module_label", self.moduleLabel_(myname))
530  newpset.addString(True, "@module_type", self.type_())
531  newpset.addString(True, "@module_edm_type", type(self).__name__)
532  self.insertContentsInto(newpset)
533  parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset)
534 
535 
536 
538  """A 'mixin' used to denote that the class can be paired with a label (e.g. an EDProducer)"""
539  def label_(self) -> str:
540  if not hasattr(self, "_Labelable__label"):
541  raise RuntimeError("module has no label. Perhaps it wasn't inserted into the process?")
542  return self.__label
543  def hasLabel_(self) -> bool:
544  return hasattr(self, "_Labelable__label") and self.__label is not None
545  def setLabel(self,label:str):
546  if self.hasLabel_() :
547  if self.label_() != label and label is not None :
548  msg100 = "Attempting to change the label of a Labelable object, possibly an attribute of the Process\n"
549  msg101 = "Old label = "+self.label_()+" New label = "+label+"\n"
550  msg102 = "Type = "+str(type(self))+"\n"
551  msg103 = "Some possible solutions:\n"
552  msg104 = " 1. Clone modules instead of using simple assignment. Cloning is\n"
553  msg105 = " also preferred for other types when possible.\n"
554  msg106 = " 2. Declare new names starting with an underscore if they are\n"
555  msg107 = " for temporaries you do not want propagated into the Process. The\n"
556  msg108 = " underscore tells \"from x import *\" and process.load not to import\n"
557  msg109 = " the name.\n"
558  msg110 = " 3. Reorganize so the assigment is not necessary. Giving a second\n"
559  msg111 = " name to the same object usually causes confusion and problems.\n"
560  msg112 = " 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
561  raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
562  self.__label = label
563  def label(self) -> str:
564  #print "WARNING: _Labelable::label() needs to be changed to label_()"
565  return self.__label
566  def __str__(self):
567  #this is probably a bad idea
568  # I added this so that when we ask a path to print
569  # we will see the label that has been assigned
570  return str(self.__label)
572  return str(self.__label)
573  def dumpSequencePython(self, options:PrintOptions=PrintOptions()):
574  if options.isCfg:
575  return 'process.'+str(self.__label)
576  else:
577  return str(self.__label)
578  def _findDependencies(self,knownDeps,presentDeps):
579  #print 'in labelled'
580  myDeps=knownDeps.get(self.label_(),None)
581  if myDeps!=None:
582  if presentDeps != myDeps:
583  raise RuntimeError("the module "+self.label_()+" has two dependencies \n"
584  +str(presentDeps)+"\n"
585  +str(myDeps)+"\n"
586  +"Please modify sequences to rectify this inconsistency")
587  else:
588  myDeps=set(presentDeps)
589  knownDeps[self.label_()]=myDeps
590  presentDeps.add(self.label_())
591 
592 
594  """A 'mixin' used to denote that the class can be used without a label (e.g. a Service)"""
595  pass
596 
597 class _ValidatingListBase(list):
598  """Base class for a list which enforces that its entries pass a 'validity' test"""
599  def __init__(self,*arg,**args):
600  super(_ValidatingListBase,self).__init__(arg)
601  if 0 != len(args):
602  raise SyntaxError("named arguments ("+','.join([x for x in args])+") passsed to "+str(type(self)))
603  if not type(self)._isValid(iter(self)):
604  raise TypeError("wrong types ("+','.join([str(type(value)) for value in iter(self)])+
605  ") added to "+str(type(self)))
606  def __setitem__(self,key,value):
607  if isinstance(key,slice):
608  if not self._isValid(value):
609  raise TypeError("wrong type being inserted into this container "+self._labelIfAny())
610  else:
611  if not self._itemIsValid(value):
612  raise TypeError("can not insert the type "+str(type(value))+" in container "+self._labelIfAny())
613  super(_ValidatingListBase,self).__setitem__(key,value)
614  @classmethod
615  def _isValid(cls,seq) -> bool:
616  # see if strings get reinterpreted as lists
617  if isinstance(seq, str):
618  return False
619  for item in seq:
620  if not cls._itemIsValid(item):
621  return False
622  return True
623  def _itemFromArgument(self, x):
624  return x
625  def _convertArguments(self, seq):
626  if isinstance(seq, str):
627  yield seq
628  for x in seq:
629  yield self._itemFromArgument(x)
630  def append(self,x):
631  if not self._itemIsValid(x):
632  raise TypeError("wrong type being appended to container "+self._labelIfAny())
633  super(_ValidatingListBase,self).append(self._itemFromArgument(x))
634  def extend(self,x):
635  if not self._isValid(x):
636  raise TypeError("wrong type being extended to container "+self._labelIfAny())
637  super(_ValidatingListBase,self).extend(self._convertArguments(x))
638  def __add__(self,rhs):
639  if not self._isValid(rhs):
640  raise TypeError("wrong type being added to container "+self._labelIfAny())
641  import copy
642  value = copy.copy(self)
643  value.extend(rhs)
644  return value
645  def insert(self,i,x):
646  if not self._itemIsValid(x):
647  raise TypeError("wrong type being inserted to container "+self._labelIfAny())
648  super(_ValidatingListBase,self).insert(i,self._itemFromArgument(x))
649  def _labelIfAny(self) -> str:
650  result = type(self).__name__
651  if hasattr(self, '__label'):
652  result += ' ' + self.__label
653  return result
654 
656  def __init__(self,*arg,**args):
657  _ParameterTypeBase.__init__(self)
658  if len (arg) == 1 and not isinstance(arg[0],str):
659  try:
660  arg = iter(arg[0])
661  except TypeError:
662  pass
663  super(_ValidatingParameterListBase,self).__init__(*arg,**args)
664  def value(self):
665  return list(self)
666  def setValue(self,v):
667  self[:] = []
668  self.extend(v)
669  self._isModified=True
670  def configValue(self, options:PrintOptions=PrintOptions()) -> str:
671  config = '{\n'
672  first = True
673  for value in iter(self):
674  options.indent()
675  config += options.indentation()
676  if not first:
677  config+=', '
678  config+= self.configValueForItem(value, options)+'\n'
679  first = False
680  options.unindent()
681  config += options.indentation()+'}\n'
682  return config
683  def configValueForItem(self,item, options:PrintOptions) -> str:
684  return str(item)
685  def pythonValueForItem(self,item, options:PrintOptions) -> str:
686  return self.configValueForItem(item, options)
687  def __repr__(self):
688  return self.dumpPython()
689  def dumpPython(self, options:PrintOptions=PrintOptions()) -> str:
690  specialImportRegistry.registerUse(self)
691  result = self.pythonTypeName()+"("
692  n = len(self)
693  if hasattr(self, "_nPerLine"):
694  nPerLine = self._nPerLine
695  else:
696  nPerLine = 5
697  if n>nPerLine: options.indent()
698  if n>=256:
699  #wrap in a tuple since they don't have a size constraint
700  result+=" ("
701  for i, v in enumerate(self):
702  if i == 0:
703  if n>nPerLine: result += '\n'+options.indentation()
704  else:
705  if i % nPerLine == 0:
706  result += ',\n'+options.indentation()
707  else:
708  result += ', '
709  result += self.pythonValueForItem(v,options)
710  if n>nPerLine:
711  options.unindent()
712  result += '\n'+options.indentation()
713  if n>=256:
714  result +=' ) '
715  result += ')'
716  return result
718  return []
719  @staticmethod
720  def _itemsFromStrings(strings,converter):
721  return (converter(x).value() for x in strings)
722 
723 def saveOrigin(obj, level):
724  import sys
725  fInfo = inspect.getframeinfo(sys._getframe(level+1))
726  obj._filename = fInfo.filename
727  obj._lineNumber =fInfo.lineno
728 
729 def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth=""):
730  if len(newParams):
731  #need to treat items both in params and myparams specially
732  for key,value in newParams.items():
733  if key in params:
734  if value is None:
735  del params[key]
736  elif isinstance(value, dict):
737  if isinstance(params[key],_Parameterizable):
738  pset = params[key]
739  p =pset.parameters_()
740  oldkeys = set(p.keys())
742  value,errorRaiser,
743  ("%s.%s" if isinstance(key, str) else "%s[%s]")%(keyDepth,key))
744  for k,v in p.items():
745  setattr(pset,k,v)
746  oldkeys.discard(k)
747  for k in oldkeys:
748  delattr(pset,k)
749  elif isinstance(params[key],_ValidatingParameterListBase):
750  if any(not isinstance(k, int) for k in value.keys()):
751  raise TypeError("Attempted to change a list using a dict whose keys are not integers")
752  plist = params[key]
753  if any((k < 0 or k >= len(plist)) for k in value.keys()):
754  raise IndexError("Attempted to set an index which is not in the list")
755  p = dict(enumerate(plist))
757  value,errorRaiser,
758  ("%s.%s" if isinstance(key, str) else "%s[%s]")%(keyDepth,key))
759  for k,v in p.items():
760  plist[k] = v
761  else:
762  raise ValueError("Attempted to change non PSet value "+keyDepth+" using a dictionary")
763  elif isinstance(value,_ParameterTypeBase) or (isinstance(key, int)) or isinstance(value, _Parameterizable):
764  params[key] = value
765  else:
766  params[key].setValue(value)
767  else:
768  if isinstance(value,_ParameterTypeBase) or isinstance(value, _Parameterizable):
769  params[key]=value
770  else:
771  errorRaiser(key)
772 
773 
774 if __name__ == "__main__":
775 
776  import unittest
778  @classmethod
779  def _itemIsValid(cls,item):
780  return True
781  class testMixins(unittest.TestCase):
783  t = TestList(1)
784  self.assertEqual(t,[1])
785  t = TestList((1,))
786  self.assertEqual(t,[1])
787  t = TestList("one")
788  self.assertEqual(t,["one"])
789  t = TestList( [1,])
790  self.assertEqual(t,[1])
791  t = TestList( (x for x in [1]) )
792  self.assertEqual(t,[1])
793 
794  t = TestList(1,2)
795  self.assertEqual(t,[1,2])
796  t = TestList((1,2))
797  self.assertEqual(t,[1,2])
798  t = TestList("one","two")
799  self.assertEqual(t,["one","two"])
800  t = TestList(("one","two"))
801  self.assertEqual(t,["one","two"])
802  t = TestList( [1,2])
803  self.assertEqual(t,[1,2])
804  t = TestList( (x for x in [1,2]) )
805  self.assertEqual(t,[1,2])
806  t = TestList( iter((1,2)) )
807  self.assertEqual(t,[1,2])
808 
809 
810  def testLargeList(self):
811  #lists larger than 255 entries can not be initialized
812  #using the constructor
813  args = [i for i in range(0,300)]
814 
815  t = TestList(*args)
816  pdump= t.dumpPython()
817  class cms(object):
818  def __init__(self):
819  self.TestList = TestList
820  pythonized = eval( pdump, globals(),{'cms':cms()} )
821  self.assertEqual(t,pythonized)
822  def testUsingBlock(self):
823  a = UsingBlock("a")
824  self.assertTrue(isinstance(a, _ParameterTypeBase))
825  def testConstruction(self):
826  class __Test(_TypedParameterizable):
827  pass
828  class __TestType(_SimpleParameterTypeBase):
829  def _isValid(self,value):
830  return True
831  class __PSet(_ParameterTypeBase,_Parameterizable):
832  def __init__(self,*arg,**args):
833  #need to call the inits separately
834  _ParameterTypeBase.__init__(self)
835  _Parameterizable.__init__(self,*arg,**args)
836 
837  a = __Test("MyType", __PSet(a=__TestType(1)))
838  self.assertEqual(a.a.value(), 1)
839  b = __Test("MyType", __PSet(a=__TestType(1)), __PSet(b=__TestType(2)))
840  self.assertEqual(b.a.value(), 1)
841  self.assertEqual(b.b.value(), 2)
842  self.assertRaises(ValueError, lambda: __Test("MyType", __PSet(a=__TestType(1)), __PSet(a=__TestType(2))))
843  c = __Test("MyType", dict(a=__TestType(1)), dict(b=__TestType(2)))
844  self.assertEqual(c.a.value(), 1)
845  self.assertEqual(c.b.value(), 2)
846  self.assertRaises(ValueError, lambda: __Test("MyType", dict(a=__TestType(1)), dict(a=__TestType(2))))
847  def testUpdate_(self):
848  class __Test(_TypedParameterizable):
849  pass
850  class __TestType(_SimpleParameterTypeBase):
851  def _isValid(self,value):
852  return True
853  class __PSet(_ParameterTypeBase,_Parameterizable):
854  def __init__(self,*arg,**args):
855  #need to call the inits separately
856  _ParameterTypeBase.__init__(self)
857  _Parameterizable.__init__(self,*arg,**args)
858  a = __Test("MyType", a = __TestType(1))
859  a.update_(dict(b=__TestType(2)))
860  self.assertEqual(a.a.value(), 1)
861  self.assertEqual(a.b.value(), 2)
862  a.update_(dict(a=3))
863  self.assertEqual(a.a.value(), 3)
864  a.update_(__PSet(a=__TestType(5)))
865  self.assertEqual(a.a.value(), 5)
866  self.assertRaises(TypeError, lambda: a.update_(dict(c=6)))
867 
868  def testCopy(self):
869  class __Test(_TypedParameterizable):
870  pass
871  class __TestType(_SimpleParameterTypeBase):
872  def _isValid(self,value):
873  return True
874  a = __Test("MyType",t=__TestType(1), u=__TestType(2))
875  b = a.copy()
876  self.assertEqual(b.t.value(),1)
877  self.assertEqual(b.u.value(),2)
878 
879  c = __Test("MyType")
880  self.assertEqual(len(c.parameterNames_()), 0)
881  d = c.copy()
882  self.assertEqual(len(d.parameterNames_()), 0)
883  def testClone(self):
884  class __Test(_TypedParameterizable):
885  pass
886  class __TestType(_SimpleParameterTypeBase):
887  def _isValid(self,value):
888  return True
889  class __PSet(_ParameterTypeBase,_Parameterizable):
890  def __init__(self,*arg,**args):
891  #need to call the inits separately
892  _ParameterTypeBase.__init__(self)
893  _Parameterizable.__init__(self,*arg,**args)
894  def dumpPython(self,options=PrintOptions()):
895  return "__PSet(\n"+_Parameterizable.dumpPython(self, options)+options.indentation()+")"
896 
897  a = __Test("MyType",
898  t=__TestType(1),
899  u=__TestType(2),
900  w = __TestType(3),
901  x = __PSet(a = __TestType(4),
902  b = __TestType(6),
903  c = __PSet(gamma = __TestType(5))))
904  b = a.clone(t=3,
905  v=__TestType(4),
906  w= None,
907  x = dict(a = 7,
908  c = dict(gamma = 8),
909  d = __TestType(9)))
910  c = a.clone(x = dict(a=None, c=None))
911  self.assertEqual(a.t.value(),1)
912  self.assertEqual(a.u.value(),2)
913  self.assertEqual(b.t.value(),3)
914  self.assertEqual(b.u.value(),2)
915  self.assertEqual(b.v.value(),4)
916  self.assertEqual(b.x.a.value(),7)
917  self.assertEqual(b.x.b.value(),6)
918  self.assertEqual(b.x.c.gamma.value(),8)
919  self.assertEqual(b.x.d.value(),9)
920  self.assertEqual(hasattr(b,"w"), False)
921  self.assertEqual(hasattr(c.x,"a"), False)
922  self.assertEqual(hasattr(c.x,"c"), False)
923  self.assertRaises(TypeError,a.clone,**{"v":1})
924  d = a.clone(__PSet(k=__TestType(42)))
925  self.assertEqual(d.t.value(), 1)
926  self.assertEqual(d.k.value(), 42)
927  d2 = a.clone(__PSet(t=__TestType(42)))
928  self.assertEqual(d2.t.value(), 42)
929  d3 = a.clone(__PSet(t=__TestType(42)),
930  __PSet(u=__TestType(56)))
931  self.assertEqual(d3.t.value(), 42)
932  self.assertEqual(d3.u.value(), 56)
933  self.assertRaises(ValueError,a.clone,
934  __PSet(t=__TestType(42)),
935  __PSet(t=__TestType(56)))
936  d4 = a.clone(__PSet(t=__TestType(43)), u = 57)
937  self.assertEqual(d4.t.value(), 43)
938  self.assertEqual(d4.u.value(), 57)
939  self.assertRaises(TypeError,a.clone,t=__TestType(43),**{"doesNotExist":57})
940 
941  e = __Test("MyType")
942  self.assertEqual(len(e.parameterNames_()), 0)
943  f = e.clone(__PSet(a = __TestType(1)), b = __TestType(2))
944  self.assertEqual(f.a.value(), 1)
945  self.assertEqual(f.b.value(), 2)
946  g = e.clone()
947  self.assertEqual(len(g.parameterNames_()), 0)
948 
949  def testModified(self):
950  class __TestType(_SimpleParameterTypeBase):
951  def _isValid(self,value):
952  return True
953  a = __TestType(1)
954  self.assertEqual(a.isModified(),False)
955  a.setValue(1)
956  self.assertEqual(a.isModified(),False)
957  a.setValue(2)
958  self.assertEqual(a.isModified(),True)
959  a.resetModified()
960  self.assertEqual(a.isModified(),False)
963  pass
965  def _isValid(self,value):
966  return True
967  class __DummyModule(object):
968  def __init__(self):
969  self.tLPTest = tLPTest
970  self.tLPTestType = tLPTestType
971  p = tLPTest("MyType",** dict( [ ("a"+str(x), tLPTestType(x)) for x in range(0,300) ] ) )
972  #check they are the same
973  self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{"cms": __DummyModule()}).dumpPython())
975  reg = _SpecialImportRegistry()
976  reg.registerSpecialImportForType(int, "import foo")
977  self.assertRaises(RuntimeError, lambda: reg.registerSpecialImportForType(int, "import bar"))
978  reg.registerSpecialImportForType(str, "import bar")
979  self.assertEqual(reg.getSpecialImports(), [])
980  reg.registerUse([1])
981  self.assertEqual(reg.getSpecialImports(), [])
982  reg.registerUse(1)
983  self.assertEqual(reg.getSpecialImports(), ["import foo"])
984  reg.registerUse(1)
985  self.assertEqual(reg.getSpecialImports(), ["import foo"])
986  reg.registerUse("a")
987  self.assertEqual(reg.getSpecialImports(), ["import bar", "import foo"])
989  class __Test(_TypedParameterizable):
990  pass
991  class __TestTypeA(_SimpleParameterTypeBase):
992  def _isValid(self,value):
993  return True
994  class __TestTypeB(_SimpleParameterTypeBase):
995  def _isValid(self,value):
996  return True
997  pass
998  a = __Test("MyType",
999  t=__TestTypeA(1))
1000  self.assertRaises(TypeError, lambda : setattr(a,'t',__TestTypeB(2)))
1001 
1002 
1003  unittest.main()
def __init__(self, arg, args)
Definition: Mixins.py:599
def indent(self)
Definition: Mixins.py:20
def testSpecialImportRegistry(self)
Definition: Mixins.py:974
def __gt__(self, other)
Definition: Mixins.py:130
def _isValid(cls, seq)
Definition: Mixins.py:615
def testModified(self)
Definition: Mixins.py:949
def label_(self)
Definition: Mixins.py:539
def pythonTypeName(self)
Definition: Mixins.py:70
def __eq__(self, other)
Definition: Mixins.py:114
def _modifyParametersFromDict(params, newParams, errorRaiser, keyDepth="")
Definition: Mixins.py:729
def __setParameters(self, parameters)
Definition: Mixins.py:263
def _findDependencies(self, knownDeps, presentDeps)
Definition: Mixins.py:578
def testClone(self)
Definition: Mixins.py:883
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:37
def _itemFromArgument(self, x)
Definition: Mixins.py:623
def testCopy(self)
Definition: Mixins.py:868
def __init__(self, arg, kargs)
Definition: Mixins.py:171
def __init__(self, dataset, job_number, job_id, job_name, isDA, isMC, applyBOWS, applyEXTRACOND, extraconditions, runboundary, lumilist, intlumi, maxevents, gt, allFromGT, alignmentDB, alignmentTAG, apeDB, apeTAG, bowDB, bowTAG, vertextype, tracktype, refittertype, ttrhtype, applyruncontrol, ptcut, CMSSW_dir, the_dir)
def unindent(self)
Definition: Mixins.py:22
def _valueFromString(value)
Definition: Mixins.py:153
def __ne__(self, other)
Definition: Mixins.py:118
def append(self, x)
Definition: Mixins.py:630
def testConstruction(self)
Definition: Mixins.py:825
def registerUse(self, obj)
Definition: Mixins.py:40
def _checkAndReturnValueWithType(self, valueWithType)
Definition: Mixins.py:89
def insert(self, i, x)
Definition: Mixins.py:645
bool setValue(Container &, const reco::JetBaseRef &, const JetExtendedData &)
associate jet with value. Returns false and associate nothing if jet is already associated ...
def __le__(self, other)
Definition: Mixins.py:126
def isCompatibleCMSType(self, aType)
Definition: Mixins.py:87
def isModified(self)
Definition: Mixins.py:62
def testListConstruction(self)
Definition: Mixins.py:782
def _itemIsValid(cls, item)
Definition: Mixins.py:779
def _convertArguments(self, seq)
Definition: Mixins.py:625
def setIsFrozen(self)
Definition: Mixins.py:308
def isModified(self)
Definition: Mixins.py:184
def _itemsFromStrings(strings, converter)
Definition: Mixins.py:720
def configTypeName(self)
Definition: Mixins.py:66
def clone(self, args, params)
Definition: Mixins.py:422
def setIsFrozen(self)
Definition: Mixins.py:85
def dumpSequenceConfig(self)
Definition: Mixins.py:571
def directDependencies(self)
Definition: Mixins.py:490
def __init__(self, type_, arg, kargs)
Definition: Mixins.py:402
def testLargeParameterizable(self)
Definition: Mixins.py:961
def indentation(self)
Definition: Mixins.py:18
def __repr__(self)
Definition: Mixins.py:392
def resetModified(self)
Definition: Mixins.py:64
Definition: value.py:1
def saveOrigin(obj, level)
Definition: Mixins.py:723
def testUsingBlock(self)
Definition: Mixins.py:822
def registerSpecialImportForType(self, cls, impStatement)
Definition: Mixins.py:34
Namespace of DDCMS conversion namespace.
def _isTaskComponent(self)
Definition: Mixins.py:8
def dumpSequencePython
Definition: Mixins.py:573
static std::string join(char **cmd)
Definition: RemoteFile.cc:21
def hasParameter(self, params)
Definition: Mixins.py:194
def setValue(self, value)
Definition: Mixins.py:104
def __ge__(self, other)
Definition: Mixins.py:134
def extend(self, x)
Definition: Mixins.py:634
def _isValid(value)
Definition: Mixins.py:151
def parameterNames_(self)
Definition: Mixins.py:181
def dumpPython(process, name)
def remove(d, key, TELL=False)
Definition: MatrixUtil.py:233
def __setParametersFromArg(self, arg)
Definition: Mixins.py:253
def __str__(self)
Definition: Mixins.py:566
def __add__(self, rhs)
Definition: Mixins.py:638
def label(self)
Definition: Mixins.py:563
def testLargeList(self)
Definition: Mixins.py:810
def isFrozen(self)
Definition: Mixins.py:306
def hasLabel_(self)
Definition: Mixins.py:543
def __setitem__(self, key, value)
Definition: Mixins.py:606
def __init__(self, value)
Definition: Mixins.py:97
def testUpdate_(self)
Definition: Mixins.py:847
def parameters_(self)
Definition: Mixins.py:227
def testInvalidTypeChange(self)
Definition: Mixins.py:988
#define str(s)
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
def getParameter(self, params)
Definition: Mixins.py:208
def insertContentsInto(self, parameterSet)
Definition: Mixins.py:394
def update_(self, d)
Definition: Mixins.py:294
def __init__(self, arg, args)
Definition: Mixins.py:656
def __lt__(self, other)
Definition: Mixins.py:122