# Buggy code
def __init__(
    self, index, grouper=None, obj=None, name=None, level=None, sort=True, in_axis=False
):
    self.name = name
    self.level = level
    self.grouper = _convert_grouper(index, grouper)
    self.index = index
    self.sort = sort
    self.obj = obj
    self.in_axis = in_axis

    # right place for this?
    if isinstance(grouper, (Series, Index)) and name is None:
        self.name = grouper.name

    if isinstance(grouper, MultiIndex):
        self.grouper = grouper.values

    # pre-computed
    self._should_compress = True

    # we have a single grouper which may be a myriad of things,
    # some of which are dependent on the passing in level

    if level is not None:
        if not isinstance(level, int):
            if level not in index.names:
                raise AssertionError("Level %s not in index" % str(level))
            level = index.names.index(level)

        if self.name is None:
            self.name = index.names[level]

        self.grouper, self._labels, self._group_index = index._get_grouper_for_level(
            self.grouper, level
        )

    else:
        if isinstance(self.grouper, (list, tuple)):
            self.grouper = com._asarray_tuplesafe(self.grouper)

        # a passed Categorical
        elif is_categorical_dtype(self.grouper):
            # must have an ordered categorical
            if self.sort:
                if not self.grouper.ordered:
                    # technically we cannot group on an unordered
                    # Categorical
                    # but this a user convenience to do so; the ordering
                    # is preserved and if it's a reduction it doesn't make
                    # any difference
                    pass

            # fix bug #GH8868 sort=False being ignored in categorical
            # groupby
            else:
                cat = self.grouper.unique()
                self.grouper = self.grouper.reorder_categories(cat.categories)

            # we make a CategoricalIndex out of the cat grouper
            # preserving the categories / ordered attributes
            self._labels = self.grouper.codes

            c = self.grouper.categories
            self._group_index = CategoricalIndex(
                Categorical.from_codes(
                    np.arange(len(c)), categories=c, ordered=self.grouper.ordered
                )
            )

        # a passed Grouper like
        elif isinstance(self.grouper, Grouper):
            # get the new grouper
            grouper = self.grouper._get_binner_for_grouping(self.obj)
            self.obj = self.grouper.obj
            self.grouper = grouper
            if self.name is None:
                self.name = grouper.name

        # we are done
        if isinstance(self.grouper, Grouping):
            self.grouper = self.grouper.grouper

        # no level passed
        elif not isinstance(self.grouper, (Series, Index, Categorical, np.ndarray)):
            if getattr(self.grouper, "ndim", 1) != 1:
                t = self.name or str(type(self.grouper))
                raise ValueError("Grouper for '%s' not 1-dimensional" % t)
            self.grouper = self.index.map(self.grouper)
            if not (
                hasattr(self.grouper, "__len__")
                and len(self.grouper) == len(self.index)
            ):
                errmsg = (
                    "Grouper result violates len(labels) == "
                    "len(data)\nresult: %s" % pprint_thing(self.grouper)
                )
                self.grouper = None  # Try for sanity
                raise AssertionError(errmsg)

    # if we have a date/time-like grouper, make sure that we have
    # Timestamps like
    if getattr(self.grouper, "dtype", None) is not None:
        if is_datetime64_dtype(self.grouper):
            from pandas import to_datetime

            self.grouper = to_datetime(self.grouper)
        elif is_timedelta64_dtype(self.grouper):
            from pandas import to_timedelta

            self.grouper = to_timedelta(self.grouper)


# Traceback (TypeError)
In [27]: df.groupby([pd.Grouper(key='A')]).count()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-f4f86763ebfc> in <module>()
----> 1 df.groupby([pd.Grouper(key='A')]).count()

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/generic.py in groupby(self, by, axis, level, as_index, sort, group_keys, squeeze, **kwargs)
3776         return groupby(self, by=by, axis=axis, level=level, as_index=as_index,
3777                        sort=sort, group_keys=group_keys, squeeze=squeeze,
-> 3778                        **kwargs)
3779
3780     def asfreq(self, freq, method=None, how=None, normalize=False):

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in groupby(obj, by, **kwds)
1425         raise TypeError('invalid type: %s' % type(obj))
1426
-> 1427     return klass(obj, by, **kwds)
1428
1429

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in __init__(self, obj, keys, axis, level, grouper, exclusions, selection, as_index, sort, group_keys, squeeze, **kwargs)
352                                                     level=level,
353                                                     sort=sort,
--> 354                                                     mutated=self.mutated)
355
356         self.obj = obj

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in _get_grouper(obj, key, axis, level, sort, mutated)
2400                         sort=sort,
2401                         in_axis=in_axis) \
-> 2402             if not isinstance(gpr, Grouping) else gpr
2403
2404         groupings.append(ping)

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in __init__(self, index, grouper, obj, name, level, sort, in_axis)
2197
2198                 # get the new grouper
-> 2199                 grouper = self.grouper._get_binner_for_grouping(self.obj)
2200                 self.obj = self.grouper.obj
2201                 self.grouper = grouper

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in _get_binner_for_grouping(self, obj)
290         group_axis = obj._get_axis(self.axis)
291         return Grouping(group_axis, None, obj=obj, name=self.key,
--> 292                         level=self.level, sort=self.sort, in_axis=False)
293
294     @property

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/core/groupby.py in __init__(self, index, grouper, obj, name, level, sort, in_axis)
2213                     t = self.name or str(type(self.grouper))
2214                     raise ValueError("Grouper for '%s' not 1-dimensional" % t)
-> 2215                 self.grouper = self.index.map(self.grouper)
2216                 if not (hasattr(self.grouper, "__len__") and
2217                         len(self.grouper) == len(self.index)):

