# Path: groupy/exceptions.py
# class GroupyError(Exception):
# class MissingMembershipError(GroupyError):
# class FindError(GroupyError):
# class NoMatchesError(FindError):
# class MultipleMatchesError(FindError):
# class ApiError(GroupyError):
# class NoResponse(ApiError):
# class BadResponse(ApiError):
# class InvalidJsonError(BadResponse):
# class MissingResponseError(BadResponse):
# class MissingMetaError(BadResponse):
# class ResultsError(ApiError):
# class ResultsNotReady(ResultsError):
# class ResultsExpired(ResultsError):
#     def __init__(self, message=None):
#     def __init__(self, group_id, user_id, message=None):
#     def __init__(self, message, objects, tests, matches=None):
#     def __init__(self, objects, tests):
#     def __init__(self, objects, tests, matches):
#     def __init__(self, request, *args, **kwargs):
#     def __init__(self, response, message=None):
#     def _extract_message(self, response):
#     def __init__(self, response, message='The JSON was incomplete/invalid'):
#     def __init__(self, response, message='The response contained no response data'):
#     def __init__(self, response, message='The response contained no meta data'):
#     def __init__(self, response, message):
#     def __init__(self, response, message='The results are not ready yet'):
#     def __init__(self, response, message='The results have expired'):


import urllib
import operator
from datetime import datetime, timezone, timedelta
from groupy import exceptions
        try:
            attr = getattr(obj, self.attr)
        except AttributeError:
            return False
        else:
            return self.op(attr, self.value)


class Filter:
    """A callable filter composed of one or more tests.

    :param tests: tests to perform
    """
    def __init__(self, tests):
        self.tests = tests

    def __call__(self, objects):
        yield from filter(self.passes, objects)

    def find(self, objects):
        """Find exactly one match in the list of objects.

        :param objects: objects to filter
        :type objects: :class:`list`
        :return: the one matching object
        :raises groupy.exceptions.NoMatchesError: if no objects match
        :raises groupy.exceptions.MultipleMatchesError: if multiple objects match
        """
        matches = list(self.__call__(objects))
        if not matches:

# Path: groupy/exceptions.py
# class GroupyError(Exception):
# class MissingMembershipError(GroupyError):
# class FindError(GroupyError):
# class NoMatchesError(FindError):
# class MultipleMatchesError(FindError):
# class ApiError(GroupyError):
# class NoResponse(ApiError):
# class BadResponse(ApiError):
# class InvalidJsonError(BadResponse):
# class MissingResponseError(BadResponse):
# class MissingMetaError(BadResponse):
# class ResultsError(ApiError):
# class ResultsNotReady(ResultsError):
# class ResultsExpired(ResultsError):
#     def __init__(self, message=None):
#     def __init__(self, group_id, user_id, message=None):
#     def __init__(self, message, objects, tests, matches=None):
#     def __init__(self, objects, tests):
#     def __init__(self, objects, tests, matches):
#     def __init__(self, request, *args, **kwargs):
#     def __init__(self, response, message=None):
#     def _extract_message(self, response):
#     def __init__(self, response, message='The JSON was incomplete/invalid'):
#     def __init__(self, response, message='The response contained no response data'):
#     def __init__(self, response, message='The response contained no meta data'):
#     def __init__(self, response, message):
#     def __init__(self, response, message='The results are not ready yet'):
#     def __init__(self, response, message='The results have expired'):


# Path: groupy/utils.py
import urllib
import operator
from datetime import datetime, timezone, timedelta
from groupy import exceptions

        try:
            attr = getattr(obj, self.attr)
        except AttributeError:
            return False
        else:
            return self.op(attr, self.value)


class Filter:
    """A callable filter composed of one or more tests.

    :param tests: tests to perform
    """
    def __init__(self, tests):
        self.tests = tests

    def __call__(self, objects):
        yield from filter(self.passes, objects)

    def find(self, objects):
        """Find exactly one match in the list of objects.

        :param objects: objects to filter
        :type objects: :class:`list`
        :return: the one matching object
        :raises groupy.exceptions.NoMatchesError: if no objects match
        :raises groupy.exceptions.MultipleMatchesError: if multiple objects match
        """
        matches = list(self.__call__(objects))
        if not matches:

            raise exceptions.NoMatchesError(objects, self.tests)