# Buggy code
def __call__(self, expanding):
    inp = expanding.input
    raw_func = self.func
    self._normalize_funcs()

    if isinstance(inp, DATAFRAME_TYPE):
        pd_index = inp.index_value.to_pandas()

        empty_df = build_empty_df(inp.dtypes, index=pd_index[:1])
        for c, t in empty_df.dtypes.items():
            if t == np.dtype("O"):
                empty_df[c] = "O"

        test_df = expanding(empty_df).agg(raw_func)
        if self._axis == 0:
            index_value = inp.index_value
        else:
            index_value = parse_index(
                test_df.index, expanding.params, inp, store_data=False
            )
        self._append_index = test_df.columns.nlevels != empty_df.columns.nlevels
        return self.new_dataframe(
            [inp],
            shape=(inp.shape[0], test_df.shape[1]),
            dtypes=test_df.dtypes,
            index_value=index_value,
            columns_value=parse_index(test_df.columns, store_data=True),
        )
    else:
        pd_index = inp.index_value.to_pandas()
        empty_series = build_empty_series(inp.dtype, index=pd_index[:0], name=inp.name)
        test_obj = expanding(empty_series).agg(raw_func)
        if isinstance(test_obj, pd.DataFrame):
            return self.new_dataframe(
                [inp],
                shape=(inp.shape[0], test_obj.shape[1]),
                dtypes=test_obj.dtypes,
                index_value=inp.index_value,
                columns_value=parse_index(test_obj.dtypes.index, store_data=True),
            )
        else:
            return self.new_series(
                [inp],
                shape=inp.shape,
                dtype=test_obj.dtype,
                index_value=inp.index_value,
                name=test_obj.name,
            )


# Traceback (TypeError)
In [1]: import mars.dataframe as md

In [2]: df = md.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})

In [3]: df['b'] = df['b'].astype(md.ArrowStringDtype())

In [6]: df.groupby('b').count()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/miniconda3/lib/python3.7/site-packages/pandas/core/construction.py in _try_cast(arr, dtype, copy, raise_cast_failure)
545         elif not is_extension_array_dtype(subarr):
--> 546             subarr = construct_1d_ndarray_preserving_na(subarr, dtype, copy=copy)
547     except OutOfBoundsDatetime:

