141 lines
3.6 KiB
Python
141 lines
3.6 KiB
Python
from collections import namedtuple
|
|
|
|
|
|
def isconfigurable(mixed):
|
|
"""
|
|
Check if the given argument is an instance of :class:`bonobo.config.Configurable`.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
from bonobo.config.configurables import Configurable
|
|
|
|
return isinstance(mixed, Configurable)
|
|
|
|
|
|
def isconfigurabletype(mixed, *, strict=False):
|
|
"""
|
|
Check if the given argument is an instance of :class:`bonobo.config.ConfigurableMeta`, meaning it has all the
|
|
plumbery necessary to build :class:`bonobo.config.Configurable`-like instances.
|
|
|
|
:param mixed:
|
|
:param strict: should we consider partially configured objects?
|
|
:return: bool
|
|
"""
|
|
from bonobo.config.configurables import ConfigurableMeta, PartiallyConfigured
|
|
|
|
if isinstance(mixed, ConfigurableMeta):
|
|
return True
|
|
|
|
if strict:
|
|
return False
|
|
|
|
if isinstance(mixed, PartiallyConfigured):
|
|
return True
|
|
|
|
if hasattr(mixed, "_partial") and mixed._partial:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def isoption(mixed):
|
|
"""
|
|
Check if the given argument is an instance of :class:`bonobo.config.Option`.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
|
|
from bonobo.config.options import Option
|
|
|
|
return isinstance(mixed, Option)
|
|
|
|
|
|
def ismethod(mixed):
|
|
"""
|
|
Check if the given argument is an instance of :class:`bonobo.config.Method`.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
from bonobo.config.options import Method
|
|
|
|
return isinstance(mixed, Method)
|
|
|
|
|
|
def iscontextprocessor(x):
|
|
"""
|
|
Check if the given argument is an instance of :class:`bonobo.config.ContextProcessor`.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
from bonobo.config.processors import ContextProcessor
|
|
|
|
return isinstance(x, ContextProcessor)
|
|
|
|
|
|
def istype(mixed):
|
|
"""
|
|
Check if the given argument is a type object.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
return isinstance(mixed, type)
|
|
|
|
|
|
def isdict(mixed):
|
|
"""
|
|
Check if the given argument is a dict.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
return isinstance(mixed, dict)
|
|
|
|
|
|
def istuple(mixed):
|
|
"""
|
|
Check if the given argument is a tuple.
|
|
|
|
:param mixed:
|
|
:return: bool
|
|
"""
|
|
return isinstance(mixed, tuple)
|
|
|
|
|
|
ConfigurableInspection = namedtuple("ConfigurableInspection", ["type", "instance", "options", "processors", "partial"])
|
|
|
|
ConfigurableInspection.__enter__ = lambda self: self
|
|
ConfigurableInspection.__exit__ = lambda *exc_details: None
|
|
|
|
|
|
def inspect_node(mixed, *, _partial=None):
|
|
"""
|
|
If the given argument is somehow a :class:`bonobo.config.Configurable` object (either a subclass, an instance, or
|
|
a partially configured instance), then it will return a :class:`ConfigurableInspection` namedtuple, used to inspect
|
|
the configurable metadata (options). If you want to get the option values, you don't need this, it is only usefull
|
|
to perform introspection on a configurable.
|
|
|
|
If it's not looking like a configurable, it will raise a :class:`TypeError`.
|
|
|
|
:param mixed:
|
|
:return: ConfigurableInspection
|
|
|
|
:raise: TypeError
|
|
"""
|
|
if isconfigurabletype(mixed, strict=True):
|
|
inst, typ = None, mixed
|
|
elif isconfigurable(mixed):
|
|
inst, typ = mixed, type(mixed)
|
|
elif hasattr(mixed, "func"):
|
|
return inspect_node(mixed.func, _partial=(mixed.args, mixed.keywords))
|
|
else:
|
|
raise TypeError(
|
|
"Not a Configurable, nor a Configurable instance and not even a partially configured Configurable. Check your inputs."
|
|
)
|
|
|
|
return ConfigurableInspection(typ, inst, list(typ.__options__), list(typ.__processors__), _partial)
|