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