Skip to content

Commit b98d027

Browse files
Python interface: various PR bugs caught by Copilot
1 parent 8fa1a79 commit b98d027

4 files changed

Lines changed: 40 additions & 24 deletions

File tree

sbnalg/gallery/python/LArSoftUtils.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def serviceClassToConfigKeys(serviceClassName: str) -> list[str]:
226226
candidates = []
227227

228228
# remove namespaces (namespaces are not part of any candidate)
229-
try: serviceClassName = serviceClassName[:serviceClassName.index('::')]
229+
try: serviceClassName = serviceClassName[serviceClassName.rindex('::')+2:]
230230
except ValueError: pass # no namespace
231231

232232
if not serviceClassName: return [] # ?!
@@ -284,10 +284,10 @@ def readServiceConfig(getConfig, configKey, returnConfigKey = True):
284284
= tuple(base + suffix for base in serviceClassToConfigKeys(configKey))
285285

286286
Logger.debug("Configuration from candidates: '%s'", "', '".join(configKeys))
287-
for configKey in configKeys:
288-
try: config = getConfig(configKey)
287+
for candidateKey in configKeys:
288+
try: config = getConfig(candidateKey)
289289
except Exception: continue
290-
return (config, configKey) if returnConfigKey else config
290+
return (config, candidateKey) if returnConfigKey else config
291291
raise RuntimeError(f"No configuration for service key '{configKey}'")
292292
# readServiceConfig()
293293

