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):
425 if self._Parameterizable__validator
is not None:
426 myparams[
"allowAnyLabel_"] = self._Parameterizable__validator
428 returnValue.__init__(self.__type,*args,
430 returnValue._isModified =
False
431 returnValue._isFrozen =
False
442 choices.extend(glob.glob(d+
'/*/*/'+label+
'.py'))
452 mod = __import__(name)
453 components = name.split(
'.')
454 for comp
in components[1:]:
455 mod = getattr(mod,comp)
456 if hasattr(mod,label):
457 default = getattr(mod,label)
458 if isinstance(default,_TypedParameterizable):
459 if(default.type_() == type):
461 for name
in default.parameterNames_():
462 params[name] = getattr(default,name)
470 config = self.__type +
' { \n'
472 param = self.__dict__[name]
474 config+=options.indentation()+param.configTypeName()+
' '+name+
' = '+param.configValue(options)+
'\n'
476 config += options.indentation()+
'}\n'
480 specialImportRegistry.registerUse(self)
481 result =
"cms."+
str(type(self).__name__)+
'("'+self.
type_()+
'"'
486 result +=
",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() +
")\n"
490 """ dumps the object with all attributes declared after the constructor"""
493 param = self.__dict__[name]
494 result += options.indentation() + myname +
"." + name +
" = " + param.dumpPython(options) +
"\n"
504 newpset = parameterSet.newPSet()
505 newpset.addString(
True,
"@module_label", self.
moduleLabel_(myname))
506 newpset.addString(
True,
"@module_type", self.
type_())
507 newpset.addString(
True,
"@module_edm_type", type(self).__name__)
514 """A 'mixin' used to denote that the class can be paired with a label (e.g. an EDProducer)"""
516 if not hasattr(self,
"_Labelable__label"):
517 raise RuntimeError(
"module has no label. Perhaps it wasn't inserted into the process?")
520 return hasattr(self,
"_Labelable__label")
and self.
__label is not None
523 if self.
label_() != label
and label
is not None :
524 msg100 =
"Attempting to change the label of a Labelable object, possibly an attribute of the Process\n"
525 msg101 =
"Old label = "+self.
label_()+
" New label = "+label+
"\n"
526 msg102 =
"Type = "+
str(type(self))+
"\n"
527 msg103 =
"Some possible solutions:\n"
528 msg104 =
" 1. Clone modules instead of using simple assignment. Cloning is\n"
529 msg105 =
" also preferred for other types when possible.\n"
530 msg106 =
" 2. Declare new names starting with an underscore if they are\n"
531 msg107 =
" for temporaries you do not want propagated into the Process. The\n"
532 msg108 =
" underscore tells \"from x import *\" and process.load not to import\n"
533 msg109 =
" the name.\n"
534 msg110 =
" 3. Reorganize so the assigment is not necessary. Giving a second\n"
535 msg111 =
" name to the same object usually causes confusion and problems.\n"
536 msg112 =
" 4. Compose Sequences: newName = cms.Sequence(oldName)\n"
537 raise ValueError(msg100+msg101+msg102+msg103+msg104+msg105+msg106+msg107+msg108+msg109+msg110+msg111+msg112)
556 myDeps=knownDeps.get(self.
label_(),
None)
558 if presentDeps != myDeps:
559 raise RuntimeError(
"the module "+self.
label_()+
" has two dependencies \n"
560 +
str(presentDeps)+
"\n"
562 +
"Please modify sequences to rectify this inconsistency")
564 myDeps=set(presentDeps)
565 knownDeps[self.
label_()]=myDeps
566 presentDeps.add(self.
label_())
570 """A 'mixin' used to denote that the class can be used without a label (e.g. a Service)"""
573 class _ValidatingListBase(list):
574 """Base class for a list which enforces that its entries pass a 'validity' test"""
576 super(_ValidatingListBase,self).
__init__(arg)
578 raise SyntaxError(
"named arguments ("+
','.
join([x
for x
in args])+
") passsed to "+
str(type(self)))
580 raise TypeError(
"wrong types ("+
','.
join([
str(type(value))
for value
in iter(self)])+
581 ") added to "+
str(type(self)))
583 if isinstance(key,slice):
585 raise TypeError(
"wrong type being inserted into this container "+self.
_labelIfAny())
587 if not self._itemIsValid(value):
588 raise TypeError(
"can not insert the type "+
str(type(value))+
" in container "+self.
_labelIfAny())
589 super(_ValidatingListBase,self).
__setitem__(key,value)
592 if isinstance(seq, str):
595 if not self._itemIsValid(item):
601 if isinstance(seq, str):
606 if not self._itemIsValid(x):
607 raise TypeError(
"wrong type being appended to container "+self.
_labelIfAny())
611 raise TypeError(
"wrong type being extended to container "+self.
_labelIfAny())
615 raise TypeError(
"wrong type being added to container "+self.
_labelIfAny())
617 value = copy.copy(self)
621 if not self._itemIsValid(x):
622 raise TypeError(
"wrong type being inserted to container "+self.
_labelIfAny())
625 result = type(self).__name__
626 if hasattr(self,
'__label'):
627 result +=
' ' + self.__label
632 _ParameterTypeBase.__init__(self)
633 if len (arg) == 1
and not isinstance(arg[0],str):
638 super(_ValidatingParameterListBase,self).
__init__(*arg,**args)
648 for value
in iter(self):
650 config += options.indentation()
656 config += options.indentation()+
'}\n'
665 specialImportRegistry.registerUse(self)
668 if hasattr(self,
"_nPerLine"):
669 nPerLine = self._nPerLine
672 if n>nPerLine: options.indent()
676 for i, v
in enumerate(self):
678 if n>nPerLine: result +=
'\n'+options.indentation()
681 if i % nPerLine == 0:
682 result +=
'\n'+options.indentation()
686 result +=
'\n'+options.indentation()
699 fInfo = inspect.getframeinfo(sys._getframe(level+1))
700 obj._filename = fInfo.filename
701 obj._lineNumber =fInfo.lineno
706 for key,value
in six.iteritems(newParams):
710 elif isinstance(value, dict):
711 if isinstance(params[key],_Parameterizable):
713 p =pset.parameters_()
714 oldkeys = set(p.keys())
717 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
718 for k,v
in six.iteritems(p):
723 elif isinstance(params[key],_ValidatingParameterListBase):
724 if any(
not isinstance(k, int)
for k
in value.keys()):
725 raise TypeError(
"Attempted to change a list using a dict whose keys are not integers")
727 if any((k < 0
or k >= len(plist))
for k
in value.keys()):
728 raise IndexError(
"Attempted to set an index which is not in the list")
729 p = dict(enumerate(plist))
732 (
"%s.%s" if isinstance(key, str)
else "%s[%s]")%(keyDepth,key))
733 for k,v
in six.iteritems(p):
736 raise ValueError(
"Attempted to change non PSet value "+keyDepth+
" using a dictionary")
737 elif isinstance(value,_ParameterTypeBase)
or (isinstance(key, int))
or isinstance(value, _Parameterizable):
742 if isinstance(value,_ParameterTypeBase)
or isinstance(value, _Parameterizable):
748 if __name__ ==
"__main__":
757 self.assertEqual(t,[1])
759 self.assertEqual(t,[1])
761 self.assertEqual(t,[
"one"])
763 self.assertEqual(t,[1])
765 self.assertEqual(t,[1])
768 self.assertEqual(t,[1,2])
770 self.assertEqual(t,[1,2])
772 self.assertEqual(t,[
"one",
"two"])
774 self.assertEqual(t,[
"one",
"two"])
776 self.assertEqual(t,[1,2])
778 self.assertEqual(t,[1,2])
780 self.assertEqual(t,[1,2])
786 args = [i
for i
in range(0,300)]
789 pdump= t.dumpPython()
793 pythonized = eval( pdump, globals(),{
'cms':
cms()} )
794 self.assertEqual(t,pythonized)
797 self.assert_(isinstance(a, _ParameterTypeBase))
802 def _isValid(self,value):
804 a = __Test(
"MyType",t=__TestType(1), u=__TestType(2))
806 self.assertEqual(b.t.value(),1)
807 self.assertEqual(b.u.value(),2)
812 def _isValid(self,value):
815 def __init__(self,*arg,**args):
817 _ParameterTypeBase.__init__(self)
818 _Parameterizable.__init__(self,*arg,**args)
823 x = __PSet(a = __TestType(4),
825 c = __PSet(gamma = __TestType(5))))
832 c = a.clone(x = dict(a=
None, c=
None))
833 self.assertEqual(a.t.value(),1)
834 self.assertEqual(a.u.value(),2)
835 self.assertEqual(b.t.value(),3)
836 self.assertEqual(b.u.value(),2)
837 self.assertEqual(b.v.value(),4)
838 self.assertEqual(b.x.a.value(),7)
839 self.assertEqual(b.x.b.value(),6)
840 self.assertEqual(b.x.c.gamma.value(),8)
841 self.assertEqual(b.x.d.value(),9)
842 self.assertEqual(hasattr(b,
"w"),
False)
843 self.assertEqual(hasattr(c.x,
"a"),
False)
844 self.assertEqual(hasattr(c.x,
"c"),
False)
845 self.assertRaises(TypeError,a.clone,
None,**{
"v":1})
848 def _isValid(self,value):
851 self.assertEqual(a.isModified(),
False)
853 self.assertEqual(a.isModified(),
False)
855 self.assertEqual(a.isModified(),
True)
857 self.assertEqual(a.isModified(),
False)
862 def _isValid(self,value):
864 class __DummyModule(
object):
870 self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{
"cms": __DummyModule()}).
dumpPython())
873 reg.registerSpecialImportForType(int,
"import foo")
874 self.assertRaises(
lambda x: reg.registerSpecialImportForType(int,
"import bar"))
875 reg.registerSpecialImportForType(str,
"import bar")
876 self.assertEqual(reg.getSpecialImports(), [])
878 self.assertEqual(reg.getSpecialImports(), [])
880 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
882 self.assertEqual(reg.getSpecialImports(), [
"import foo"])
884 self.assertEqual(reg.getSpecialImports(), [
"import bar",
"import foo"])