Beispiel #1
0
def call_attr(name: str, *args: Any, **kwds: Any) -> Any:
    """Call an attribute of current module with given arguments.

    Args:
        name: Name of callable attribute
        *args: Arbitrary arguments, that are passed to the call
        *kwds: Arbitrary keyword arguments, that are passes to the call, if
            supported by the member attribute.

    Returns:
        Result of call.

    """
    return otree.call_attr(stack.get_caller_module(), name, *args, **kwds)
Beispiel #2
0
def get_submodule(name: str, parent: OptModule = None) -> OptModule:
    """Get instance from the name of a submodule of the current module.

    Args:
        name: Name of submodule of given module.
        parent: Optional reference to module, which has to be searched for
            submodules. By default the current callers module is used.

    Returns:
        Module reference of submodule or None, if the current module does not
        contain the given module name.

    """
    # Set default values
    parent = parent or stack.get_caller_module()

    # Get reference to submodule
    return get_module(parent.__name__ + '.' + name)
Beispiel #3
0
def get_attr(name: str, default: Any = None, module: OptModule = None) -> Any:
    """Get an attribute of current module.

    Args:
        name: Name of attribute.
        default: Default value, which is returned, if the attribute does not
            exist.
        module: Optional reference to module, which is used to search for the
            given attribute. By default the current callers module is used.

    Returns:
        Value of attribute.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Get attribute
    return getattr(module, name, default)
Beispiel #4
0
def has_attr(name: str, module: OptModule = None) -> bool:
    """Determine if a module has an attribute of given name.

    Args:
        name: Name of attribute
        module: Optional reference to module, which is used to search for the
            given attribute. By default the current callers module is used.

    Returns:
        Result of call.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Check Arguments
    check.has_type("'name'", name, str)
    check.has_type("'module'", module, Module)

    return hasattr(module, name)
Beispiel #5
0
def crop_functions(prefix: str, module: OptModule = None) -> list:
    """Get list of cropped function names that satisfy a given prefix.

    Args:
        prefix: String conatining the initial prefix of the returned functions
        module: Module reference. By default the current callers module is used.

    Returns:
        List of functions, that match a given prefix.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Get functions of current callers module
    pattern = prefix + '*'
    funcs = otree.get_members_dict(module, classinfo=Function, pattern=pattern)

    # Create list of cropped function names
    offset = len(prefix)
    return [each['name'][offset:] for each in funcs.values()]
Beispiel #6
0
def get_root(module: OptModule = None) -> Module:
    """Get top level module.

    Args:
        module: Optional reference to module. By default the current callers
            module is used.

    Returns:
        Module reference to the top level module of the current callers module.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Get name of the root module
    name = get_root_name(module.__name__)

    # Get reference to the root module
    root = get_module(name)
    if not isinstance(root, Module):
        raise ModuleNotFoundError(f"module '{name}' does not exist")
    return root
