# 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
            # We will never pass keyword arguments, so if the param must be a
            # keyword, and there's no default set, we can error early
            elif param.kind == param.KEYWORD_ONLY \
                    and param.default == param.empty:
                raise EventCallbackError(
                    "Callbacks must not take required keyword arguments"
                )
            # These are irrelevant - we'll never pass any but they are optional
            elif param.kind == param.VAR_KEYWORD:
                pass

        # If no event is registered, we will still register the callback but
        # we can't sanity check it since the event hasn't been registered yet
        if event_name not in self.registered_events:
            if num_func_args < 1 and not accepts_vargs:
                raise EventCallbackError(
                    "Callback must take at least one argument (cardinal)")

            return self._add_callback(event_name, callback)

        # Add one to needed args to account for CardinalBot being passed in
        num_needed_args = self.registered_events[event_name] + 1

        if (not accepts_vargs and num_func_args < num_needed_args):
            raise EventCallbackError(
                "Can't register callback with wrong number of arguments "
                "(event passes %d, %d accepted)" %
                (num_needed_args, num_func_args)
            )
        elif num_required_args > num_needed_args:

# 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

            # We will never pass keyword arguments, so if the param must be a
            # keyword, and there's no default set, we can error early
            elif param.kind == param.KEYWORD_ONLY \
                    and param.default == param.empty:
                raise EventCallbackError(
                    "Callbacks must not take required keyword arguments"
                )
            # These are irrelevant - we'll never pass any but they are optional
            elif param.kind == param.VAR_KEYWORD:
                pass

        # If no event is registered, we will still register the callback but
        # we can't sanity check it since the event hasn't been registered yet
        if event_name not in self.registered_events:
            if num_func_args < 1 and not accepts_vargs:
                raise EventCallbackError(
                    "Callback must take at least one argument (cardinal)")

            return self._add_callback(event_name, callback)

        # Add one to needed args to account for CardinalBot being passed in
        num_needed_args = self.registered_events[event_name] + 1

        if (not accepts_vargs and num_func_args < num_needed_args):
            raise EventCallbackError(
                "Can't register callback with wrong number of arguments "
                "(event passes %d, %d accepted)" %
                (num_needed_args, num_func_args)
            )
        elif num_required_args > num_needed_args:

            raise EventCallbackError(