4 from pprint
import pprint
5 from FWCore.Utilities.Enumerate
import Enumerate
6 from FWCore.Utilities.FileUtils
import sectionNofTotal
9 """Infrastructure to parse variable definitions passed to cmsRun 10 configuration scripts""" 13 multiplicity = Enumerate (
"singleton list",
"multiplicity")
14 varType = Enumerate (
"bool int float string tagString")
15 commaRE = re.compile (
r',')
16 trueRE = re.compile (
r'^true$', re.IGNORECASE)
17 falseRE = re.compile (
r'^false$', re.IGNORECASE)
21 """Class initializer""" 42 VarParsing.multiplicity.singleton,
43 VarParsing.varType.string,
44 "Prepend location of files starting " 48 if lower ==
'analysis' or lower ==
'python':
52 VarParsing.multiplicity.singleton,
53 VarParsing.varType.int,
54 "Number of events to process (-1 for all)")
57 VarParsing.multiplicity.singleton,
58 VarParsing.varType.int,
59 "Total number of sections")
62 VarParsing.multiplicity.singleton,
63 VarParsing.varType.int,
64 "This section (from 1..totalSections inclusive)")
67 VarParsing.multiplicity.list,
68 VarParsing.varType.string,
70 self.
register (
'secondaryInputFiles',
72 VarParsing.multiplicity.list,
73 VarParsing.varType.string,
74 "Second group of files to process (if needed)")
77 VarParsing.multiplicity.singleton,
78 VarParsing.varType.string,
79 "String to prepend location of all files")
82 VarParsing.multiplicity.singleton,
83 VarParsing.varType.tagString,
84 "Name of output file (if needed)")
85 self.
register (
'secondaryOutputFile',
87 VarParsing.multiplicity.singleton,
88 VarParsing.varType.tagString,
89 "Name of second output file (if needed)")
92 VarParsing.multiplicity.singleton,
93 VarParsing.varType.string,
94 "tag to add to output filename")
96 ifCond =
'maxEvents > 0',
103 if lower ==
"standard":
107 VarParsing.multiplicity.singleton,
108 VarParsing.varType.int,
109 "Number of events to process (-1 for all)")
112 VarParsing.multiplicity.list,
113 VarParsing.varType.string,
117 VarParsing.multiplicity.list,
118 VarParsing.varType.string,
119 "Second group of files to process (if needed)")
122 VarParsing.multiplicity.singleton,
123 VarParsing.varType.tagString,
124 "Name of output file (if needed)")
127 VarParsing.multiplicity.singleton,
128 VarParsing.varType.tagString,
129 "Name of second output file (if needed)")
131 ifCond =
'maxEvents > 0',
132 tagArg =
'maxEvents')
135 print "Error: VarParsing.__init__ doesn't understand '%s'" \
137 raise RuntimeError(
"Failed to create VarParsing object")
141 """Sets up information for tags for output names""" 142 necessaryKeys = set ([
'ifCond',
'tag'])
143 allowedKeys = set ([
'tagArg'])
144 for key
in kwargs.keys():
145 if key
in allowedKeys:
147 if key
in necessaryKeys:
148 necessaryKeys.remove (key)
151 print "Unknown option '%s'" % key
152 raise RuntimeError(
"Unknown option")
156 print "Missing keys: %s" % necessaryKeys
157 raise runtimeError(
"Missing keys")
158 tag = kwargs.get(
'tag')
160 self.
_tags[tag] = kwargs
161 self._tagOrder.append (tag)
165 """Parses command line arguments. Parsing starts just after 166 the name of the configuration script. Parsing will fail if 167 there is not 'xxxx.py'""" 174 if not foundPy
and arg.endswith (
'.py'):
183 name, value = arg.split (
'=', 1)
186 name, command = name.split (
'_', 1)
187 command = command.lower()
188 if command ==
'load':
191 if command ==
'clear':
195 print "Unknown command '%s' in '%s_%s" % \
196 (command, name, command)
197 raise RuntimeError(
"Illegal parsing command")
201 print "Error: '%s' not registered." \
203 raise RuntimeError(
"Unknown variable")
204 if VarParsing.multiplicity.singleton == \
207 if self._beenSet.get (name)
and singleAssign:
208 print "Variable '%s' assigned multiple times. Use" \
209 ,
"'multipleAssign' command to avoid" 210 raise RuntimeError(
"Multiple assignment")
220 name, command = arg.split (
'_', 1)
221 command = command.lower()
223 print "Error: '%s' not registered." \
225 raise RuntimeError(
"Unknown variable")
226 if command ==
'clear':
231 print "Do not understand '%s' in '%s'" % (command, arg)
232 raise RuntimeError(
"Unknown command")
235 command = arg.lower()
236 if command ==
'help' or command ==
'--help':
238 elif command ==
'print' or command ==
'--print':
240 elif command ==
'noprint' or command ==
'--noprint':
244 print "Do not understand command '%s'" % (arg)
245 raise RuntimeError(
"Unknown command")
251 if 'totalSections' in self.
_register and \
254 self.totalSections
and self.section:
264 if 'storePrepend' in self.
_register and \
267 storeRE = re.compile (
r'^/store/')
270 if storeRE.match (filename):
271 filename = self.storePrepend + filename
272 newFileList.append (filename)
283 filename = self.filePrepend + filename
284 newFileList.append (filename)
291 print "VarParsing.parseArguments() Failure: No configuration " + \
292 "file found ending in .py." 293 raise RuntimeError(
"Invalid configuration ending")
302 """Empties all entries from list""" 304 print "Error: '%s' not registered." \
306 raise RuntimeError(
"Unknown variable")
307 if self.
_register[name] != VarParsing.multiplicity.list:
308 print "Error: '%s' is not a list" % name
309 raise RuntimeError(
"Faulty 'clear' command")
315 """Tells lists to not clear default list values when set from 318 print "Error: '%s' not registered." \
320 raise RuntimeError(
"Unknown variable")
321 if self.
_register[name] != VarParsing.multiplicity.list:
322 print "Error: '%s' is not a list" % name
323 raise RuntimeError(
"Faulty 'setNoDefaultClear' command")
328 """Tells lists to not split up values by commas.""" 330 print "Error: '%s' not registered." \
332 raise RuntimeError(
"Unknown variable")
333 if self.
_register[name] != VarParsing.multiplicity.list:
334 print "Error: '%s' is not a list" % name
335 raise RuntimeError(
"Faulty 'setNoCommaSplit' command")
340 """Loads a list from file""" 342 print "Error: '%s' not registered." \
344 raise RuntimeError(
"Unknown variable")
345 if self.
_register[name] != VarParsing.multiplicity.list:
346 print "Error: '%s' is not a list" % name
347 raise RuntimeError(
"'load' only works for lists")
348 filename = os.path.expanduser (filename)
349 if not os.path.exists (filename):
350 print "Error: '%s' file does not exist." 351 raise RuntimeError(
"Bad filename")
352 source = open (filename,
'r') 353 for line
in source.readlines():
354 line = re.sub (
r'#.+$',
'', line)
362 """Prints out help information and exits""" 366 multipleAssign : Allows singletons to have multiple assigments 367 print : Prints out current values 368 XXX_clear : Clears list named 'XXX' 375 mult = multiplicity.singleton,
376 mytype = varType.int,
379 """Register a variable""" 381 if not VarParsing.multiplicity.isValidValue (mult):
382 print "Error: VarParsing.register() must use ",\
383 "VarParsing.multiplicity." 384 raise RuntimeError(
"Improper 'mult' value")
385 if not VarParsing.varType.isValidValue (mytype):
386 print "Error: VarParsing.register() must use ",\
387 "VarParsing.varType." 388 raise RuntimeError(
"Improper 'type' value %s" % mytype)
389 if VarParsing.multiplicity.list == mult
and \
390 VarParsing.varType.tagString == mytype:
391 print "Error: 'tagString' can only be used with 'singleton'" 392 raise RuntimeError(
"Improper registration")
395 print "Error: Name can not contain '_': %s" % name
396 raise RuntimeError(
"Improper 'name'")
400 print "Error: You can not register a name twice, '%s'" \
402 raise RuntimeError(
"Attempt to re-register variable")
405 self.
_info[name] = info
406 self.
_types[name] = mytype
409 if VarParsing.multiplicity.singleton == mult:
416 self.
_lists[name].append (default)
422 if kwargs.get (
'noCommaSplit'):
424 del kwargs[
'noCommaSplit']
425 if kwargs.get (
'noDefaultClear'):
427 del kwargs[
'noDefaultClear']
429 raise RuntimeError(
"register() Unknown arguments %s" % kwargs)
433 """Returns true if a key is registered""" 438 """Change the type of 'name' to 'mytype'""" 439 if not VarParsing.varType.isValidValue (mytype):
440 print "Error: VarParsing.setType() must use ",\
441 "VarParsing.varType." 442 raise RuntimeError(
"Improper 'type' value")
444 self.
_types[name] = mytype
449 """Used to set or change the default of an already registered 453 print "Error: VarParsing.setDefault '%s' not already registered." \
455 raise RuntimeError(
"setDefault without registration")
456 if VarParsing.multiplicity.singleton == self.
_register[name]:
459 print "Error: VarParsing.setDefault needs exactly 1 ",\
460 "value for '%s'" % name
461 raise RuntimeError(
"setDefault args problem")
472 not self._setDuringParsing.get(name)
and \
473 not self._noDefaultClear.get(name):
483 if isinstance (args, tuple)
and len (args) == 1:
486 if isinstance (args, tuple):
488 elif isinstance (args, list):
493 if not self._noCommaSplit.get (name):
497 mylist.extend( VarParsing.commaRE.split( item ) )
503 """Converts inputVal to the type required by name""" 504 inputVal = str (inputVal)
505 if self.
_types[name] == VarParsing.varType.bool:
506 if VarParsing.trueRE.match (inputVal)
or '1' == inputVal:
508 elif VarParsing.falseRE.match (inputVal)
or '0' == inputVal:
511 raise RuntimeError(
"Unknown bool value '%s'. Must be 'true' or 'false'" % inputVal)
512 if self.
_types[name] == VarParsing.varType.string
or \
513 self.
_types[name] == VarParsing.varType.tagString:
515 elif self.
_types[name] == VarParsing.varType.int:
516 return int (inputVal, 0)
517 elif self.
_types[name] == VarParsing.varType.float:
518 return float (inputVal)
520 raise RuntimeError(
"Unknown varType")
525 print "Error: '%s' not registered." \
527 raise RuntimeError(
"Unknown variable")
528 if self.
_register[name] == VarParsing.multiplicity.list:
529 print "Error: '%s' is a list" % name
530 raise RuntimeError(
"withTags() only works on singletons")
532 if retval.endswith (
'.root'):
533 retval, garbage = os.path.splitext (retval)
535 reverseOrder.reverse()
536 for tag
in reverseOrder:
537 tagDict = self.
_tags[tag]
538 ifCond = tagDict[
'ifCond']
539 if ifCond.count(
'%'):
542 ifCond =
"self." + ifCond
543 boolValue = eval (ifCond)
544 tagArg = tagDict.get (
'tagArg')
546 evalString =
"'%s' %% self.%s" % (tag, tagArg)
547 tag = eval (evalString)
549 retval = retval +
"_" + tag
550 return retval +
".root" 554 """String form of self""" 556 form =
" %%-%ds: %%s" % maxLen
557 formInfo =
" %%%ds - %%s" % (maxLen - 2)
558 formItem =
" %%%ds %%s" % (maxLen - 1)
560 if len (self._singletons.keys()):
561 retval = retval +
"Singletons:\n" 562 for varName, value
in sorted (self._singletons.iteritems()):
563 retval = retval + form % (varName, value) +
"\n";
564 if self._info.get(varName):
565 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n" 566 if len (self._singletons.keys()):
567 retval = retval +
"Lists:\n" 568 for varName, value
in sorted (self._lists.iteritems()):
569 stringValue =
"%s" % value
570 if len (stringValue) < 76 - maxLen:
571 retval = retval + form % (varName, value) +
"\n" 573 varLength = len (value)
574 for index, item
in enumerate (value):
576 retval = retval + form % (varName,
"['" + item)
578 retval = retval + formItem % (
'',
"'" + item)
579 if index == varLength - 1:
580 retval = retval +
"' ]\n" 582 retval = retval +
"',\n" 583 if self._info.get(varName):
584 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n" 589 """Lets me set internal values, or uses setDefault""" 590 if not name.startswith (
"_"):
591 mylist = list (extras)
592 mylist.insert (0, value)
595 object.__setattr__ (self, name, value)
599 """Lets user get the info they want with obj.name""" 600 if name.startswith (
"_"):
602 return object.__getattribute__ (self, name)
606 print "Error: '%s' not already registered." \
608 raise RuntimeError(
"Unknown variable")
609 if VarParsing.multiplicity.singleton == self.
_register[name]:
610 if VarParsing.varType.tagString == self.
_types[name] \
626 if __name__ ==
"__main__":
633 historyPath = os.path.expanduser(
"~/.pyhistory")
638 readline.write_history_file(historyPath)
639 if os.path.exists(historyPath):
640 readline.read_history_file(historyPath)
643 atexit.register(save_history)
644 readline.parse_and_bind(
"set show-all-if-ambiguous on")
645 readline.parse_and_bind(
"tab: complete")
646 if os.path.exists (historyPath) :
647 readline.read_history_file(historyPath)
648 readline.set_history_length(-1)
655 obj = VarParsing (
'standard')
656 obj.register (
'someVar',
657 mult=VarParsing.multiplicity.singleton,
659 obj.setupTags (tag =
"someCondition",
def setupTags(self, kwargs)
inputFiles
Post-loading processing #.
def _withTags(self, name)
def setNoCommaSplit(self, name, value=True)
def setType(self, name, mytype)
def setNoDefaultClear(self, name, value=True)
def save_history(historyPath=historyPath)
def register(self, name, default="", mult=multiplicity.singleton, mytype=varType.int, info="", kwargs)
def __getattr__(self, name, noTags=False)
def loadFromFile(self, name, filename)
def setDefault(self, name, args)
def __setattr__(self, name, value, extras)
def _convert(self, name, inputVal)
def clearList(self, name)