1 from __future__
import print_function
2 from builtins
import range, object
7 """Denotes a class that can be used by the Processes class"""
12 def __init__(self, indent = 0, deltaIndent = 4, process = True, targetDirectory = None, useSubdirectories = False):
26 """This class collects special import statements of configuration types"""
31 for lst
in six.itervalues(self.
_registry):
35 className = cls.__name__
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]
41 className = obj.__class__.__name__
49 for (imp, used)
in six.itervalues(self.
_registry):
57 """base class for classes which are used as the 'parameters' for a ParameterSet"""
59 self.__dict__[
"_isFrozen"] =
False
68 return type(self).__name__
69 return 'untracked '+type(self).__name__
72 return 'cms.'+type(self).__name__
73 return 'cms.untracked.'+type(self).__name__
75 specialImportRegistry.registerUse(self)
88 return isinstance(self,aType)
91 """base class for parameter classes which only hold a single value"""
93 super(_SimpleParameterTypeBase,self).
__init__()
95 if not self._isValid(value):
96 raise ValueError(
str(value)+
" is not a valid "+
str(type(self)))
100 if not self._isValid(value):
101 raise ValueError(
str(value)+
" is not a valid "+
str(type(self)))
110 if isinstance(other,_SimpleParameterTypeBase):
111 return self.
_value == other._value
112 return self.
_value == other
114 if isinstance(other,_SimpleParameterTypeBase):
115 return self.
_value != other._value
116 return self.
_value != other
118 if isinstance(other,_SimpleParameterTypeBase):
119 return self.
_value < other._value
120 return self.
_value < other
122 if isinstance(other,_SimpleParameterTypeBase):
123 return self.
_value <= other._value
124 return self.
_value <= other
126 if isinstance(other,_SimpleParameterTypeBase):
127 return self.
_value > other._value
128 return self.
_value > other
130 if isinstance(other,_SimpleParameterTypeBase):
131 return self.
_value >= other._value
132 return self.
_value >= other
136 """For injection purposes, pretend this is a new parameter type
137 then have a post process step which strips these out
140 super(UsingBlock,self).
__init__(value)
147 return isinstance(value,str)
149 """only used for cfg-parsing"""
156 parameterSet.addString(self.
isTracked(), myname, value)
159 return "process."+self.
value()
165 """Base class for classes which allow addition of _ParameterTypeBase data"""
167 self.__dict__[
'_Parameterizable__parameterNames'] = []
168 self.__dict__[
"_isFrozen"] =
False
169 self.__dict__[
'_Parameterizable__validator'] =
None
170 """The named arguments are the 'parameters' which are added as 'python attributes' to the object"""
174 if type(block).__name__ !=
"PSet":
175 raise ValueError(
"Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
181 """Returns the name of the parameters"""
182 return self.__parameterNames[:]
187 param = self.__dict__[name]
188 if isinstance(param, _Parameterizable)
and param.isModified():
197 check that pset provided has the attribute chain
200 Eg, if params is [ 'attr1', 'attr2', 'attr3' ]
201 check for pset.attr1.attr2.attr3
203 returns True if parameter exists, False if not
211 Retrieve the specified parameter from the PSet Provided
212 given the attribute chain
214 returns None if not found
218 if type(params).__name__ ==
'str':
219 return getattr(self, params,
None)
221 lastParam = getattr(lastParam, param,
None)
223 if lastParam ==
None:
228 """Returns a dictionary of copies of the user-set parameters"""
232 result[name]=copy.deepcopy(self.__dict__[name])
236 if name ==
'allowAnyLabel_':
240 if not isinstance(value,_ParameterTypeBase):
245 if name
in self.__dict__:
246 message =
"Duplicate insert of member " + name
247 message +=
"\nThe original parameters are:\n"
249 raise ValueError(message)
250 self.__dict__[name]=value
251 self.__parameterNames.
append(name)
256 for name,value
in six.iteritems(parameters):
257 if name ==
'allowAnyLabel_':
266 if self.
isFrozen()
and not (name
in [
"_Labelable__label",
"_isFrozen"]
or name.startswith(
'_')):
267 message =
"Object already added to a process. It is read only now\n"
268 message +=
" %s = %s" %(name, value)
269 message +=
"\nThe original parameters are:\n"
271 raise ValueError(message)
274 super(_Parameterizable,self).
__setattr__(name,value)
275 elif not name
in self.__dict__:
280 if isinstance(value,_ParameterTypeBase):
281 self.__dict__[name] = value
294 raise ValueError(
"Object already added to a process. It is read only now")
296 self.__parameterNames.
remove(name)
299 raise TypeError(name+
" does not already exist, so it can only be set to a CMS python configuration type")
301 specialImportRegistry.registerUse(self)
303 if len(sortedNames) > 200:
312 for name
in sortedNames:
313 param = self.__dict__[name]
315 name2 = name.replace(
'-',
'_')
318 if name.startswith(
"using_"):
319 usings.append(options.indentation()+param.dumpPython(options))
321 others.append((name2, param.dumpPython(options)))
324 resultList =
',\n'.
join(usings)
325 longOthers = options.indentation()+
"**dict(\n"
327 longOthers += options.indentation()+
"[\n"
332 if entriesInList > 200:
335 longOthers += options.indentation()+
"] +\n"+options.indentation()+
"[\n"
338 longOthers += options.indentation()+
'("'+n+
'" , '+v+
' ),\n'
340 longOthers += options.indentation()+
"]\n"
342 longOthers +=options.indentation()+
")\n"
346 ret.append(resultList)
348 ret.append(longOthers)
349 return ",\n".
join(ret)
353 for name
in sortedNames:
354 param = self.__dict__[name]
356 name2 = name.replace(
'-',
'_')
359 if name.startswith(
"using_"):
360 usings.append(options.indentation()+param.dumpPython(options))
362 others.append(options.indentation()+name2+
' = '+param.dumpPython(options))
366 resultList.extend(others)
371 return ',\n'.
join(resultList)+
'\n'
376 param = getattr(self,name)
377 param.insertInto(parameterSet, name)
381 """Base class for classes which are Parameterizable and have a 'type' assigned"""
383 self.__dict__[
'_TypedParameterizable__type'] = type_
389 arg = tuple([x
for x
in arg
if x !=
None])
390 super(_TypedParameterizable,self).
__init__(*arg,**kargs)
393 self._placeImpl(name,proc)
395 """returns the type of the object, e.g. 'FooProducer'"""
398 returnValue =_TypedParameterizable.__new__(type(self))
403 returnValue.__init__(self.__type,*args,
408 """Copies the object and allows one to modify the parameters of the clone.
409 New parameters may be added by specify the exact type
410 Modifying existing parameters can be done by just specifying the new
411 value without having to specify the type.
412 A parameter may be removed from the clone using the value None.
413 #remove the parameter foo.fred
414 mod.toModify(foo, fred = None)
415 A parameter embedded within a PSet may be changed via a dictionary
416 #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
417 mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
419 returnValue =_TypedParameterizable.__new__(type(self))
421 if len(myparams) == 0
and len(params)
and len(args):
426 returnValue.__init__(self.__type,*args,
428 returnValue._isModified =
False
429 returnValue._isFrozen =
False
440 choices.extend(glob.glob(d+
'/*/*/'+label+
'.py'))
450 mod = __import__(name)
451 components = name.split(
'.')
452 for comp
in components[1:]:
453 mod = getattr(mod,comp)
454 if hasattr(mod,label):
455 default = getattr(mod,label)
456 if isinstance(default,_TypedParameterizable):
457 if(default.type_() == type):
459 for name
in default.parameterNames_():
460 params[name] = getattr(default,name)
468 config = self.__type +
' { \n'
470 param = self.__dict__[name]
472 config+=options.indentation()+param.configTypeName()+
' '+name+
' = '+param.configValue(options)+
'\n'
474 config += options.indentation()+
'}\n'
478 specialImportRegistry.registerUse(self)
479 result =
"cms."+
str(type(self).__name__)+
'("'+self.
type_()+
'"'
484 result +=
",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() +
")\n"
488 """ dumps the object with all attributes declared after the constructor"""
491 param = self.__dict__[name]
492 result += options.indentation() + myname +
"." + name +
" = " + param.dumpPython(options) +
"\n"
502 newpset = parameterSet.newPSet()
503 newpset.addString(
True,
"@module_label", self.
moduleLabel_(myname))
504 newpset.addString(
True,
"@module_type", self.
type_())
505 newpset.addString(
True,
"@module_edm_type", type(self).__name__)
512 """A 'mixin' used to denote that the class can be paired with a label (e.g. an EDProducer)"""
514 if not hasattr(self,
"_Labelable__label"):
515 raise RuntimeError(
"module has no label. Perhaps it wasn't inserted into the process?")
518 return hasattr(self,
"_Labelable__label")
and self.
__label is not None
521 if self.
label_() != label
and label
is not None :
522 msg100 =
"Attempting to change the label of a Labelable object, possibly an attribute of the Process\n"
523 msg101 =
"Old label = "+self.
label_()+
" New label = "+label+
"\n"
524 msg102 =
"Type = "+
str(type(self))+
"\n"
525 msg103 =
"Some possible solutions:\n"
526 msg104 =
" 1. Clone modules instead of using simple assignment. Cloning is\n"
527 msg105 =
" also preferred for other types when possible.\n"
528 msg106 =
" 2. Declare new names starting with an underscore if they are\n"
529 msg107 =
" for temporaries you do not want propagated into the Process. The\n"
530 msg108 =
" underscore tells \"from x import *\" and process.load not to import\n"
531 msg109 =
" the name.\n"
532 msg110 =
" 3. Reorganize so the assigment is not necessary. Giving a second\n"
533 msg111 =
" name to the same object usually causes confusion and problems.\n"
534 msg112 =
" 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
535 raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
554 myDeps=knownDeps.get(self.
label_(),
None)
556 if presentDeps != myDeps:
557 raise RuntimeError(
"the module "+self.
label_()+
" has two dependencies \n"
558 +
str(presentDeps)+
"\n"
560 +
"Please modify sequences to rectify this inconsistency")
562 myDeps=set(presentDeps)
563 knownDeps[self.
label_()]=myDeps
564 presentDeps.add(self.
label_())
568 """A 'mixin' used to denote that the class can be used without a label (e.g. a Service)"""
571 class _ValidatingListBase(list):
572 """Base class for a list which enforces that its entries pass a 'validity' test"""
574 super(_ValidatingListBase,self).
__init__(arg)
576 raise SyntaxError(
"named arguments ("+
','.
join([x
for x
in args])+
") passsed to "+
str(type(self)))
578 raise TypeError(
"wrong types ("+
','.
join([
str(type(value))
for value
in iter(self)])+
579 ") added to "+
str(type(self)))
581 if isinstance(key,slice):
583 raise TypeError(
"wrong type being inserted into this container "+self.
_labelIfAny())
585 if not self._itemIsValid(value):
586 raise TypeError(
"can not insert the type "+
str(type(value))+
" in container "+self.
_labelIfAny())
587 super(_ValidatingListBase,self).
__setitem__(key,value)
590 if isinstance(seq, str):
593 if not self._itemIsValid(item):
599 if isinstance(seq, str):
604 if not self._itemIsValid(x):
605 raise TypeError(
"wrong type being appended to container "+self.
_labelIfAny())
609 raise TypeError(
"wrong type being extended to container "+self.
_labelIfAny())
613 raise TypeError(
"wrong type being added to container "+self.
_labelIfAny())
615 value = copy.copy(self)
619 if not self._itemIsValid(x):
620 raise TypeError(
"wrong type being inserted to container "+self.
_labelIfAny())
623 result = type(self).__name__
624 if hasattr(self,
'__label'):
625 result +=
' ' + self.__label
630 _ParameterTypeBase.__init__(self)
631 if len (arg) == 1
and not isinstance(arg[0],str):
636 super(_ValidatingParameterListBase,self).
__init__(*arg,**args)
646 for value
in iter(self):
648 config += options.indentation()
654 config += options.indentation()+
'}\n'
663 specialImportRegistry.registerUse(self)
666 if hasattr(self,
"_nPerLine"):
667 nPerLine = self._nPerLine
670 if n>nPerLine: options.indent()
674 for i, v
in enumerate(self):
676 if n>nPerLine: result +=
'\n'+options.indentation()
679 if i % nPerLine == 0:
680 result +=
'\n'+options.indentation()
684 result +=
'\n'+options.indentation()
697 fInfo = inspect.getframeinfo(sys._getframe(level+1))
698 obj._filename = fInfo.filename
699 obj._lineNumber =fInfo.lineno
704 for key,value
in six.iteritems(newParams):
708 elif isinstance(value, dict):
709 if isinstance(params[key],_Parameterizable):
711 p =pset.parameters_()
712 oldkeys = set(p.keys())
715 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
716 for k,v
in six.iteritems(p):
721 elif isinstance(params[key],_ValidatingParameterListBase):
722 if any(
not isinstance(k, int)
for k
in value.keys()):
723 raise TypeError(
"Attempted to change a list using a dict whose keys are not integers")
725 if any((k < 0
or k >= len(plist))
for k
in value.keys()):
726 raise IndexError(
"Attempted to set an index which is not in the list")
727 p = dict(enumerate(plist))
730 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
731 for k,v
in six.iteritems(p):
734 raise ValueError(
"Attempted to change non PSet value "+keyDepth+
" using a dictionary")
735 elif isinstance(value,_ParameterTypeBase)
or (isinstance(key, int))
or isinstance(value, _Parameterizable):
740 if isinstance(value,_ParameterTypeBase)
or isinstance(value, _Parameterizable):
746 if __name__ ==
"__main__":
755 self.assertEqual(t,[1])
757 self.assertEqual(t,[1])
759 self.assertEqual(t,[
"one"])
761 self.assertEqual(t,[1])
763 self.assertEqual(t,[1])
766 self.assertEqual(t,[1,2])
768 self.assertEqual(t,[1,2])
770 self.assertEqual(t,[
"one",
"two"])
772 self.assertEqual(t,[
"one",
"two"])
774 self.assertEqual(t,[1,2])
776 self.assertEqual(t,[1,2])
778 self.assertEqual(t,[1,2])
784 args = [i
for i
in range(0,300)]
787 pdump= t.dumpPython()
791 pythonized = eval( pdump, globals(),{
'cms':
cms()} )
792 self.assertEqual(t,pythonized)
795 self.assert_(isinstance(a, _ParameterTypeBase))
800 def _isValid(self,value):
802 a = __Test(
"MyType",t=__TestType(1), u=__TestType(2))
804 self.assertEqual(b.t.value(),1)
805 self.assertEqual(b.u.value(),2)
810 def _isValid(self,value):
813 def __init__(self,*arg,**args):
815 _ParameterTypeBase.__init__(self)
816 _Parameterizable.__init__(self,*arg,**args)
821 x = __PSet(a = __TestType(4),
823 c = __PSet(gamma = __TestType(5))))
830 c = a.clone(x = dict(a=
None, c=
None))
831 self.assertEqual(a.t.value(),1)
832 self.assertEqual(a.u.value(),2)
833 self.assertEqual(b.t.value(),3)
834 self.assertEqual(b.u.value(),2)
835 self.assertEqual(b.v.value(),4)
836 self.assertEqual(b.x.a.value(),7)
837 self.assertEqual(b.x.b.value(),6)
838 self.assertEqual(b.x.c.gamma.value(),8)
839 self.assertEqual(b.x.d.value(),9)
840 self.assertEqual(hasattr(b,
"w"),
False)
841 self.assertEqual(hasattr(c.x,
"a"),
False)
842 self.assertEqual(hasattr(c.x,
"c"),
False)
843 self.assertRaises(TypeError,a.clone,
None,**{
"v":1})
846 def _isValid(self,value):
849 self.assertEqual(a.isModified(),
False)
851 self.assertEqual(a.isModified(),
False)
853 self.assertEqual(a.isModified(),
True)
855 self.assertEqual(a.isModified(),
False)
860 def _isValid(self,value):
862 class __DummyModule(
object):
868 self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{
"cms": __DummyModule()}).
dumpPython())
871 reg.registerSpecialImportForType(int,
"import foo")
872 self.assertRaises(
lambda x: reg.registerSpecialImportForType(int,
"import bar"))
873 reg.registerSpecialImportForType(str,
"import bar")
874 self.assertEqual(reg.getSpecialImports(), [])
876 self.assertEqual(reg.getSpecialImports(), [])
878 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
880 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
882 self.assertEqual(reg.getSpecialImports(), [
"import bar",
"import foo"])