# Buggy code
def tile(cls, op: "DataFrameDrop"):
    inp = op.inputs[0]
    out = op.outputs[0]
    if len(op.inputs) > 1:
        index_chunk = (
            op.index.rechunk({0: (op.index.shape[0],)})._inplace_tile().chunks[0]
        )
    else:
        index_chunk = op.index

    col_to_args = OrderedDict()
    chunks = []
    for c in inp.chunks:
        params = c.params.copy()
        if isinstance(inp, DATAFRAME_TYPE):
            new_dtypes, new_col_id = col_to_args.get(c.index[1], (None, None))

            if new_dtypes is None:
                new_col_id = len(col_to_args)
                new_dtypes = op._filter_dtypes(c.dtypes, ignore_errors=True)
                if len(new_dtypes) == 0:
                    continue
                col_to_args[c.index[1]] = (new_dtypes, new_col_id)

            params.update(
                dict(
                    dtypes=new_dtypes,
                    index=(c.index[0], new_col_id),
                    index_value=parse_index(None, (c.key, c.index_value.key)),
                )
            )
            if op.index is not None:
                params.update(
                    dict(
                        shape=(np.nan, len(new_dtypes)),
                        index_value=parse_index(None, (c.key, c.index_value.key)),
                    )
                )
            else:
                params["shape"] = (c.shape[0], len(new_dtypes))
        elif op.index is not None:
            params.update(
                dict(
                    shape=(np.nan,),
                    index_value=parse_index(None, (c.key, c.index_value.key)),
                )
            )

        chunk_inputs = [c]
        if isinstance(index_chunk, Chunk):
            chunk_inputs.append(index_chunk)

        new_op = op.copy().reset_key()
        new_op._index = index_chunk
        chunks.append(new_op.new_chunk(chunk_inputs, **params))

    new_op = op.copy().reset_key()
    params = out.params.copy()
    if op.index is not None:
        nsplits_list = [(np.nan,) * inp.chunk_shape[0]]
    else:
        nsplits_list = [inp.nsplits[0]]
    if isinstance(inp, DATAFRAME_TYPE):
        nsplits_list.append(tuple(len(dt) for dt, _ in col_to_args.values()))
    params.update(dict(chunks=chunks, nsplits=tuple(nsplits_list)))
    return new_op.new_tileables(op.inputs, **params)


# Traceback (TypeError)
Traceback (most recent call last):
File "/Users/qinxuye/Downloads/test_mars3.py", line 13, in <module>
print(c.execute())
File "/Users/qinxuye/Workspace/mars/mars/core.py", line 579, in execute
self._data.execute(session, **kw)
File "/Users/qinxuye/Workspace/mars/mars/core.py", line 367, in execute
session.run(self, **kw)
File "/Users/qinxuye/Workspace/mars/mars/session.py", line 461, in run
result = self._sess.run(*tileables, **kw)
File "/Users/qinxuye/Workspace/mars/mars/session.py", line 106, in run
res = self._executor.execute_tileables(tileables, **kw)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 408, in _wrapped
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 502, in inner
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/executor.py", line 860, in execute_tileables
tileables, tileable_graph=tileable_graph)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 408, in _wrapped
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 502, in inner
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 350, in build
tileables, tileable_graph=tileable_graph)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 408, in _wrapped
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 502, in inner
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 263, in build
self._on_tile_failure(tileable_data.op, exc_info)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 302, in inner
raise exc_info[1].with_traceback(exc_info[2]) from None
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 243, in build
tiled = self._tile(tileable_data, tileable_graph)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 338, in _tile
return super()._tile(tileable_data, tileable_graph)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 201, in _tile
tds[0]._inplace_tile()
File "/Users/qinxuye/Workspace/mars/mars/core.py", line 163, in _inplace_tile
return handler.inplace_tile(self)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 136, in inplace_tile
dispatched = self.dispatch(to_tile.op)
File "/Users/qinxuye/Workspace/mars/mars/utils.py", line 408, in _wrapped
return func(*args, **kwargs)
File "/Users/qinxuye/Workspace/mars/mars/tiles.py", line 119, in dispatch
tiled = op_cls.tile(op)
File "/Users/qinxuye/Workspace/mars/mars/dataframe/arithmetic/core.py", line 255, in tile
return cls._tile_both_series(op)
File "/Users/qinxuye/Workspace/mars/mars/dataframe/arithmetic/core.py", line 106, in _tile_both_series
nsplits, out_shape, left_chunks, right_chunks = align_series_series(left, right)
File "/Users/qinxuye/Workspace/mars/mars/dataframe/align.py", line 731, in align_series_series
left_index_chunks, right_index_chunks)
File "/Users/qinxuye/Workspace/mars/mars/dataframe/align.py", line 490, in _calc_axis_splits
right_splits = left_splits = [[c] for c in left_chunk_index_min_max]
TypeError: 'NoneType' object is not iterable

# Fixed code
def tile(cls, op: "DataFrameDrop"):
    inp = op.inputs[0]
    out = op.outputs[0]
    if len(op.inputs) > 1:
        index_chunk = (
            op.index.rechunk({0: (op.index.shape[0],)})._inplace_tile().chunks[0]
        )
    else:
        index_chunk = op.index

    col_to_args = OrderedDict()
    chunks = []
    for c in inp.chunks:
        params = c.params.copy()
        if isinstance(inp, DATAFRAME_TYPE):
            new_dtypes, new_col_id = col_to_args.get(c.index[1], (None, None))

            if new_dtypes is None:
                new_col_id = len(col_to_args)
                new_dtypes = op._filter_dtypes(c.dtypes, ignore_errors=True)
                if len(new_dtypes) == 0:
                    continue
                col_to_args[c.index[1]] = (new_dtypes, new_col_id)

            params.update(
                dict(
                    dtypes=new_dtypes,
                    index=(c.index[0], new_col_id),
                    index_value=c.index_value,
                )
            )
            if op.index is not None:
                params.update(
                    dict(
                        shape=(np.nan, len(new_dtypes)),
                        index_value=parse_index(None, (c.key, c.index_value.key)),
                    )
                )
            else:
                params["shape"] = (c.shape[0], len(new_dtypes))
        elif op.index is not None:
            params.update(
                dict(
                    shape=(np.nan,),
                    index_value=parse_index(None, (c.key, c.index_value.key)),
                )
            )

        chunk_inputs = [c]
        if isinstance(index_chunk, Chunk):
            chunk_inputs.append(index_chunk)

        new_op = op.copy().reset_key()
        new_op._index = index_chunk
        chunks.append(new_op.new_chunk(chunk_inputs, **params))

    new_op = op.copy().reset_key()
    params = out.params.copy()
    if op.index is not None:
        nsplits_list = [(np.nan,) * inp.chunk_shape[0]]
    else:
        nsplits_list = [inp.nsplits[0]]
    if isinstance(inp, DATAFRAME_TYPE):
        nsplits_list.append(tuple(len(dt) for dt, _ in col_to_args.values()))
    params.update(dict(chunks=chunks, nsplits=tuple(nsplits_list)))
    return new_op.new_tileables(op.inputs, **params)