# Buggy code
def shift(self, periods, axis=0):
    """shift the block by periods, possibly upcast"""
    # convert integer to float if necessary. need to do a lot more than
    # that, handle boolean etc also
    new_values, fill_value = com._maybe_upcast(self.values)
    # make sure array sent to np.roll is c_contiguous
    f_ordered = new_values.flags.f_contiguous
    if f_ordered:
        new_values = new_values.T
        axis = new_values.ndim - axis - 1
    new_values = np.roll(new_values, periods, axis=axis)
    axis_indexer = [slice(None)] * self.ndim
    if periods > 0:
        axis_indexer[axis] = slice(None, periods)
    else:
        axis_indexer[axis] = slice(periods, None)
    new_values[tuple(axis_indexer)] = fill_value

    # restore original order
    if f_ordered:
        new_values = new_values.T

    return [
        make_block(new_values, ndim=self.ndim, fastpath=True, placement=self.mgr_locs)
    ]


# Traceback (ZeroDivisionError)
In [1]: from pandas import *

In [2]: df = DataFrame(columns=['foo'])

In [3]: df.shift(-1)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-3-6aa009807b04> in <module>()
----> 1 df.shift(-1)

/users/is/whughes/pyenvs/da497516f84bbd5b/lib/python2.7/site-packages/pandas/core/generic.pyc in shift(self, periods, freq, axis, **kwds)
3288         block_axis = self._get_block_manager_axis(axis)
3289         if freq is None and not len(kwds):
-> 3290             new_data = self._data.shift(periods=periods, axis=block_axis)
3291         else:
3292             return self.tshift(periods, freq, **kwds)

/users/is/whughes/pyenvs/da497516f84bbd5b/lib/python2.7/site-packages/pandas/core/internals.pyc in shift(self, **kwargs)
2226
2227     def shift(self, **kwargs):
-> 2228         return self.apply('shift', **kwargs)
2229
2230     def fillna(self, **kwargs):

/users/is/whughes/pyenvs/da497516f84bbd5b/lib/python2.7/site-packages/pandas/core/internals.pyc in apply(self, f, axes, filter, do_integrity_check, **kwargs)
2190                                                  copy=align_copy)
2191
-> 2192             applied = getattr(b, f)(**kwargs)
2193
2194             if isinstance(applied, list):

/users/is/whughes/pyenvs/da497516f84bbd5b/lib/python2.7/site-packages/pandas/core/internals.pyc in shift(self, periods, axis)
789             new_values = new_values.T
790             axis = new_values.ndim - axis - 1
--> 791         new_values = np.roll(new_values, periods, axis=axis)
792         axis_indexer = [ slice(None) ] * self.ndim
793         if periods > 0:

/users/is/whughes/pyenvs/da497516f84bbd5b/lib/python2.7/site-packages/numpy/core/numeric.pyc in roll(a, shift, axis)
1145         n = a.shape[axis]
1146         reshape = False
-> 1147     shift %= n
1148     indexes = concatenate((arange(n-shift,n),arange(n-shift)))
1149     res = a.take(indexes, axis)

ZeroDivisionError: integer division or modulo by zero

# Fixed code
def shift(self, periods, axis=0):
    """shift the block by periods, possibly upcast"""
    # convert integer to float if necessary. need to do a lot more than
    # that, handle boolean etc also
    new_values, fill_value = com._maybe_upcast(self.values)
    # make sure array sent to np.roll is c_contiguous
    f_ordered = new_values.flags.f_contiguous
    if f_ordered:
        new_values = new_values.T
        axis = new_values.ndim - axis - 1

    if np.prod(new_values.shape):
        new_values = np.roll(new_values, periods, axis=axis)

    axis_indexer = [slice(None)] * self.ndim
    if periods > 0:
        axis_indexer[axis] = slice(None, periods)
    else:
        axis_indexer[axis] = slice(periods, None)
    new_values[tuple(axis_indexer)] = fill_value

    # restore original order
    if f_ordered:
        new_values = new_values.T

    return [
        make_block(new_values, ndim=self.ndim, fastpath=True, placement=self.mgr_locs)
    ]