@@ -319,6 +319,7 @@ def loadSimpleService \
319319
config = readServiceConfig(
320320
getConfig=(config.service if config else registry.config),
321321
configKey=serviceName,
322+
returnConfigKey=False,
322323
)
323324
except RuntimeError:
324325
Logger.debug("Full configuration:\n%s",
@@ -400,7 +401,10 @@ def __init__(self,
400401
def _needsSpecialConfig(self): return self.addConfig or self.purgeConfig
401402

402403
def _makeConfig(self, registry):
403-
"""See the constructor for details on the configuration key algorithm."""
404+
"""Fetches, finalizes and returns the FHiCL configuration for the service.
405+
406+
See the constructor for details on the configuration key algorithm.
407+
"""
404408

405409
configKey = self.configKey
406410
if not configKey or configKey.startswith('.'):
@@ -471,16 +475,15 @@ def _loadService(self, manager, dependencies):
471475
The dependencies are expected to be a dictionary: provider name → provider object
472476
(`None` if not available).
473477
"""
474-
475-
# if we don't need a special configuration,
476-
# we let loadSimpleService() find it
478+
479+
# put together the configuration of the service being loaded
477480
registry = manager.registry()
478481
config = self._makeConfig(registry)
479482
Logger.debug("Service configuration:\n%s", config.to_indented_string())
480483

481484
self._loadCode()
482485

483-
# loads the actual classes from ROOT
486+
# load the actual classes from ROOT
484487
self.expandClass('serviceClass')
485488
if self.interfaceClass is not None: self.expandClass('interfaceClass')
486489

@@ -701,6 +704,8 @@ def fullConfig(self): return self.serviceTable is None
701704
def isValid(self): return self.configPath is not None
702705
def hasExtraConfig(self): return bool(self.extraConfig)
703706
def needsCustom(self): return not self.fullConfig() or self.hasExtraConfig()
707+
def serviceTableName(self):
708+
return 'services' if self.fullConfig() else self.serviceTable
704709

705710
def addExtraConfig(self, extra): self.extraConfig += "\n" + extra
706711

@@ -743,7 +748,15 @@ def get(self, serviceKey, interfaceClass = None):
743748
# get()
744749

745750

746-
def defaultConfiguration(self): return None
751+
def defaultConfiguration(self):
752+
"""Returns the default configuration.
753+
754+
The configuration is delivered as a ServiceManagerInstance.ConfigurationInfo object.
755+
This configuration is used when the service manager is not explicitly
756+
configured with `setConfiguration()`.
757+
"""
758+
return ServiceManagerInstance.ConfigurationInfo()
759+
# defaultConfiguration()
747760

748761
def setConfiguration(self, configFile, serviceTable = None, extra = ""):
749762
"""Sets which configuration to use for setup.
@@ -787,7 +800,12 @@ def loadConfiguration(self):
787800
else self.defaultConfiguration()
788801

789802
# if assertion fails, then `setConfiguration()` was not correctly called.
790-
assert configurationInfo.isValid()
803+
if not configurationInfo or not configurationInfo.isValid():
804+
raise RuntimeError(
805+
"No configuration in place at setup time. Call 'setConfiguration()'"
806+
" or override 'defaultConfiguration()' to provide a configuration file path."
807+
)
808+
# if
791809

792810
if configurationInfo.needsCustom():
793811
Logger.debug(
@@ -811,7 +829,7 @@ def loadConfiguration(self):
811829
'\n# ==============================='
812830
.format(
813831
configPath=configurationInfo.configPath,
814-
serviceTable=configurationInfo.serviceTable,
832+
serviceTable=configurationInfo.serviceTableName(),
815833
extraConfig=configurationInfo.extraConfig,
816834
)
817835
)

sbnalg/gallery/python/ROOTutils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def expandFileList(
287287
288288
NOTE: because of the internal implementation, a `fileListPaths` that is a
289289
collection of file names that are all one character long may be mistaken
290-
for a string. The general solution is: do not name your file not file lists
290+
for a string. The general solution is: do not name your file nor file lists
291291
with a single-character name. It's most often a bad idea anyway.
292292
"""
293293

@@ -308,7 +308,7 @@ def expandFileList(
308308
# Just don't call your file lists "a", "b" etc. Nor your files.
309309
# Nevertheless, some special cases are singled out and specifically addressed.
310310

311-
isClearlyList = isinstance(fileListPaths, (ROOT.std.vector[ROOT.std.string], list, set))
311+
isClearlyList = isinstance(fileListPaths, (ROOT.std.vector[ROOT.std.string], list, tuple, set))
312312
isClearlyPath = isinstance(fileListPaths, (ROOT.std.string, str))
313313
# we expand the argument to support single-pass generators; what happens?
314314
# str -> list[str] (one character each element)

sbnalg/gallery/python/cppUtils.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,13 @@ def loadMany(self, *pathSpecs, extraPaths = [], force = False, loadAll = False):
145145
"""Calls `load()` for each of the path specifications.
146146
147147
A path specification is a dictionary of `load()` parameters, e.g.
148-
`{ relPath: 'larcorealg_Geometry', extraPaths: [] }`.
148+
`dict(relPath='larcorealg_Geometry', extraPaths=[])`.
149149
If a path specification is not a dictionary, it is assumed to be a `relPath`
150-
and it is equivalent to having `{ relPath: pathSpec }`.
151-
If an argument `extraPath` or `force` is specified in the path
152-
specification, a value is used from the `extraPath` and `force` arguments
153-
of this function.
150+
and it is equivalent to having `dict(relPath=pathSpec)`.
151+
If `extraPaths` or `force` are not specified in a path specification,
152+
they default to the `extraPaths` and `force` arguments of this function;
153+
if they are specified in the path specification, their values override
154+
the defaults from this function.
154155
155156
If `loadAll` is set, all loads are attempted; the return value is a pair:
156157
whether an exception was thrown, and a list of all return values or

sbnalg/gallery/python/galleryUtils.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,8 @@ def eventLoop(inputFiles,
289289
nSkip = options.get('nSkip', 0)
290290
nEvents = options.get('nEvents', None)
291291

292-
# make sure the input file list is in the right format
293-
if not isinstance(inputFiles, ROOT.vector(ROOT.string)):
294-
if isinstance(inputFiles, str): inputFiles = [ inputFiles, ]
295-
inputFiles = makeFileList(*inputFiles)
296-
# if
292+
# create a gallery event with an expanded (flattened) input list
293+
inputFiles = makeFileList(inputFiles)
297294

298295
event = ROOT.gallery.Event(inputFiles)
299296

0 commit comments

Comments
 (0)