# Path: cardinal/exceptions.py
# class CommandNotFoundError(CardinalException):
#     """Raised when a given command isn't loaded."""
# 
# class ConfigNotFoundError(CardinalException):
#     """Raised when an expected plugin config isn't found."""
# 
# class EventAlreadyExistsError(CardinalException):
#     """Raised durring attempt to register an event name already registered."""
# 
# class EventCallbackError(CardinalException):
#     """Raised when there is an error with a callback."""
# 
# class EventDoesNotExistError(CardinalException):
#     """Raised during attempt to register a callback for a nonexistent event."""
# 
# class EventRejectedMessage(CardinalException):
#     """Raised when an event callback wants to reject an event."""
# 
# class PluginError(CardinalException):
#     """Raised when a plugin is invalid in some way."""


import os
import re
import string
import logging
import importlib
import inspect
import linecache
import random
import json
from collections import defaultdict
from copy import copy
from importlib import reload
from cardinal.exceptions import (
    CommandNotFoundError,
    ConfigNotFoundError,
    EventAlreadyExistsError,
    EventCallbackError,
    EventDoesNotExistError,
    EventRejectedMessage,
    PluginError,
)
from twisted.internet import defer
        it expects an instance of CardinalBot or not by checking whether it
        accepts an argument or not. If it does, we will pass in the instance of
        CardinalBot. This method is called just prior to removing the internal
        reference to the plugin's instance.

        Keyword arguments:
          plugin -- The name of the plugin to remove the instance of.

        Raises:
          PluginError -- When a plugin's close function has more than one
            argument.
        """

        instance = self.plugins[plugin]['instance']

        if hasattr(instance, 'close') and inspect.ismethod(instance.close):
            # The plugin has a close method, so we now need to check how
            # many arguments the method has. If it only has one, then the
            # argument must be 'self' and therefore they aren't expecting
            # us to pass in an instance of CardinalBot. If there are two
            # arguments, they expect CardinalBot. Anything else is invalid.
            argspec = inspect.getfullargspec(
                instance.close
            )

            if len(argspec.args) == 1:
                instance.close()
            elif len(argspec.args) == 2:
                instance.close(self.cardinal)
            else:

# Path: cardinal/exceptions.py
# class CommandNotFoundError(CardinalException):
#     """Raised when a given command isn't loaded."""
# 
# class ConfigNotFoundError(CardinalException):
#     """Raised when an expected plugin config isn't found."""
# 
# class EventAlreadyExistsError(CardinalException):
#     """Raised durring attempt to register an event name already registered."""
# 
# class EventCallbackError(CardinalException):
#     """Raised when there is an error with a callback."""
# 
# class EventDoesNotExistError(CardinalException):
#     """Raised during attempt to register a callback for a nonexistent event."""
# 
# class EventRejectedMessage(CardinalException):
#     """Raised when an event callback wants to reject an event."""
# 
# class PluginError(CardinalException):
#     """Raised when a plugin is invalid in some way."""


# Path: cardinal/plugins.py
import os
import re
import string
import logging
import importlib
import inspect
import linecache
import random
import json
from collections import defaultdict
from copy import copy
from importlib import reload
from cardinal.exceptions import (
    CommandNotFoundError,
    ConfigNotFoundError,
    EventAlreadyExistsError,
    EventCallbackError,
    EventDoesNotExistError,
    EventRejectedMessage,
    PluginError,
)
from twisted.internet import defer

        it expects an instance of CardinalBot or not by checking whether it
        accepts an argument or not. If it does, we will pass in the instance of
        CardinalBot. This method is called just prior to removing the internal
        reference to the plugin's instance.

        Keyword arguments:
          plugin -- The name of the plugin to remove the instance of.

        Raises:
          PluginError -- When a plugin's close function has more than one
            argument.
        """

        instance = self.plugins[plugin]['instance']

        if hasattr(instance, 'close') and inspect.ismethod(instance.close):
            # The plugin has a close method, so we now need to check how
            # many arguments the method has. If it only has one, then the
            # argument must be 'self' and therefore they aren't expecting
            # us to pass in an instance of CardinalBot. If there are two
            # arguments, they expect CardinalBot. Anything else is invalid.
            argspec = inspect.getfullargspec(
                instance.close
            )

            if len(argspec.args) == 1:
                instance.close()
            elif len(argspec.args) == 2:
                instance.close(self.cardinal)
            else:

                raise PluginError("Unknown arguments for close function")