18 from sys
import version_info
27 if version_info >= (3,):
33 CALLABLE_FORMAT = re.compile(
34 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_]*)$"
40 from collections.abc
import Mapping
42 from collections
import Mapping
46 if not isinstance(iterable, Mapping):
47 return {c.name: c
for c
in iterable}
53 Merge configuration dictionaries ({'name': Configurable('name'), ...}) or
54 lists ([Configurable('name'), ...]) into one configuration dictionary.
56 **warning** the configurable instances passed are not cloned during the
57 merging, so the arguments to this function cannot be used afterwards
60 for config
in configs:
64 result[name].
merge(config[name])
66 result[name] = config[name]
71 from importlib
import import_module
73 if not callable(func):
74 if isinstance(func, basestring):
75 m = CALLABLE_FORMAT.match(func)
76 if m
and m.group(
"module"):
77 func = getattr(import_module(m.group(
"module")), m.group(
"callable"))
78 elif m
and m.group(
"path"):
79 globals = {
"__file__": m.group(
"path")}
82 open(m.group(
"path"),
"rb").
read(), m.group(
"path"),
"exec"
86 func = globals[m.group(
"callable")]
88 raise ValueError(
"invalid callable id %r" % func)
90 raise TypeError(
"expected either a callable or a string as first argument")