src/sisy/models.py
def func_from_string(callable_str):
    """Return a live function from a full dotted path.  Must be either a plain function
    directly in a module, a class function, or a static function.  (No modules, classes,
    or instance methods, since those can't be called as tasks.)"""
    components = callable_str.split('.')

    func = None

    if len(components) < 2:
        raise ValueError("Need full dotted path to task function")
    elif len(components) == 2:
        mod_name = components[0]
        func_name = components[1]
        try:
            mod = import_module(mod_name)
        except ModuleNotFoundError:
            raise ValueError(f"Module {mod_name} not found")
        func = get_member(mod, func_name)
        if func is None:
            raise ValueError(f"{func_name} is not a member of {mod_name}")
    else:
        mod_name = '.'.join(components[:-1])
        func_name = components[-1]

        try:
            mod = import_module(mod_name)
        except ModuleNotFoundError:
            mod_name = '.'.join(components[:-2])
            class_name = components[-2]

            try:
                mod = import_module(mod_name)
            except ModuleNotFoundError:
                raise ValueError(f"Module {mod_name} not found")

            klass = get_member(mod, class_name)
            if klass is None:
                raise ValueError(f"Class {class_name} is not a member of {mod_name}")

            func = get_member(klass, func_name)
            if func is None:
                raise ValueError(f"Function {func_name} is not a member of {mod_name}.{class_name}")

        if func is None:
            func = get_member(mod, func_name)
            if func is None:
                raise ValueError(f"Function {func_name} is not a member of {mod_name}")

    if inspect.ismodule(func):
        raise ValueError("Cannot call module directly")

    if inspect.isclass(func):
        raise ValueError("Cannot call class directly")

    try:
        sig = [x for x in inspect.signature(func).parameters]
    except TypeError:
        raise ValueError(f"{callable_str} ({str(type(func))[1:-1]}) is not a callable object")

    if len(sig) == 1:
        if sig[0] == 'message':
            return func
        else:
            raise ValueError("Task function must have one parameter, named 'message'")

    elif len(sig)==2 and sig[0]=='self' and sig[1]=='message':
        # We only check for the conventional 'self', but if you're using something else,
        # you deserve the pain you'll have trying to debug this.
        raise ValueError("Can't call instance method without an instance! (Try sisy.models.task_with_callable)")
    else:
        raise ValueError("Improper signature for task function (needs only 'message')")
def func_from_string(callable_str):
    """Return a live function from a full dotted path.  Must be either a plain function
    directly in a module, a class function, or a static function.  (No modules, classes,
    or instance methods, since those can't be called as tasks.)"""
    components = callable_str.split('.')

    func = None

    if len(components) < 2:
        raise ValueError("Need full dotted path to task function")
    elif len(components) == 2:
        mod_name = components[0]
        func_name = components[1]
        try:
            mod = import_module(mod_name)
        except ModuleNotFoundError:
            raise ValueError(f"Module {mod_name} not found")
        func = get_member(mod, func_name)
        if func is None:
            raise ValueError(f"{func_name} is not a member of {mod_name}")
    else:
        mod_name = '.'.join(components[:-1])
        func_name = components[-1]

        try:
            mod = import_module(mod_name)
        except ModuleNotFoundError:
            mod_name = '.'.join(components[:-2])
            class_name = components[-2]

            try:
                mod = import_module(mod_name)
            except ModuleNotFoundError:
                raise ValueError(f"Module {mod_name} not found")

            klass = get_member(mod, class_name)
            if klass is None:
                raise ValueError(f"Class {class_name} is not a member of {mod_name}")

            func = get_member(klass, func_name)
            if func is None:
                raise ValueError(f"Function {func_name} is not a member of {mod_name}.{class_name}")

        if func is None:
            func = get_member(mod, func_name)
            if func is None:
                raise ValueError(f"Function {func_name} is not a member of {mod_name}")

    if inspect.ismodule(func):
        raise ValueError("Cannot call module directly")

    if inspect.isclass(func):
        raise ValueError("Cannot call class directly")

    try:
        sig = [x for x in inspect.signature(func).parameters]
    except TypeError:
        raise ValueError(f"{callable_str} ({str(type(func))[1:-1]}) is not a callable object")

    if len(sig) == 1:
        if sig[0] == 'message':
            return func
        else:
            raise ValueError("Task function must have one parameter, named 'message'")

    elif len(sig)==2 and sig[0]=='self' and sig[1]=='message':
        # We only check for the conventional 'self', but if you're using something else,
        # you deserve the pain you'll have trying to debug this.
        raise ValueError("Can't call instance method without an instance! (Try sisy.models.task_with_callable)")
    else:
        raise ValueError("Improper signature for task function (needs only 'message')")
def func_from_string ( callable_str ) : components = callable_str . split ( '.' ) func = None if len ( components ) < 2 : raise ValueError ( "Need full dotted path to task function" ) elif len ( components ) == 2 : mod_name = components [ 0 ] func_name = components [ 1 ] try : mod = import_module ( mod_name ) except ModuleNotFoundError : raise ValueError ( f"Module {mod_name} not found" ) func = get_member ( mod , func_name ) if func is None : raise ValueError ( f"{func_name} is not a member of {mod_name}" ) else : mod_name = '.' . join ( components [ : - 1 ] ) func_name = components [ - 1 ] try : mod = import_module ( mod_name ) except ModuleNotFoundError : mod_name = '.' . join ( components [ : - 2 ] ) class_name = components [ - 2 ] try : mod = import_module ( mod_name ) except ModuleNotFoundError : raise ValueError ( f"Module {mod_name} not found" ) klass = get_member ( mod , class_name ) if klass is None : raise ValueError ( f"Class {class_name} is not a member of {mod_name}" ) func = get_member ( klass , func_name ) if func is None : raise ValueError ( f"Function {func_name} is not a member of {mod_name}.{class_name}" ) if func is None : func = get_member ( mod , func_name ) if func is None : raise ValueError ( f"Function {func_name} is not a member of {mod_name}" ) if inspect . ismodule ( func ) : raise ValueError ( "Cannot call module directly" ) if inspect . isclass ( func ) : raise ValueError ( "Cannot call class directly" ) try : sig = [ x for x in inspect . signature ( func ) . parameters ] except TypeError : raise ValueError ( f"{callable_str} ({str(type(func))[1:-1]}) is not a callable object" ) if len ( sig ) == 1 : if sig [ 0 ] == 'message' : return func else : raise ValueError ( "Task function must have one parameter, named 'message'" ) elif len ( sig ) == 2 and sig [ 0 ] == 'self' and sig [ 1 ] == 'message' : # We only check for the conventional 'self', but if you're using something else, # you deserve the pain you'll have trying to debug this. raise ValueError ( "Can't call instance method without an instance! (Try sisy.models.task_with_callable)" ) else : raise ValueError ( "Improper signature for task function (needs only 'message')" )
Return a live function from a full dotted path.  Must be either a plain function
    directly in a module, a class function, or a static function.  (No modules, classes,
    or instance methods, since those can't be called as tasks.)
Return a live function from a full dotted path . Must be either a plain function directly in a module a class function or a static function . ( No modules classes or instance methods since those can t be called as tasks . )