# Path: dyndnsc/plugins/base.py
# class IPluginInterface(object):
#     """IPluginInterface describes the plugin API.
# 
#     Do not subclass or use this class directly.
#     """
# 
#     def __new__(cls, *arg, **kw):
#         """Private constructor."""
#         raise TypeError("IPluginInterface class cannot be instantiated, it "
#                         "is for documentation and API verification only")
# 
#     def options(self, parser, env):
#         """Register command line options with the argparse parser.
# 
#         DO NOT return a value from this method unless you want to stop
#         all other plugins from setting their options.
# 
#         :param parser: options parser instance
#         :type parser: `argparse.ArgumentParser`
#         :param env: environment, default is os.environ
#         """
#         pass
# 
#     def configure(self, options):
#         """Call after any user input has been parsed, with the options.
# 
#         DO NOT return a value from this method unless you want to
#         stop all other plugins from being configured.
#         """
#         pass
# 
#     def initialize(self):
#         """Call before any core activities are run.
# 
#         Use this to perform any plugin specific setup.
#         """
#         pass
# 
#     def after_remote_ip_update(self, ip, status):
#         """Call after a remote IP update was performed."""


import logging
            import textwrap
    import pkg_resources  # noqa: @UnusedImport pylint: disable=unused-import
from warnings import warn
from .base import IPluginInterface
        from pkg_resources import iter_entry_points
        from dyndnsc.plugins.builtin import PLUGINS
        return self.listcall(*arg, **kw)

    def add_plugin(self, plugin, call):
        """Add plugin to list of plugins.

        Will be added if it has the attribute I'm bound to.
        """
        meth = getattr(plugin, call, None)
        if meth is not None:
            self.plugins.append((plugin, meth))

    def listcall(self, *arg, **kw):
        """Call each plugin sequentially.

        Return the first result that is not None.
        """
        final_result = None
        for _, meth in self.plugins:
            result = meth(*arg, **kw)
            if final_result is None and result is not None:
                final_result = result
        return final_result


class NullPluginManager(object):
    """Plugin manager that has no plugins.

    Used as a NOP when no plugins are used
    """


# Path: dyndnsc/plugins/base.py
# class IPluginInterface(object):
#     """IPluginInterface describes the plugin API.
# 
#     Do not subclass or use this class directly.
#     """
# 
#     def __new__(cls, *arg, **kw):
#         """Private constructor."""
#         raise TypeError("IPluginInterface class cannot be instantiated, it "
#                         "is for documentation and API verification only")
# 
#     def options(self, parser, env):
#         """Register command line options with the argparse parser.
# 
#         DO NOT return a value from this method unless you want to stop
#         all other plugins from setting their options.
# 
#         :param parser: options parser instance
#         :type parser: `argparse.ArgumentParser`
#         :param env: environment, default is os.environ
#         """
#         pass
# 
#     def configure(self, options):
#         """Call after any user input has been parsed, with the options.
# 
#         DO NOT return a value from this method unless you want to
#         stop all other plugins from being configured.
#         """
#         pass
# 
#     def initialize(self):
#         """Call before any core activities are run.
# 
#         Use this to perform any plugin specific setup.
#         """
#         pass
# 
#     def after_remote_ip_update(self, ip, status):
#         """Call after a remote IP update was performed."""


# Path: dyndnsc/plugins/manager.py
import logging
            import textwrap
    import pkg_resources  # noqa: @UnusedImport pylint: disable=unused-import
from warnings import warn
from .base import IPluginInterface
        from pkg_resources import iter_entry_points
        from dyndnsc.plugins.builtin import PLUGINS

        return self.listcall(*arg, **kw)

    def add_plugin(self, plugin, call):
        """Add plugin to list of plugins.

        Will be added if it has the attribute I'm bound to.
        """
        meth = getattr(plugin, call, None)
        if meth is not None:
            self.plugins.append((plugin, meth))

    def listcall(self, *arg, **kw):
        """Call each plugin sequentially.

        Return the first result that is not None.
        """
        final_result = None
        for _, meth in self.plugins:
            result = meth(*arg, **kw)
            if final_result is None and result is not None:
                final_result = result
        return final_result


class NullPluginManager(object):
    """Plugin manager that has no plugins.

    Used as a NOP when no plugins are used
    """


    interface = IPluginInterface