Skip to content

Commit

Permalink
Merge pull request #10333 from Dr15Jones/longParameterLists
Browse files Browse the repository at this point in the history
Properly handle long lists of Parameters
  • Loading branch information
cmsbuild committed Jul 25, 2015
2 parents 83433ea + 184a518 commit d8b85d0
Showing 1 changed file with 64 additions and 13 deletions.
77 changes: 64 additions & 13 deletions FWCore/ParameterSet/python/Mixins.py
Expand Up @@ -229,9 +229,58 @@ def __delattr__(self,name):
def __raiseBadSetAttr(name):
raise TypeError(name+" does not already exist, so it can only be set to a CMS python configuration type")
def dumpPython(self, options=PrintOptions()):
sortedNames = sorted(self.parameterNames_())
if len(sortedNames) > 200:
#Too many parameters for a python function call
# The solution is to create a temporary dictionary which
# is constructed by concatenating long lists (with maximum
# 200 entries each) together.
# This looks like
# **dict( [(...,...), ...] + [...] + ... )
others = []
usings = []
for name in sortedNames:
param = self.__dict__[name]
# we don't want minuses in names
name2 = name.replace('-','_')
options.indent()
#_UsingNodes don't get assigned variables
if name.startswith("using_"):
usings.append(options.indentation()+param.dumpPython(options))
else:
others.append((name2, param.dumpPython(options)))
options.unindent()

resultList = ',\n'.join(usings)
longOthers = options.indentation()+"**dict(\n"
options.indent()
longOthers += options.indentation()+"[\n"
entriesInList = 0
options.indent()
for n,v in others:
entriesInList +=1
if entriesInList > 200:
#need to start a new list
options.unindent()
longOthers += options.indentation()+"] +\n"+options.indentation()+"[\n"
entriesInList = 0
options.indent()
longOthers += options.indentation()+'("'+n+'" , '+v+' ),\n'

longOthers += options.indentation()+"]\n"
options.unindent()
longOthers +=options.indentation()+")\n"
options.unindent()
ret = []
if resultList:
ret.append(resultList)
if longOthers:
ret.append(longOthers)
return ",\n".join(ret)
#Standard case, small number of parameters
others = []
usings = []
for name in sorted(self.parameterNames_()):
for name in sortedNames:
param = self.__dict__[name]
# we don't want minuses in names
name2 = name.replace('-','_')
Expand Down Expand Up @@ -358,19 +407,8 @@ def dumpPython(self, options=PrintOptions()):
nparam = len(self.parameterNames_())
if nparam == 0:
result += ")\n"
elif nparam < 256:
result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() + ")\n"
else:
# too big. Need to dump externally
#NOTE: in future should explore just creating a dict
# {'foo':cms.uint32(1), .... }
# and pass it to the constructor using the **{...} notation
label = ""
try:
label = "process."+self.label_()
except:
label = "FIX-THIS"
result += ")\n" + self.dumpPythonAttributes(label, options)
result += ",\n"+_Parameterizable.dumpPython(self,options)+options.indentation() + ")\n"
return result

def dumpPythonAttributes(self, myname, options):
Expand Down Expand Up @@ -663,4 +701,17 @@ def _isValid(self,value):
self.assertEqual(a.isModified(),True)
a.resetModified()
self.assertEqual(a.isModified(),False)
def testLargeParameterizable(self):
class tLPTest(_TypedParameterizable):
pass
class tLPTestType(_SimpleParameterTypeBase):
def _isValid(self,value):
return True
class __DummyModule(object):
def __init__(self):
self.tLPTest = tLPTest
self.tLPTestType = tLPTestType
p = tLPTest("MyType",** { "a"+str(x): tLPTestType(x) for x in xrange(0,300) } )
#check they are the same
self.assertEqual(p.dumpPython(), eval(p.dumpPython(),{"cms": __DummyModule()}).dumpPython())
unittest.main()

0 comments on commit d8b85d0

Please sign in to comment.