/Users/measejm1/anaconda/lib/python3.5/site-packages/pandas/indexes/base.py in map(self, mapper)
2238         applied : array
2239         """
-> 2240         return self._arrmap(self.values, mapper)
2241
2242     def isin(self, values, level=None):

pandas/src/generated.pyx in pandas.algos.arrmap_int64 (pandas/algos.c:94003)()

TypeError: 'NoneType' object is not callable

# Fixed code
def __init__(
    self, index, grouper=None, obj=None, name=None, level=None, sort=True, in_axis=False
):
    self.name = name
    self.level = level
    self.grouper = _convert_grouper(index, grouper)
    self.index = index
    self.sort = sort
    self.obj = obj
    self.in_axis = in_axis

    # right place for this?
    if isinstance(grouper, (Series, Index)) and name is None:
        self.name = grouper.name

    if isinstance(grouper, MultiIndex):
        self.grouper = grouper.values

    # pre-computed
    self._should_compress = True

    # we have a single grouper which may be a myriad of things,
    # some of which are dependent on the passing in level

    if level is not None:
        if not isinstance(level, int):
            if level not in index.names:
                raise AssertionError("Level %s not in index" % str(level))
            level = index.names.index(level)

        if self.name is None:
            self.name = index.names[level]

        self.grouper, self._labels, self._group_index = index._get_grouper_for_level(
            self.grouper, level
        )

    else:
        if self.grouper is None and self.name is not None:
            self.grouper = self.obj[self.name]

        elif isinstance(self.grouper, (list, tuple)):
            self.grouper = com._asarray_tuplesafe(self.grouper)

        # a passed Categorical
        elif is_categorical_dtype(self.grouper):
            # must have an ordered categorical
            if self.sort:
                if not self.grouper.ordered:
                    # technically we cannot group on an unordered
                    # Categorical
                    # but this a user convenience to do so; the ordering
                    # is preserved and if it's a reduction it doesn't make
                    # any difference
                    pass

            # fix bug #GH8868 sort=False being ignored in categorical
            # groupby
            else:
                cat = self.grouper.unique()
                self.grouper = self.grouper.reorder_categories(cat.categories)

            # we make a CategoricalIndex out of the cat grouper
            # preserving the categories / ordered attributes
            self._labels = self.grouper.codes

            c = self.grouper.categories
            self._group_index = CategoricalIndex(
                Categorical.from_codes(
                    np.arange(len(c)), categories=c, ordered=self.grouper.ordered
                )
            )

        # a passed Grouper like
        elif isinstance(self.grouper, Grouper):
            # get the new grouper
            grouper = self.grouper._get_binner_for_grouping(self.obj)
            self.obj = self.grouper.obj
            self.grouper = grouper
            if self.name is None:
                self.name = grouper.name

        # we are done
        if isinstance(self.grouper, Grouping):
            self.grouper = self.grouper.grouper

        # no level passed
        elif not isinstance(self.grouper, (Series, Index, Categorical, np.ndarray)):
            if getattr(self.grouper, "ndim", 1) != 1:
                t = self.name or str(type(self.grouper))
                raise ValueError("Grouper for '%s' not 1-dimensional" % t)
            self.grouper = self.index.map(self.grouper)
            if not (
                hasattr(self.grouper, "__len__")
                and len(self.grouper) == len(self.index)
            ):
                errmsg = (
                    "Grouper result violates len(labels) == "
                    "len(data)\nresult: %s" % pprint_thing(self.grouper)
                )
                self.grouper = None  # Try for sanity
                raise AssertionError(errmsg)

    # if we have a date/time-like grouper, make sure that we have
    # Timestamps like
    if getattr(self.grouper, "dtype", None) is not None:
        if is_datetime64_dtype(self.grouper):
            from pandas import to_datetime

            self.grouper = to_datetime(self.grouper)
        elif is_timedelta64_dtype(self.grouper):
            from pandas import to_timedelta

            self.grouper = to_timedelta(self.grouper)