~/miniconda3/lib/python3.7/site-packages/pandas/core/dtypes/cast.py in construct_1d_ndarray_preserving_na(values, dtype, copy)
1506     """
-> 1507     subarr = np.array(values, dtype=dtype, copy=copy)
1508

TypeError: Cannot interpret '<mars.dataframe.arrays.ArrowStringDtype object at 0x7f7f81874150>' as a data type

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-6-884154032b17> in <module>
----> 1 df.groupby('b').count()

~/Workspace/mars/mars/dataframe/groupby/__init__.py in <lambda>(groupby, **kw)
40         setattr(cls, 'max', lambda groupby, **kw: agg(groupby, 'max', **kw))
41         setattr(cls, 'min', lambda groupby, **kw: agg(groupby, 'min', **kw))
---> 42         setattr(cls, 'count', lambda groupby, **kw: agg(groupby, 'count', **kw))
43         setattr(cls, 'size', lambda groupby, **kw: agg(groupby, 'size', **kw))
44         setattr(cls, 'mean', lambda groupby, **kw: agg(groupby, 'mean', **kw))

~/Workspace/mars/mars/dataframe/groupby/aggregation.py in agg(groupby, func, method, *args, **kwargs)
650     agg_op = DataFrameGroupByAgg(func=func, method=method, raw_func=func,
651                                  groupby_params=groupby.op.groupby_params)
--> 652     return agg_op(groupby)

~/Workspace/mars/mars/dataframe/groupby/aggregation.py in __call__(self, groupby)
201
202         if self.output_types[0] == OutputType.dataframe:
--> 203             return self._call_dataframe(groupby, df)
204         else:
205             return self._call_series(groupby, df)

~/Workspace/mars/mars/dataframe/groupby/aggregation.py in _call_dataframe(self, groupby, input_df)
144
145     def _call_dataframe(self, groupby, input_df):
--> 146         grouped = groupby.op.build_mock_groupby()
147         agg_df = grouped.aggregate(self.func)
148

~/Workspace/mars/mars/dataframe/groupby/core.py in build_mock_groupby(self, **kwargs)
98         in_df = self.inputs[0]
99         if self.is_dataframe_obj:
--> 100             empty_df = build_empty_df(in_df.dtypes, index=pd.RangeIndex(2))
101             obj_dtypes = in_df.dtypes[in_df.dtypes == np.dtype('O')]
102             empty_df[obj_dtypes.index] = 'O'

~/Workspace/mars/mars/dataframe/utils.py in build_empty_df(dtypes, index)
446     df = pd.DataFrame(columns=pd.RangeIndex(len(columns)), index=index)
447     for i, d in enumerate(dtypes):
--> 448         df[i] = pd.Series(dtype=d, index=index)
449     df.columns = columns
450     return df

~/miniconda3/lib/python3.7/site-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
254                 data = data._data
255             elif is_dict_like(data):
--> 256                 data, index = self._init_dict(data, index, dtype)
257                 dtype = None
258                 copy = False

~/miniconda3/lib/python3.7/site-packages/pandas/core/series.py in _init_dict(self, data, index, dtype)
347         # TODO: passing np.float64 to not break anything yet. See GH-17261
348         s = create_series_with_explicit_dtype(
--> 349             values, index=keys, dtype=dtype, dtype_if_empty=np.float64
350         )
351

~/miniconda3/lib/python3.7/site-packages/pandas/core/construction.py in create_series_with_explicit_dtype(data, index, dtype, name, copy, fastpath, dtype_if_empty)
623         dtype = dtype_if_empty
624     return Series(
--> 625         data=data, index=index, dtype=dtype, name=name, copy=copy, fastpath=fastpath
626     )

~/miniconda3/lib/python3.7/site-packages/pandas/core/series.py in __init__(self, data, index, dtype, name, copy, fastpath)
303                     data = data.copy()
304             else:
--> 305                 data = sanitize_array(data, index, dtype, copy, raise_cast_failure=True)
306
307                 data = SingleBlockManager(data, index, fastpath=True)

~/miniconda3/lib/python3.7/site-packages/pandas/core/construction.py in sanitize_array(data, index, dtype, copy, raise_cast_failure)
447         subarr = _try_cast(arr, dtype, copy, raise_cast_failure)
448     else:
--> 449         subarr = _try_cast(data, dtype, copy, raise_cast_failure)
450
451     # scalar like, GH

~/miniconda3/lib/python3.7/site-packages/pandas/core/construction.py in _try_cast(arr, dtype, copy, raise_cast_failure)
560             dtype = cast(ExtensionDtype, dtype)
561             array_type = dtype.construct_array_type()._from_sequence
--> 562             subarr = array_type(arr, dtype=dtype, copy=copy)
563         elif dtype is not None and raise_cast_failure:
564             raise

~/Workspace/mars/mars/dataframe/arrays.py in _from_sequence(cls, scalars, dtype, copy)
253     def _from_sequence(cls, scalars, dtype=None, copy=False):
254         if not hasattr(scalars, 'dtype'):
--> 255             ret = np.empty(len(scalars), dtype=object)
256             for i, s in enumerate(scalars):
257                 ret[i] = s

TypeError: object of type 'pyarrow.lib.NullScalar' has no len()

# Fixed code
def __call__(self, expanding):
    inp = expanding.input
    raw_func = self.func
    self._normalize_funcs()

    if isinstance(inp, DATAFRAME_TYPE):
        empty_df = build_df(inp)
        for c, t in empty_df.dtypes.items():
            if t == np.dtype("O"):
                empty_df[c] = "O"

        test_df = expanding(empty_df).agg(raw_func)
        if self._axis == 0:
            index_value = inp.index_value
        else:
            index_value = parse_index(
                test_df.index, expanding.params, inp, store_data=False
            )
        self._append_index = test_df.columns.nlevels != empty_df.columns.nlevels
        return self.new_dataframe(
            [inp],
            shape=(inp.shape[0], test_df.shape[1]),
            dtypes=test_df.dtypes,
            index_value=index_value,
            columns_value=parse_index(test_df.columns, store_data=True),
        )
    else:
        pd_index = inp.index_value.to_pandas()
        empty_series = build_empty_series(inp.dtype, index=pd_index[:0], name=inp.name)
        test_obj = expanding(empty_series).agg(raw_func)
        if isinstance(test_obj, pd.DataFrame):
            return self.new_dataframe(
                [inp],
                shape=(inp.shape[0], test_obj.shape[1]),
                dtypes=test_obj.dtypes,
                index_value=inp.index_value,
                columns_value=parse_index(test_obj.dtypes.index, store_data=True),
            )
        else:
            return self.new_series(
                [inp],
                shape=inp.shape,
                dtype=test_obj.dtype,
                index_value=inp.index_value,
                name=test_obj.name,
            )