# Path: pybabe/sort.py
# def sort(stream, field, reverse=False):
#     buf = []
#     for elt in stream:
#         if isinstance(elt, StreamHeader):
#             yield elt
#         elif isinstance(elt, StreamFooter):
#             buf.sort(key=lambda obj: getattr(obj, field), reverse=reverse)
#             for row in buf:
#                 yield row
#             yield elt
#         else:
#             buf.append(elt)


from base import StreamHeader, BabeBase, StreamFooter
from pybabe.sort import sort
        else:
            elt = self.f(self.buf)
        if isinstance(elt, t):
            return elt
        else:
            return t._make(elt)


def build_reducer(reducer):
    if hasattr(reducer, "begin_group"):
        return reducer
    else:
        return Reducer(reducer)


def group(stream, key, reducer,
		assume_sorted=False, typename=None, fields=None):
    """
GroupBy all values for a key.
If reducer is a function, function(t, key, row_group) is called with an array of all rows matching the key value
        t is the expected return type
        key is the common key for the group.
Otherwise can be a 'Reducer' object.
    reducer.begin_group(key) will be called at the beginning of each grou
    reducer.row(row) is called on each row
    reducer.end_group(t) will be called at the end of each group
    and should return the resulting row or a list of rows of type t
    """
    reducer = build_reducer(reducer)
    if not assume_sorted:

# Path: pybabe/sort.py
# def sort(stream, field, reverse=False):
#     buf = []
#     for elt in stream:
#         if isinstance(elt, StreamHeader):
#             yield elt
#         elif isinstance(elt, StreamFooter):
#             buf.sort(key=lambda obj: getattr(obj, field), reverse=reverse)
#             for row in buf:
#                 yield row
#             yield elt
#         else:
#             buf.append(elt)


# Path: pybabe/group.py
from base import StreamHeader, BabeBase, StreamFooter
from pybabe.sort import sort

        else:
            elt = self.f(self.buf)
        if isinstance(elt, t):
            return elt
        else:
            return t._make(elt)


def build_reducer(reducer):
    if hasattr(reducer, "begin_group"):
        return reducer
    else:
        return Reducer(reducer)


def group(stream, key, reducer,
		assume_sorted=False, typename=None, fields=None):
    """
GroupBy all values for a key.
If reducer is a function, function(t, key, row_group) is called with an array of all rows matching the key value
        t is the expected return type
        key is the common key for the group.
Otherwise can be a 'Reducer' object.
    reducer.begin_group(key) will be called at the beginning of each grou
    reducer.row(row) is called on each row
    reducer.end_group(t) will be called at the end of each group
    and should return the resulting row or a list of rows of type t
    """
    reducer = build_reducer(reducer)
    if not assume_sorted:

        stream = sort(stream, key)