29 CALLABLE_FORMAT = re.compile(
30 r"^(?:(?P<module>[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)|(?P<path>[^\0]+\.py)):(?P<callable>[a-zA-Z_][a-zA-Z0-9_]*)$"
36 from collections.abc
import Mapping
38 from collections
import Mapping
42 if not isinstance(iterable, Mapping):
43 return {c.name: c
for c
in iterable}
49 Merge configuration dictionaries ({'name': Configurable('name'), ...}) or
50 lists ([Configurable('name'), ...]) into one configuration dictionary.
52 **warning** the configurable instances passed are not cloned during the
53 merging, so the arguments to this function cannot be used afterwards
56 for config
in configs:
60 result[name].
merge(config[name])
62 result[name] = config[name]
67 from importlib
import import_module
69 if not callable(func):
70 if isinstance(func, str):
71 m = CALLABLE_FORMAT.match(func)
72 if m
and m.group(
"module"):
73 func = getattr(import_module(m.group(
"module")), m.group(
"callable"))
74 elif m
and m.group(
"path"):
75 globals = {
"__file__": m.group(
"path")}
78 open(m.group(
"path"),
"rb").
read(), m.group(
"path"),
"exec"
82 func = globals[m.group(
"callable")]
84 raise ValueError(
"invalid callable id %r" % func)
86 raise TypeError(
"expected either a callable or a string as first argument")