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)
89 """base class for parameter classes which only hold a single value"""
91 super(_SimpleParameterTypeBase,self).
__init__()
93 if not self._isValid(value):
94 raise ValueError(
str(value)+
" is not a valid "+
str(type(self)))
98 if not self._isValid(value):
99 raise ValueError(
str(value)+
" is not a valid "+
str(type(self)))
108 if isinstance(other,_SimpleParameterTypeBase):
109 return self.
_value == other._value
110 return self.
_value == other
112 if isinstance(other,_SimpleParameterTypeBase):
113 return self.
_value != other._value
114 return self.
_value != other
116 if isinstance(other,_SimpleParameterTypeBase):
117 return self.
_value < other._value
118 return self.
_value < other
120 if isinstance(other,_SimpleParameterTypeBase):
121 return self.
_value <= other._value
122 return self.
_value <= other
124 if isinstance(other,_SimpleParameterTypeBase):
125 return self.
_value > other._value
126 return self.
_value > other
128 if isinstance(other,_SimpleParameterTypeBase):
129 return self.
_value >= other._value
130 return self.
_value >= other
134 """For injection purposes, pretend this is a new parameter type
135 then have a post process step which strips these out
138 super(UsingBlock,self).
__init__(value)
145 return isinstance(value,str)
147 """only used for cfg-parsing"""
154 parameterSet.addString(self.
isTracked(), myname, value)
157 return "process."+self.
value()
163 """Base class for classes which allow addition of _ParameterTypeBase data"""
165 self.__dict__[
'_Parameterizable__parameterNames'] = []
166 self.__dict__[
"_isFrozen"] =
False
167 self.__dict__[
'_Parameterizable__validator'] =
None
168 """The named arguments are the 'parameters' which are added as 'python attributes' to the object"""
172 if type(block).__name__ !=
"PSet":
173 raise ValueError(
"Only PSets can be passed as unnamed argument blocks. This is a "+type(block).__name__)
179 """Returns the name of the parameters"""
180 return self.__parameterNames[:]
185 param = self.__dict__[name]
186 if isinstance(param, _Parameterizable)
and param.isModified():
195 check that pset provided has the attribute chain
198 Eg, if params is [ 'attr1', 'attr2', 'attr3' ]
199 check for pset.attr1.attr2.attr3
201 returns True if parameter exists, False if not
209 Retrieve the specified parameter from the PSet Provided
210 given the attribute chain
212 returns None if not found
216 if type(params).__name__ ==
'str':
217 return getattr(self, params,
None)
219 lastParam = getattr(lastParam, param,
None)
221 if lastParam ==
None:
226 """Returns a dictionary of copies of the user-set parameters"""
230 result[name]=copy.deepcopy(self.__dict__[name])
234 if name ==
'allowAnyLabel_':
238 if not isinstance(value,_ParameterTypeBase):
243 if name
in self.__dict__:
244 message =
"Duplicate insert of member " + name
245 message +=
"\nThe original parameters are:\n"
247 raise ValueError(message)
248 self.__dict__[name]=value
249 self.__parameterNames.
append(name)
254 for name,value
in six.iteritems(parameters):
255 if name ==
'allowAnyLabel_':
264 if self.
isFrozen()
and not (name
in [
"_Labelable__label",
"_isFrozen"]
or name.startswith(
'_')):
265 message =
"Object already added to a process. It is read only now\n"
266 message +=
" %s = %s" %(name, value)
267 message +=
"\nThe original parameters are:\n"
269 raise ValueError(message)
272 super(_Parameterizable,self).
__setattr__(name,value)
273 elif not name
in self.__dict__:
278 if isinstance(value,_ParameterTypeBase):
279 self.__dict__[name] = value
292 raise ValueError(
"Object already added to a process. It is read only now")
294 self.__parameterNames.
remove(name)
297 raise TypeError(name+
" does not already exist, so it can only be set to a CMS python configuration type")
299 specialImportRegistry.registerUse(self)
301 if len(sortedNames) > 200:
310 for name
in sortedNames:
311 param = self.__dict__[name]
313 name2 = name.replace(
'-',
'_')
316 if name.startswith(
"using_"):
317 usings.append(options.indentation()+param.dumpPython(options))
319 others.append((name2, param.dumpPython(options)))
322 resultList =
',\n'.
join(usings)
323 longOthers = options.indentation()+
"**dict(\n"
325 longOthers += options.indentation()+
"[\n"
330 if entriesInList > 200:
333 longOthers += options.indentation()+
"] +\n"+options.indentation()+
"[\n"
336 longOthers += options.indentation()+
'("'+n+
'" , '+v+
' ),\n'
338 longOthers += options.indentation()+
"]\n"
340 longOthers +=options.indentation()+
")\n"
344 ret.append(resultList)
346 ret.append(longOthers)
347 return ",\n".
join(ret)
351 for name
in sortedNames:
352 param = self.__dict__[name]
354 name2 = name.replace(
'-',
'_')
357 if name.startswith(
"using_"):
358 usings.append(options.indentation()+param.dumpPython(options))
360 others.append(options.indentation()+name2+
' = '+param.dumpPython(options))
364 resultList.extend(others)
365 return ',\n'.
join(resultList)+
'\n'
370 param = getattr(self,name)
371 param.insertInto(parameterSet, name)
375 """Base class for classes which are Parameterizable and have a 'type' assigned"""
377 self.__dict__[
'_TypedParameterizable__type'] = type_
383 arg = tuple([x
for x
in arg
if x !=
None])
384 super(_TypedParameterizable,self).
__init__(*arg,**kargs)
387 self._placeImpl(name,proc)
389 """returns the type of the object, e.g. 'FooProducer'"""
392 returnValue =_TypedParameterizable.__new__(type(self))
397 returnValue.__init__(self.__type,*args,
402 """Copies the object and allows one to modify the parameters of the clone.
403 New parameters may be added by specify the exact type
404 Modifying existing parameters can be done by just specifying the new
405 value without having to specify the type.
406 A parameter may be removed from the clone using the value None.
407 #remove the parameter foo.fred
408 mod.toModify(foo, fred = None)
409 A parameter embedded within a PSet may be changed via a dictionary
410 #change foo.fred.pebbles to 3 and foo.fred.friend to "barney"
411 mod.toModify(foo, fred = dict(pebbles = 3, friend = "barney)) )
413 returnValue =_TypedParameterizable.__new__(type(self))
415 if len(myparams) == 0
and len(params)
and len(args):
420 returnValue.__init__(self.__type,*args,
422 returnValue._isModified =
False
423 returnValue._isFrozen =
False
434 choices.extend(glob.glob(d+
'/*/*/'+label+
'.py'))
444 mod = __import__(name)
445 components = name.split(
'.')
446 for comp
in components[1:]:
447 mod = getattr(mod,comp)
448 if hasattr(mod,label):
449 default = getattr(mod,label)
450 if isinstance(default,_TypedParameterizable):
451 if(default.type_() == type):
453 for name
in default.parameterNames_():
454 params[name] = getattr(default,name)
462 config = self.__type +
' { \n'
464 param = self.__dict__[name]
466 config+=options.indentation()+param.configTypeName()+
' '+name+
' = '+param.configValue(options)+
'\n'
468 config += options.indentation()+
'}\n'
472 specialImportRegistry.registerUse(self)
473 result =
"cms."+
str(type(self).__name__)+
'("'+self.
type_()+
'"'
478 result +=
",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() +
")\n"
482 """ dumps the object with all attributes declared after the constructor"""
485 param = self.__dict__[name]
486 result += options.indentation() + myname +
"." + name +
" = " + param.dumpPython(options) +
"\n"
496 newpset = parameterSet.newPSet()
497 newpset.addString(
True,
"@module_label", self.
moduleLabel_(myname))
498 newpset.addString(
True,
"@module_type", self.
type_())
499 newpset.addString(
True,
"@module_edm_type", type(self).__name__)
506 """A 'mixin' used to denote that the class can be paired with a label (e.g. an EDProducer)"""
508 if not hasattr(self,
"_Labelable__label"):
509 raise RuntimeError(
"module has no label. Perhaps it wasn't inserted into the process?")
512 return hasattr(self,
"_Labelable__label")
and self.
__label is not None
515 if self.
label_() != label
and label
is not None :
516 msg100 =
"Attempting to change the label of a Labelable object, possibly an attribute of the Process\n"
517 msg101 =
"Old label = "+self.
label_()+
" New label = "+label+
"\n"
518 msg102 =
"Type = "+
str(type(self))+
"\n"
519 msg103 =
"Some possible solutions:\n"
520 msg104 =
" 1. Clone modules instead of using simple assignment. Cloning is\n"
521 msg105 =
" also preferred for other types when possible.\n"
522 msg106 =
" 2. Declare new names starting with an underscore if they are\n"
523 msg107 =
" for temporaries you do not want propagated into the Process. The\n"
524 msg108 =
" underscore tells \"from x import *\" and process.load not to import\n"
525 msg109 =
" the name.\n"
526 msg110 =
" 3. Reorganize so the assigment is not necessary. Giving a second\n"
527 msg111 =
" name to the same object usually causes confusion and problems.\n"
528 msg112 =
" 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
529 raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
548 myDeps=knownDeps.get(self.
label_(),
None)
550 if presentDeps != myDeps:
551 raise RuntimeError(
"the module "+self.
label_()+
" has two dependencies \n"
552 +
str(presentDeps)+
"\n"
554 +
"Please modify sequences to rectify this inconsistency")
556 myDeps=set(presentDeps)
557 knownDeps[self.
label_()]=myDeps
558 presentDeps.add(self.
label_())
562 """A 'mixin' used to denote that the class can be used without a label (e.g. a Service)"""
565 class _ValidatingListBase(
list):
566 """Base class for a list which enforces that its entries pass a 'validity' test"""
568 super(_ValidatingListBase,self).
__init__(arg)
570 raise SyntaxError(
"named arguments ("+
','.
join([x
for x
in args])+
") passsed to "+
str(type(self)))
572 raise TypeError(
"wrong types ("+
','.
join([
str(type(value))
for value
in iter(self)])+
573 ") added to "+
str(type(self)))
575 if isinstance(key,slice):
577 raise TypeError(
"wrong type being inserted into this container "+self.
_labelIfAny())
579 if not self._itemIsValid(value):
580 raise TypeError(
"can not insert the type "+
str(type(value))+
" in container "+self.
_labelIfAny())
581 super(_ValidatingListBase,self).
__setitem__(key,value)
584 if isinstance(seq, str):
587 if not self._itemIsValid(item):
591 if not self._itemIsValid(x):
592 raise TypeError(
"wrong type being appended to container "+self.
_labelIfAny())
593 super(_ValidatingListBase,self).
append(x)
596 raise TypeError(
"wrong type being extended to container "+self.
_labelIfAny())
597 super(_ValidatingListBase,self).
extend(x)
600 raise TypeError(
"wrong type being added to container "+self.
_labelIfAny())
602 value = copy.copy(self)
606 if not self._itemIsValid(x):
607 raise TypeError(
"wrong type being inserted to container "+self.
_labelIfAny())
608 super(_ValidatingListBase,self).
insert(i,x)
610 result = type(self).__name__
611 if hasattr(self,
'__label'):
612 result +=
' ' + self.__label
617 _ParameterTypeBase.__init__(self)
618 if len (arg) == 1
and not isinstance(arg[0],str):
623 super(_ValidatingParameterListBase,self).
__init__(*arg,**args)
633 for value
in iter(self):
635 config += options.indentation()
641 config += options.indentation()+
'}\n'
650 specialImportRegistry.registerUse(self)
653 if hasattr(self,
"_nPerLine"):
654 nPerLine = self._nPerLine
657 if n>nPerLine: options.indent()
661 for i, v
in enumerate(self):
663 if n>nPerLine: result +=
'\n'+options.indentation()
666 if i % nPerLine == 0:
667 result +=
'\n'+options.indentation()
671 result +=
'\n'+options.indentation()
684 fInfo = inspect.getframeinfo(sys._getframe(level+1))
685 obj._filename = fInfo.filename
686 obj._lineNumber =fInfo.lineno
691 for key,value
in six.iteritems(newParams):
695 elif isinstance(value, dict):
696 if isinstance(params[key],_Parameterizable):
698 p =pset.parameters_()
699 oldkeys = set(p.keys())
702 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
703 for k,v
in six.iteritems(p):
708 elif isinstance(params[key],_ValidatingParameterListBase):
709 if any(
not isinstance(k, int)
for k
in value.keys()):
710 raise TypeError(
"Attempted to change a list using a dict whose keys are not integers")
712 if any((k < 0
or k >= len(plist))
for k
in value.keys()):
713 raise IndexError(
"Attempted to set an index which is not in the list")
714 p = dict(enumerate(plist))
717 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
718 for k,v
in six.iteritems(p):
721 raise ValueError(
"Attempted to change non PSet value "+keyDepth+
" using a dictionary")
722 elif isinstance(value,_ParameterTypeBase)
or (isinstance(key, int))
or isinstance(value, _Parameterizable):
727 if isinstance(value,_ParameterTypeBase)
or isinstance(value, _Parameterizable):
733 if __name__ ==
"__main__":
742 self.assertEqual(t,[1])
744 self.assertEqual(t,[1])
746 self.assertEqual(t,[
"one"])
748 self.assertEqual(t,[1])
750 self.assertEqual(t,[1])
753 self.assertEqual(t,[1,2])
755 self.assertEqual(t,[1,2])
757 self.assertEqual(t,[
"one",
"two"])
759 self.assertEqual(t,[
"one",
"two"])
761 self.assertEqual(t,[1,2])
763 self.assertEqual(t,[1,2])
765 self.assertEqual(t,[1,2])
771 args = [i
for i
in range(0,300)]
774 pdump= t.dumpPython()
778 pythonized = eval( pdump, globals(),{
'cms':
cms()} )
779 self.assertEqual(t,pythonized)
782 self.assert_(isinstance(a, _ParameterTypeBase))
787 def _isValid(self,value):
789 a = __Test(
"MyType",t=__TestType(1), u=__TestType(2))
791 self.assertEqual(b.t.value(),1)
792 self.assertEqual(b.u.value(),2)
797 def _isValid(self,value):
800 def __init__(self,*arg,**args):
802 _ParameterTypeBase.__init__(self)
803 _Parameterizable.__init__(self,*arg,**args)
808 x = __PSet(a = __TestType(4),
810 c = __PSet(gamma = __TestType(5))))
817 c = a.clone(x = dict(a=
None, c=
None))
818 self.assertEqual(a.t.value(),1)
819 self.assertEqual(a.u.value(),2)
820 self.assertEqual(b.t.value(),3)
821 self.assertEqual(b.u.value(),2)
822 self.assertEqual(b.v.value(),4)
823 self.assertEqual(b.x.a.value(),7)
824 self.assertEqual(b.x.b.value(),6)
825 self.assertEqual(b.x.c.gamma.value(),8)
826 self.assertEqual(b.x.d.value(),9)
827 self.assertEqual(hasattr(b,
"w"),
False)
828 self.assertEqual(hasattr(c.x,
"a"),
False)
829 self.assertEqual(hasattr(c.x,
"c"),
False)
830 self.assertRaises(TypeError,a.clone,
None,**{
"v":1})
833 def _isValid(self,value):
836 self.assertEqual(a.isModified(),
False)
838 self.assertEqual(a.isModified(),
False)
840 self.assertEqual(a.isModified(),
True)
842 self.assertEqual(a.isModified(),
False)
847 def _isValid(self,value):
849 class __DummyModule(
object):
855 self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{
"cms": __DummyModule()}).
dumpPython())
858 reg.registerSpecialImportForType(int,
"import foo")
859 self.assertRaises(
lambda x: reg.registerSpecialImportForType(int,
"import bar"))
860 reg.registerSpecialImportForType(str,
"import bar")
861 self.assertEqual(reg.getSpecialImports(), [])
863 self.assertEqual(reg.getSpecialImports(), [])
865 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
867 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
869 self.assertEqual(reg.getSpecialImports(), [
"import bar",
"import foo"])