import types


class ClassDirectory(object):
    def __init__(self, module):
        if type(module) == types.ModuleType:
            self.module = module
        else:
            raise TypeError("{} is not a module.".format(module))

    def find(self, parent=object, regex=None):
        """
        Searches self.module for instances that are subclasses of the provided
        parent object.

        :param parent: The parent object.
        :type  parent: ``type``

        :param regex: Compiled regex object that will match object names.
        :type  regex: compiled regex object

        :return matched_objects: List of matching objects.
        :rtype  matched_objects: ``list``
        """
        matched_objects = []

        for i in dir(self.module):
            obj = getattr(self.module, i)
            filter_values = []
            filter_values.extend([isinstance(obj, type) and issubclass(obj, parent)])

            if regex:
                match = regex.search(i)
                filter_values.append(match)

            if all(filter_values):
                matched_objects.append(obj)

        return matched_objects

from collections import namedtuple
import types


class ClassDirectory(object):
    def __init__(self, module):
        if isinstance(module, types.ModuleType):
            self.module = module
        else:
            raise TypeError("{} is not a module.".format(module))

        self.filters = ['inheritance', 'regex']

    def find(self, parent=object, regex=None):
        """
        Searches self.module for instances that are subclasses of the provided
        parent object.

        :param parent: The parent object.
        :type  parent: ``type``

        :param regex: Compiled regex object that will match object names.
        :type  regex: compiled regex object

        :return matched_objects: List of matching objects.
        :rtype  matched_objects: ``list``
        """
        self.parent = parent

        regex.search('')  # test if regex object implements search
        self.regex = regex

        Suspect = namedtuple('Suspect', ['name', 'object'])
        suspects = (
            Suspect(name=i, object=getattr(self.module, i))
            for i in dir(self.module)
        )

        matched_objects = [i.object for i in self._filter(suspects)]

        return matched_objects

    def _filter(self, suspects):
        for f in self.filters:
            filter_method = getattr(self, "_{}_filter".format(f))
            suspects = filter(filter_method, suspects)
        return suspects

    def _inheritance_filter(self, s):
        return isinstance(s.object, type) and issubclass(s.object, self.parent)

    def _regex_filter(self, suspect):
        return self.regex.search(suspect.name) is not None

break out filters