Beispiel #7
0
def get_parent(module: OptModule = None) -> Module:
    """Get parent module.

    Args:
        module: Optional reference to module. By default the current callers
            module is used.

    Returns:
        Module reference to the parent module of the current callers module.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Get name of the parent module
    name = module.__name__.rsplit('.', 1)[0]

    # Get reference to the parent module
    parent = get_module(name)
    if not isinstance(parent, Module):
        raise ModuleNotFoundError(f"module '{name}' does not exist")
    return parent
Beispiel #8
0
def search_old(module: Optional[Module] = None, **kwds: Any) -> dict:
    """Search for algorithms, that pass given filters.

    Args:
        module: Module instance, which is used to recursively search in
            submodules for algorithms. Default: Use the module of the caller
            of this function.
        **kwds: Attributes, which are testet by using the filter rules

    Returns:
        Dictionary with function information.

    """
    # Set default value of 'module' to module of caller
    module = module or stack.get_caller_module()

    # Create filter rules for attributes
    rules = {
        'tags': lambda a, b: set(a) <= set(b),  # requires all
        'classes': lambda a, b: bool(set(a) & set(b))
    }  # requires any

    # Search for algorithms
    return pkg.search(module=module, rules=rules, **kwds)
Beispiel #9
0
def get_submodules(parent: OptModule = None,
                   recursive: bool = False) -> StrList:
    """Get list with submodule names.

    Args:
        parent: Optional reference to module, which has to be searched for
            submodules. By default the current callers module is used.
        recursive: Boolean value which determines, if the search is performed
            recursively within all submodules. By default the returned list only
            comprises immediate submodules.

    Returns:
        List with fully qualified names of submodules.

    """
    # Set default values
    parent = parent or stack.get_caller_module()

    # Check if given module is a package by the existence of a path attribute.
    # Otherwise the module does not contain any submodules and an empty list is
    # returned.
    if not hasattr(parent, '__path__'):
        return []

    # Iterate submodules within package by using pkgutil
    children: StrList = []
    path = parent.__path__  # type: ignore
    for finder, basename, ispkg in pkgutil.iter_modules(path):
        name = '.'.join([parent.__name__, basename])
        children.append(name)
        if ispkg and recursive:
            child = get_module(name)
            if isinstance(child, Module):
                children += get_submodules(parent=child, recursive=True)

    return children
Beispiel #10
0
def search(module: OptModule = None,
           pattern: OptStr = None,
           classinfo: ClassInfo = Function,
           key: OptStr = None,
           val: OptStr = None,
           groupby: OptStr = None,
           recursive: bool = True,
           rules: OptDictOfKeyOps = None,
           errors: bool = False,
           **kwds: Any) -> dict:
    """Recursively search for objects within submodules.

    Args:
        module: Optional reference to module, which is used to search objects.
            By default the current callers module is used.
        pattern: Only objects which names satisfy the wildcard pattern given
            by 'pattern' are returned. The format of the wildcard pattern is
            described in the standard library module :py:mod:`fnmatch`. If
            pattern is None, then all objects are returned. Default: None
        classinfo: Classinfo given as a class, a type or a tuple containing
            classes, types or other tuples. Only members, which are ether an
            instance or a subclass of classinfo are returned. By default all
            types are allowed.
        key: Name of function attribute which is used as the key for the
            returned dictionary. If 'key' is None, then the fully qualified
            function names are used as keys. Default: None
        val: Name of function attribute which is used as the value for the
            returned dictionary. If 'val' is None, then all attributes of the
            respective objects are returned. Default: None
        groupby: Name of function attribute which is used to group the results.
            If 'groupby' is None, then the results are not grouped. Default:
            None
        recursive: Boolean value which determines if the search is performed
            recursively within all submodules. Default: True
        rules: Dictionary with individual filter rules, used by the attribute
            filter. The form is {<attribute>: <lambda>, ...}, where: <attribute>
            is a string with the attribute name and <lambda> is a boolean valued
            lambda function, which specifies the comparison of the attribute
            value against the argument value. Example: {'tags': lambda arg,
            attr: set(arg) <= set(attr)} By default any attribute, which is not
            in the filter rules is compared to the argument value by equality.
        errors: Boolean value which determines if an error is raised, if the
            module could not be found. By default errors are not raised.
        **kwds: Keyword arguments, that define the attribute filter for the
            returned dictionary. For example if the argument "tags = ['test']"
            is given, then only objects are returned, which have the attribute
            'tags' and the value of the attribute equals ['test']. If, however,
            the filter rule of the above example is given, then any function,
            with attribute 'tags' and a corresponding tag list, that comprises
            'test' is returned.

    Returns:
        Dictionary with function information as specified in the arguments
        'key' and 'val'.

    """
    # Set default values
    module = module or stack.get_caller_module()

    # Check argument types
    check.has_type("'module'", module, Module)
    check.has_opt_type("'pattern'", pattern, str)

    # Get list with module names, including the given and the submodules
    submodules = get_submodules(parent=module, recursive=recursive)
    mnames = [module.__name__] + submodules

    # Create dictionary with member attributes
    fd = {}
    rules = rules or {}
    for mname in mnames:
        minst = get_module(mname, errors=errors)
        if minst is None:
            continue
        d = otree.get_members_dict(minst,
                                   classinfo=classinfo,
                                   pattern=pattern,
                                   rules=rules,
                                   **kwds)

        # Ignore members if any required attribute is not available
        for name, attr in d.items():
            if key and not key in attr:
                continue
            if val and not val in attr:
                continue
            fd[name] = attr

    # Rename key for returned dictionary
    if key:
        d = {}
        for name, attr in fd.items():
            if key not in attr:
                continue
            kval = attr[key]
            if kval in d:
                continue
            d[kval] = attr
        fd = d

    # Group results
    if groupby:
        fd = mapping.groupby(fd, key=groupby)

    # Set value for returned dictionary
    if val:
        if groupby:
            for gn, group in fd.items():
                for name, attr in group.items():
                    fd[name] = attr[val]
        else:
            for name, attr in fd.items():
                fd[name] = attr[val]

    return fd
Beispiel #11
0
 def test_get_caller_module(self) -> None:
     module = stack.get_caller_module()
     self.assertIsInstance(module, Module)