def configurable(init_func=None, *, from_config=None):
    '\n    Decorate a function or a class\'s __init__ method so that it can be called\n    with a :class:`CfgNode` object using a :func:`from_config` function that translates\n    :class:`CfgNode` to arguments.\n\n    Examples:\n    ::\n        # Usage 1: Decorator on __init__:\n        class A:\n            @configurable\n            def __init__(self, a, b=2, c=3):\n                pass\n\n            @classmethod\n            def from_config(cls, cfg):   # \'cfg\' must be the first argument\n                # Returns kwargs to be passed to __init__\n                return {"a": cfg.A, "b": cfg.B}\n\n        a1 = A(a=1, b=2)  # regular construction\n        a2 = A(cfg)       # construct with a cfg\n        a3 = A(cfg, b=3, c=4)  # construct with extra overwrite\n\n        # Usage 2: Decorator on any function. Needs an extra from_config argument:\n        @configurable(from_config=lambda cfg: {"a: cfg.A, "b": cfg.B})\n        def a_func(a, b=2, c=3):\n            pass\n\n        a1 = a_func(a=1, b=2)  # regular call\n        a2 = a_func(cfg)       # call with a cfg\n        a3 = a_func(cfg, b=3, c=4)  # call with extra overwrite\n\n    Args:\n        init_func (callable): a class\'s ``__init__`` method in usage 1. The\n            class must have a ``from_config`` classmethod which takes `cfg` as\n            the first argument.\n        from_config (callable): the from_config function in usage 2. It must take `cfg`\n            as its first argument.\n    '

    def check_docstring(func):
        if func.__module__.startswith('detectron2.'):
            assert ((func.__doc__ is not None) and ('experimental' in func.__doc__.lower())), f'configurable {func} should be marked experimental'
    if (init_func is not None):
        assert (inspect.isfunction(init_func) and (from_config is None) and (init_func.__name__ == '__init__')), 'Incorrect use of @configurable. Check API documentation for examples.'
        check_docstring(init_func)

        @functools.wraps(init_func)
        def wrapped(self, *args, **kwargs):
            try:
                from_config_func = type(self).from_config
            except AttributeError as e:
                raise AttributeError("Class with @configurable must have a 'from_config' classmethod.") from e
            if (not inspect.ismethod(from_config_func)):
                raise TypeError("Class with @configurable must have a 'from_config' classmethod.")
            if _called_with_cfg(*args, **kwargs):
                explicit_args = _get_args_from_config(from_config_func, *args, **kwargs)
                init_func(self, **explicit_args)
            else:
                init_func(self, *args, **kwargs)
        return wrapped
    else:
        if (from_config is None):
            return configurable
        assert inspect.isfunction(from_config), 'from_config argument of configurable must be a function!'

        def wrapper(orig_func):
            check_docstring(orig_func)

            @functools.wraps(orig_func)
            def wrapped(*args, **kwargs):
                if _called_with_cfg(*args, **kwargs):
                    explicit_args = _get_args_from_config(from_config, *args, **kwargs)
                    return orig_func(**explicit_args)
                else:
                    return orig_func(*args, **kwargs)
            return wrapped
        return wrapper
Decorate a function or a class's __init__ method so that it can be called
with a :class:`CfgNode` object using a :func:`from_config` function that translates
:class:`CfgNode` to arguments.

Examples:
::
    # Usage 1: Decorator on __init__:
    class A:
        @configurable
        def __init__(self, a, b=2, c=3):
            pass

        @classmethod
        def from_config(cls, cfg):   # 'cfg' must be the first argument
            # Returns kwargs to be passed to __init__
            return {"a": cfg.A, "b": cfg.B}

    a1 = A(a=1, b=2)  # regular construction
    a2 = A(cfg)       # construct with a cfg
    a3 = A(cfg, b=3, c=4)  # construct with extra overwrite

    # Usage 2: Decorator on any function. Needs an extra from_config argument:
    @configurable(from_config=lambda cfg: {"a: cfg.A, "b": cfg.B})
    def a_func(a, b=2, c=3):
        pass

    a1 = a_func(a=1, b=2)  # regular call
    a2 = a_func(cfg)       # call with a cfg
    a3 = a_func(cfg, b=3, c=4)  # call with extra overwrite

Args:
    init_func (callable): a class's ``__init__`` method in usage 1. The
        class must have a ``from_config`` classmethod which takes `cfg` as
        the first argument.
    from_config (callable): the from_config function in usage 2. It must take `cfg`
        as its first argument.
def configurable(init_func=None, *, from_config=None):
    '\n    Decorate a function or a class\'s __init__ method so that it can be called\n    with a :class:`CfgNode` object using a :func:`from_config` function that translates\n    :class:`CfgNode` to arguments.\n\n    Examples:\n    ::\n        # Usage 1: Decorator on __init__:\n        class A:\n            @configurable\n            def __init__(self, a, b=2, c=3):\n                pass\n\n            @classmethod\n            def from_config(cls, cfg):   # \'cfg\' must be the first argument\n                # Returns kwargs to be passed to __init__\n                return {"a": cfg.A, "b": cfg.B}\n\n        a1 = A(a=1, b=2)  # regular construction\n        a2 = A(cfg)       # construct with a cfg\n        a3 = A(cfg, b=3, c=4)  # construct with extra overwrite\n\n        # Usage 2: Decorator on any function. Needs an extra from_config argument:\n        @configurable(from_config=lambda cfg: {"a: cfg.A, "b": cfg.B})\n        def a_func(a, b=2, c=3):\n            pass\n\n        a1 = a_func(a=1, b=2)  # regular call\n        a2 = a_func(cfg)       # call with a cfg\n        a3 = a_func(cfg, b=3, c=4)  # call with extra overwrite\n\n    Args:\n        init_func (callable): a class\'s ``__init__`` method in usage 1. The\n            class must have a ``from_config`` classmethod which takes `cfg` as\n            the first argument.\n        from_config (callable): the from_config function in usage 2. It must take `cfg`\n            as its first argument.\n    '

    def check_docstring(func):
        if func.__module__.startswith('detectron2.'):
            assert ((func.__doc__ is not None) and ('experimental' in func.__doc__.lower())), f'configurable {func} should be marked experimental'
    if (init_func is not None):
        assert (inspect.isfunction(init_func) and (from_config is None) and (init_func.__name__ == '__init__')), 'Incorrect use of @configurable. Check API documentation for examples.'
        check_docstring(init_func)

        @functools.wraps(init_func)
        def wrapped(self, *args, **kwargs):
            try:
                from_config_func = type(self).from_config
            except AttributeError as e:
                raise AttributeError("Class with @configurable must have a 'from_config' classmethod.") from e
            if (not inspect.ismethod(from_config_func)):
                raise TypeError("Class with @configurable must have a 'from_config' classmethod.")
            if _called_with_cfg(*args, **kwargs):
                explicit_args = _get_args_from_config(from_config_func, *args, **kwargs)
                init_func(self, **explicit_args)
            else:
                init_func(self, *args, **kwargs)
        return wrapped
    else:
        if (from_config is None):
            return configurable
        assert inspect.isfunction(from_config), 'from_config argument of configurable must be a function!'

        def wrapper(orig_func):
            check_docstring(orig_func)

            @functools.wraps(orig_func)
            def wrapped(*args, **kwargs):
                if _called_with_cfg(*args, **kwargs):
                    explicit_args = _get_args_from_config(from_config, *args, **kwargs)
                    return orig_func(**explicit_args)
                else:
                    return orig_func(*args, **kwargs)
            return wrapped
        return wrapper