Ejemplo n.º 1
0
def doc_one(package_name,
            plugin_name,
            part=None,
            prefix=None,
            long_doc=True,
            include_details=False):
    """Document one plug-in

    If the plug-in is not part of the package an UnknownPluginError is raised.

    If there are several functions registered in a plug-in and `part` is not specified, then the first function
    registered in the plug-in will be documented.

    Args:
        package_name (String):     Name of package containing plug-ins.
        plugin_name (String):      Name of the plug-in, i.e. the module containing the plug-in.
        part (String):             Name of function to call within the plug-in (optional).
        prefix (String):           Prefix of the plug-in name, used if the plug-in name is unknown (optional).
        long_doc (Boolean):        Whether to return the long doc-string or the short one-line string (optional).
        include_details (Boolean): Whether to include development details like parameters and return values (optional).

    Returns:
        String: Documentation of the plug-in.
    """
    # Get Plugin-object and pick out doc-string
    plugin_name = load_one(package_name, plugin_name, prefix=prefix)
    part = "__default__" if part is None else part
    try:
        plugin = _PLUGINS[package_name][plugin_name][part]
    except KeyError:
        raise exceptions.UnknownPluginError(
            "Plugin '{}' not found for '{}' in '{}'"
            "".format(part, plugin_name, package_name)) from None
    doc = plugin.function.__doc__ if plugin.function.__doc__ else ""

    if long_doc:
        # Strip short description and indentation
        lines = [
            d.strip() for d in "\n\n".join(doc.split("\n\n")[1:]).split("\n")
        ]

        # Stop before Args:, Returns: etc if details should not be included
        idx_args = len(lines)
        if not include_details:
            re_args = re.compile(
                "(Args:|Returns:|Details:|Examples?:|Attributes:)$")
            try:
                idx_args = [re_args.match(l) is not None
                            for l in lines].index(True)
            except ValueError:
                pass
        return "\n".join(lines[:idx_args]).strip()

    else:
        # Return short description
        return doc.split("\n\n")[0].replace("\n", " ").strip()
Ejemplo n.º 2
0
def _import_one(package_name, plugin_name):
    """Import a plugin from a package

    This is essentially just a regular python import. As the module is imported, the _PLUGINS-dict will be populated by
    @register decorated functions in the file.

    Args:
        package_name (String):  Name of package containing plug-ins.
        plugin_name (String):   Name of the plug-in (module).
    """
    try:
        importlib.import_module(package_name + "." + plugin_name)
    except ImportError:
        raise exceptions.UnknownPluginError(
            "Plug-in '{}' not found in package '{}'"
            "".format(plugin_name, package_name)) from None
Ejemplo n.º 3
0
def _import_all(package_name):
    """Import the relevant .py-files in the given package directory

    As each file is imported, the _PLUGINS-dict will be populated by @register decorated functions in the files.

    Args:
        package_name (String):  Name of package containing plug-ins.
    """
    # Figure out the directory of the package by importing it
    try:
        package = importlib.import_module(package_name)
    except ImportError:
        raise exceptions.UnknownPluginError(
            "Plug-in package '{}' not found".format(package_name)) from None

    # Import all .py files in the given directory
    directory = pathlib.Path(package.__file__).parent
    for file_path in directory.glob("*.py"):
        plugin_name = file_path.stem
        if not plugin_name.startswith("_"):
            _import_one(package_name, plugin_name)
Ejemplo n.º 4
0
def call_one(package_name,
             plugin_name,
             part=None,
             prefix=None,
             logger=log.time,
             use_timer=True,
             do_report=True,
             **kwargs):
    """Call one plug-in

    If the plug-in is not part of the package an UnknownPluginError is raised.

    If there are several functions registered in a plug-in and `part` is not specified, then the first function
    registered in the plug-in will be called.

    The file containing the source code of the plug-in is added to the list of dependencies.

    Args:
        package_name (String):  Name of package containing plug-ins.
        plugin_name (String):   Name of the plug-in, i.e. the module containing the plug-in.
        part (String):          Name of function to call within the plug-in (optional).
        prefix (String):        Prefix of the plug-in name, used if the plug-in name is unknown (optional).
        logger (Function):      Logger from the lib.log package specifying the level of logging to be used (optional).
        use_timer (Boolean):    Whether to time and log the call to the plug-in (optional).
        do_report (Boolean):    Whether to add the call to the plug-in to the report (optional).
        kwargs:                 Named arguments passed on to the plug-in.

    Returns:
        Return value of the plug-in.
    """
    # Get Plugin-object
    plugin_name = load_one(package_name, plugin_name, prefix=prefix)
    part = "__default__" if part is None else part
    try:
        plugin = _PLUGINS[package_name][plugin_name][part]
    except KeyError:
        raise exceptions.UnknownPluginError(
            "Plugin '{}' not found for '{}' in '{}'"
            "".format(part, plugin_name, package_name)) from None

    # Add plug-in to report
    if do_report:
        from where.reports import report

        code_kwargs = kwargs.copy()
        if "dset" in code_kwargs:
            code_kwargs["dset"] = code_kwargs["dset"].repr
        report.add(
            package_name,
            __plugin__=plugin.name,
            __doc__=plugin.function.__doc__,
            __text__="TODO",
            __code__=
            "kwargs = {}\n{} = plugins.call_one('{}', '{}', part='{}', **kwargs)"
            "".format(code_kwargs, plugin_name, package_name, plugin_name,
                      part),
            **kwargs,
        )

    # Call plug-in
    dependencies.add(plugin.file_path, label="plugin")
    if logger:
        logger(f"Start {plugin.name} in {package_name}")
        time_logger = log.time if use_timer else None
    else:
        time_logger = None
    with timer(f"Finish {plugin.name} ({package_name}) in",
               logger=time_logger):
        return plugin.function(**kwargs)