Bug: Raise ValueError with interpolate & fillna limit = 0 (#9217)
State: closed

 - [x] closes #9217
 - [x] tests added / passed
 - [x] passes ``git diff upstream/master | flake8 --diff``
 - [x] whatsnew entry


Add similar logic to `fillna`

Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: Error Reporting
description: Incorrect or improved errors from pandas

Comments:
Good idea! Added check to `fillna` as well. Will ping again on green.
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14994?src=pr&el=h1) Report
> Merging [#14994](https://codecov.io/gh/pandas-dev/pandas/pull/14994?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/dda3c4292b28d4dbead8bb6ae9927373aea9fe23?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.


```diff
@@            Coverage Diff             @@
##           master   #14994      +/-   ##
==========================================
+ Coverage   90.42%   90.42%   +<.01%     
==========================================
  Files         134      134              
  Lines       49357    49365       +8     
==========================================
+ Hits        44632    44640       +8     
  Misses       4725     4725
```


| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/14994?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/compare/dda3c4292b28d4dbead8bb6ae9927373aea9fe23...c1790eeb3f5f65f1f40e489a7c2d075eb6cf1dc3?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `96.33% <ø> (ø)` | :white_check_mark: |
| [pandas/core/missing.py](https://codecov.io/gh/pandas-dev/pandas/compare/dda3c4292b28d4dbead8bb6ae9927373aea9fe23...c1790eeb3f5f65f1f40e489a7c2d075eb6cf1dc3?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvbWlzc2luZy5weQ==) | `84.95% <100%> (+0.19%)` | :white_check_mark: |
| [pandas/core/internals.py](https://codecov.io/gh/pandas-dev/pandas/compare/dda3c4292b28d4dbead8bb6ae9927373aea9fe23...c1790eeb3f5f65f1f40e489a7c2d075eb6cf1dc3?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW50ZXJuYWxzLnB5) | `94.15% <100%> (ø)` | :white_check_mark: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14994?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14994?src=pr&el=footer). Last update [dda3c42...c1790ee](https://codecov.io/gh/pandas-dev/pandas/compare/dda3c4292b28d4dbead8bb6ae9927373aea9fe23...c1790eeb3f5f65f1f40e489a7c2d075eb6cf1dc3?el=footer&src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
Ping all green
ok these need to be change here instead: https://github.com/pandas-dev/pandas/blob/master/pandas/src/algos_common_helper.pxi.in#L85 (there are 4 places where this is hit). This is more appropriate as we are already checking the limit and its closer to the actual code path.

I think you need some more tests for < 0 (which currently should raise), and == 0 (which I think you added)
Sorry for the delay in response.

I am not too familiar with the cython portion of the code base. Interestingly in master (0d3ecfa), if negative limits are used in `fillna` or `interpolate`, an error is not thrown. Is the cython code supposed to throw an error here?

```
In [2]: s = pd.Series([1,2,3,None])

In [3]: s.interpolate(limit=-1)
Out[3]: 
0    1.0
1    2.0
2    3.0
3    NaN
dtype: float64

In [4]: s.fillna(4, limit=-1)
Out[4]: 
0    1.0
1    2.0
2    3.0
3    NaN
dtype: float64
```

Added tests on my branch to test the negative limits.
it should but might be trapped somewhere
Ah, possibly lost in a `try`/`except`?
@mroeschke somewhere, you will have to trace it.
So I traced `.fillna(4, limit=-1)`:
<details>

```
--- modulename: series, funcname: fillna
series.py(2366):         return super(Series, self).fillna(value=value, method=method,
series.py(2367):                                           axis=axis, inplace=inplace,
series.py(2368):                                           limit=limit, downcast=downcast,
series.py(2369):                                           **kwargs)
--- modulename: generic, funcname: fillna
generic.py(3260):         if isinstance(value, (list, tuple)):
generic.py(3263):         self._consolidate_inplace()
--- modulename: generic, funcname: _consolidate_inplace
generic.py(2855):         def f():
generic.py(2858):         self._protect_consolidate(f)
--- modulename: generic, funcname: _protect_consolidate
generic.py(2846):         blocks_before = len(self._data.blocks)
generic.py(2847):         result = f()
--- modulename: generic, funcname: f
generic.py(2856):             self._data = self._data.consolidate()
--- modulename: internals, funcname: consolidate
internals.py(3522):         if self.is_consolidated():
--- modulename: internals, funcname: is_consolidated
internals.py(4199):         return True
internals.py(3523):             return self
--- modulename: generic, funcname: __setattr__
generic.py(2812):         try:
generic.py(2813):             object.__getattribute__(self, name)
generic.py(2814):             return object.__setattr__(self, name, value)
generic.py(2848):         if len(self._data.blocks) != blocks_before:
generic.py(2850):         return result
generic.py(3267):         if axis is None:
generic.py(3268):             axis = 0
generic.py(3269):         axis = self._get_axis_number(axis)
--- modulename: generic, funcname: _get_axis_number
generic.py(328):         axis = self._AXIS_ALIASES.get(axis, axis)
generic.py(329):         if is_integer(axis):
generic.py(330):             if axis in self._AXIS_NAMES:
generic.py(331):                 return axis
generic.py(3270):         method = missing.clean_fill_method(method)
--- modulename: missing, funcname: clean_fill_method
missing.py(68):     if method in [None, 'asfreq']:
missing.py(69):         return None
generic.py(3272):         from pandas import DataFrame
generic.py(3273):         if value is None:
generic.py(3309):             if method is not None:
generic.py(3312):             if len(self._get_axis(axis)) == 0:
--- modulename: generic, funcname: _get_axis
generic.py(354):         name = self._get_axis_name(axis)
--- modulename: generic, funcname: _get_axis_name
generic.py(341):         axis = self._AXIS_ALIASES.get(axis, axis)
generic.py(342):         if isinstance(axis, string_types):
generic.py(346):             try:
generic.py(347):                 return self._AXIS_NAMES[axis]
generic.py(355):         return getattr(self, name)
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
generic.py(3315):             if self.ndim == 1:
--- modulename: base, funcname: ndim
base.py(824):         return 1
generic.py(3316):                 if isinstance(value, (dict, ABCSeries)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
generic.py(3319):                 elif not is_list_like(value):
--- modulename: inference, funcname: is_list_like
inference.py(56):     return (hasattr(arg, '__iter__') and
generic.py(3320):                     pass
generic.py(3325):                 new_data = self._data.fillna(value=value, limit=limit,
generic.py(3326):                                              inplace=inplace,
generic.py(3327):                                              downcast=downcast)
--- modulename: internals, funcname: fillna
internals.py(3184):         return self.apply('fillna', **kwargs)
--- modulename: internals, funcname: apply
internals.py(3001):         result_blocks = []
internals.py(3004):         if filter is not None:
internals.py(3012):         if consolidate:
internals.py(3013):             self._consolidate_inplace()
--- modulename: internals, funcname: _consolidate_inplace
internals.py(4205):         pass
internals.py(3015):         if f == 'where':
internals.py(3021):         elif f == 'putmask':
internals.py(3027):         elif f == 'eval':
internals.py(3030):         elif f == 'fillna':
internals.py(3033):             align_copy = False
internals.py(3034):             align_keys = ['value']
internals.py(3038):         aligned_args = dict((k, kwargs[k])
internals.py(3039):                             for k in align_keys
--- modulename: internals, funcname: <genexpr>
internals.py(3038):         aligned_args = dict((k, kwargs[k])
internals.py(3039):                             for k in align_keys
internals.py(3040):                             if hasattr(kwargs[k], 'reindex_axis'))
internals.py(3038):         aligned_args = dict((k, kwargs[k])
internals.py(3042):         for b in self.blocks:
internals.py(3043):             if filter is not None:
internals.py(3048):             if aligned_args:
internals.py(3056):             kwargs['mgr'] = self
internals.py(3057):             applied = getattr(b, f)(**kwargs)
--- modulename: internals, funcname: fillna
internals.py(364):         if not self._can_hold_na:
internals.py(370):         original_value = value
internals.py(371):         mask = isnull(self.values)
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(51):     elif isinstance(obj, ABCMultiIndex):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(53):     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(54):         return _isnull_ndarraylike(obj)
--- modulename: missing, funcname: _isnull_ndarraylike
missing.py(121):     values = getattr(obj, 'values', obj)
missing.py(122):     dtype = values.dtype
missing.py(124):     if is_string_dtype(dtype):
--- modulename: common, funcname: is_string_dtype
common.py(105):     dtype = _get_dtype(arr_or_dtype)
--- modulename: common, funcname: _get_dtype
common.py(345):     if isinstance(arr_or_dtype, np.dtype):
common.py(346):         return arr_or_dtype
common.py(106):     return dtype.kind in ('O', 'S', 'U') and not is_period_dtype(dtype)
missing.py(142):     elif needs_i8_conversion(obj):
--- modulename: common, funcname: needs_i8_conversion
common.py(276):     return (is_datetime_or_timedelta_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime_or_timedelta_dtype
common.py(200):     tipo = _get_dtype_type(arr_or_dtype)
--- modulename: common, funcname: _get_dtype_type
common.py(369):     if isinstance(arr_or_dtype, np.dtype):
common.py(371):     elif isinstance(arr_or_dtype, type):
common.py(373):     elif isinstance(arr_or_dtype, CategoricalDtype):
common.py(375):     elif isinstance(arr_or_dtype, DatetimeTZDtype):
common.py(377):     elif isinstance(arr_or_dtype, PeriodDtype):
common.py(379):     elif isinstance(arr_or_dtype, string_types):
common.py(387):     try:
common.py(388):         return arr_or_dtype.dtype.type
common.py(201):     return issubclass(tipo, (np.datetime64, np.timedelta64))
common.py(277):             is_datetime64tz_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime64tz_dtype
common.py(88):     return DatetimeTZDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
common.py(278):             is_period_dtype(arr_or_dtype))
--- modulename: common, funcname: is_period_dtype
common.py(97):     return PeriodDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(354):         if isinstance(dtype, compat.string_types):
dtypes.py(367):         return super(PeriodDtype, cls).is_dtype(dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
missing.py(146):         result = np.isnan(values)
missing.py(149):     if isinstance(obj, ABCSeries):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(153):     return result
internals.py(372):         if limit is not None:
internals.py(373):             if self.ndim > 2:
internals.py(376):             mask[mask.cumsum(self.ndim - 1) > limit] = False
internals.py(379):         try:
internals.py(380):             values, _, value, _ = self._try_coerce_args(self.values, value)
--- modulename: internals, funcname: _try_coerce_args
internals.py(576):         return values, False, other, False
internals.py(381):             blocks = self.putmask(mask, value, inplace=inplace)
--- modulename: internals, funcname: putmask
internals.py(802):         new_values = self.values if inplace else self.values.copy()
internals.py(804):         if hasattr(new, 'reindex_axis'):
internals.py(807):         if hasattr(mask, 'reindex_axis'):
internals.py(811):         if not is_list_like(new) and isnull(new) and not self.is_object:
--- modulename: inference, funcname: is_list_like
inference.py(56):     return (hasattr(arg, '__iter__') and
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(49):         return lib.checknull(obj)
internals.py(814):         if self._can_hold_element(new):
--- modulename: internals, funcname: _can_hold_element
internals.py(1555):         if is_list_like(element):
--- modulename: inference, funcname: is_list_like
inference.py(56):     return (hasattr(arg, '__iter__') and
internals.py(1560):         return (isinstance(element, (float, int, np.float_, np.int_)) and
internals.py(1561):                 not isinstance(element, (bool, np.bool_, datetime, timedelta,
internals.py(1562):                                          np.datetime64, np.timedelta64)))
internals.py(815):             if transpose:
internals.py(818):             new = self._try_cast(new)
--- modulename: internals, funcname: _try_cast
internals.py(1565):         try:
internals.py(1566):             return float(element)
internals.py(822):             if getattr(new, 'ndim', 0) >= 1:
internals.py(828):             np.putmask(new_values, mask, new)
internals.py(882):         if inplace:
internals.py(885):         if transpose:
internals.py(888):         return [self.make_block(new_values, fastpath=True)]
--- modulename: internals, funcname: make_block
internals.py(195):         if placement is None:
internals.py(196):             placement = self.mgr_locs
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(197):         if ndim is None:
internals.py(198):             ndim = self.ndim
internals.py(200):         return make_block(values, placement=placement, ndim=ndim, **kwargs)
--- modulename: internals, funcname: make_block
internals.py(2652):     if klass is None:
internals.py(2653):         dtype = dtype or values.dtype
internals.py(2654):         vtype = dtype.type
internals.py(2656):         if isinstance(values, SparseArray):
internals.py(2658):         elif issubclass(vtype, np.floating):
internals.py(2659):             klass = FloatBlock
internals.py(2686):     return klass(values, ndim=ndim, fastpath=fastpath, placement=placement)
--- modulename: internals, funcname: __init__
internals.py(97):         if ndim is None:
internals.py(99):         elif values.ndim != ndim:
internals.py(101):         self.ndim = ndim
internals.py(103):         self.mgr_locs = placement
--- modulename: internals, funcname: mgr_locs
internals.py(218):         if not isinstance(new_mgr_locs, BlockPlacement):
internals.py(221):         self._mgr_locs = new_mgr_locs
internals.py(104):         self.values = values
internals.py(106):         if ndim and len(self.mgr_locs) != len(self.values):
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(382):             blocks = [b.make_block(values=self._try_coerce_result(b.values))
internals.py(383):                       for b in blocks]
--- modulename: internals, funcname: _try_coerce_result
internals.py(580):         return result
--- modulename: internals, funcname: make_block
internals.py(195):         if placement is None:
internals.py(196):             placement = self.mgr_locs
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(197):         if ndim is None:
internals.py(198):             ndim = self.ndim
internals.py(200):         return make_block(values, placement=placement, ndim=ndim, **kwargs)
--- modulename: internals, funcname: make_block
internals.py(2652):     if klass is None:
internals.py(2653):         dtype = dtype or values.dtype
internals.py(2654):         vtype = dtype.type
internals.py(2656):         if isinstance(values, SparseArray):
internals.py(2658):         elif issubclass(vtype, np.floating):
internals.py(2659):             klass = FloatBlock
internals.py(2686):     return klass(values, ndim=ndim, fastpath=fastpath, placement=placement)
--- modulename: internals, funcname: __init__
internals.py(97):         if ndim is None:
internals.py(99):         elif values.ndim != ndim:
internals.py(101):         self.ndim = ndim
internals.py(103):         self.mgr_locs = placement
--- modulename: internals, funcname: mgr_locs
internals.py(218):         if not isinstance(new_mgr_locs, BlockPlacement):
internals.py(221):         self._mgr_locs = new_mgr_locs
internals.py(104):         self.values = values
internals.py(106):         if ndim and len(self.mgr_locs) != len(self.values):
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(383):                       for b in blocks]
internals.py(384):             return self._maybe_downcast(blocks, downcast)
--- modulename: internals, funcname: _maybe_downcast
internals.py(402):         if downcast is None and self.is_float:
internals.py(403):             return blocks
internals.py(3058):             result_blocks = _extend_blocks(applied, result_blocks)
--- modulename: internals, funcname: _extend_blocks
internals.py(4553):     if blocks is None:
internals.py(4555):     if isinstance(result, list):
internals.py(4556):         for r in result:
internals.py(4557):             if isinstance(r, list):
internals.py(4560):                 blocks.append(r)
internals.py(4556):         for r in result:
internals.py(4565):     return blocks
internals.py(3042):         for b in self.blocks:
internals.py(3060):         if len(result_blocks) == 0:
internals.py(3062):         bm = self.__class__(result_blocks, axes or self.axes,
internals.py(3063):                             do_integrity_check=do_integrity_check)
--- modulename: internals, funcname: __init__
internals.py(4034):         if isinstance(axis, list):
internals.py(4035):             if len(axis) != 1:
internals.py(4038):             axis = axis[0]
internals.py(4041):         if fastpath:
internals.py(4053):             self.axes = [_ensure_index(axis)]
--- modulename: base, funcname: _ensure_index
base.py(3661):     if isinstance(index_like, Index):
base.py(3662):         if copy:
base.py(3664):         return index_like
internals.py(4056):             if isinstance(block, list):
internals.py(4059):                 if len(block) > 1:
internals.py(4064):                 if len(block) != 1:
internals.py(4067):                 block = block[0]
internals.py(4069):         if not isinstance(block, Block):
internals.py(4073):         self.blocks = [block]
internals.py(3064):         bm._consolidate_inplace()
--- modulename: internals, funcname: _consolidate_inplace
internals.py(4205):         pass
internals.py(3065):         return bm
generic.py(3351):         if inplace:
generic.py(3354):             return self._constructor(new_data).__finalize__(self)
--- modulename: series, funcname: _constructor
series.py(266):         return Series
--- modulename: series, funcname: __init__
series.py(140):         if fastpath:
series.py(152):             if index is not None:
series.py(155):             if data is None:
series.py(157):             if dtype is not None:
series.py(160):             if isinstance(data, MultiIndex):
series.py(163):             elif isinstance(data, Index):
series.py(170):             elif isinstance(data, np.ndarray):
series.py(172):             elif isinstance(data, Series):
series.py(180):             elif isinstance(data, dict):
series.py(207):             elif isinstance(data, SingleBlockManager):
series.py(208):                 if index is None:
series.py(209):                     index = data.index
--- modulename: internals, funcname: index
internals.py(4141):         return self.axes[0]
series.py(231):             if index is None:
series.py(237):             if isinstance(data, SingleBlockManager):
series.py(238):                 if dtype is not None:
series.py(240):                 elif copy:
series.py(248):         generic.NDFrame.__init__(self, data, fastpath=True)
--- modulename: generic, funcname: __init__
generic.py(117):         if not fastpath:
generic.py(127):         object.__setattr__(self, 'is_copy', None)
generic.py(128):         object.__setattr__(self, '_data', data)
generic.py(129):         object.__setattr__(self, '_item_cache', {})
series.py(250):         self.name = name
--- modulename: generic, funcname: __setattr__
generic.py(2812):         try:
generic.py(2813):             object.__getattribute__(self, name)
--- modulename: series, funcname: name
series.py(325):         return self._name
--- modulename: generic, funcname: __getattr__
generic.py(2795):         if (name in self._internal_names_set or name in self._metadata or
generic.py(2797):             return object.__getattribute__(self, name)
generic.py(2815):         except AttributeError:
generic.py(2816):             pass
generic.py(2820):         if name in self._internal_names_set:
generic.py(2822):         elif name in self._metadata:
generic.py(2823):             object.__setattr__(self, name, value)
--- modulename: series, funcname: name
series.py(329):         if value is not None and not is_hashable(value):
series.py(331):         object.__setattr__(self, '_name', value)
series.py(251):         self._set_axis(0, index, fastpath=True)
--- modulename: series, funcname: _set_axis
series.py(290):         if not fastpath:
series.py(293):         is_all_dates = labels.is_all_dates
--- modulename: numeric, funcname: is_all_dates
numeric.py(136):         return False
series.py(294):         if is_all_dates:
series.py(307):         self._set_subtyp(is_all_dates)
--- modulename: series, funcname: _set_subtyp
series.py(314):         if is_all_dates:
series.py(317):             object.__setattr__(self, '_subtyp', 'series')
series.py(309):         object.__setattr__(self, '_index', labels)
series.py(310):         if not fastpath:
--- modulename: generic, funcname: __finalize__
generic.py(2782):         if isinstance(other, NDFrame):
generic.py(2783):             for name in self._metadata:
generic.py(2784):                 object.__setattr__(self, name, getattr(other, name, None))
--- modulename: series, funcname: name
series.py(325):         return self._name
--- modulename: series, funcname: name
series.py(329):         if value is not None and not is_hashable(value):
series.py(331):         object.__setattr__(self, '_name', value)
generic.py(2783):             for name in self._metadata:
generic.py(2785):         return self
--- modulename: trace, funcname: _unsettrace
trace.py(80):         sys.settrace(None)
```

</details>

And `.interpolate(limit=-1)`:

<details>

```
--- modulename: generic, funcname: interpolate
generic.py(3708):         if self.ndim > 2:
--- modulename: base, funcname: ndim
base.py(824):         return 1
generic.py(3712):         if axis == 0:
generic.py(3713):             ax = self._info_axis_name
generic.py(3714):             _maybe_transposed_self = self
generic.py(3720):         ax = _maybe_transposed_self._get_axis_number(ax)
--- modulename: generic, funcname: _get_axis_number
generic.py(328):         axis = self._AXIS_ALIASES.get(axis, axis)
generic.py(329):         if is_integer(axis):
generic.py(333):             try:
generic.py(334):                 return self._AXIS_NUMBERS[axis]
generic.py(3722):         if _maybe_transposed_self.ndim == 2:
--- modulename: base, funcname: ndim
base.py(824):         return 1
generic.py(3725):             alt_ax = ax
generic.py(3727):         if (isinstance(_maybe_transposed_self.index, MultiIndex) and
generic.py(3732):         if _maybe_transposed_self._data.get_dtype_counts().get(
--- modulename: internals, funcname: get_dtype_counts
internals.py(4161):         return {self.dtype.name: 1}
--- modulename: internals, funcname: dtype
internals.py(4150):         return self._block.dtype
--- modulename: internals, funcname: _block
internals.py(4080):         return self.blocks[0]
--- modulename: internals, funcname: dtype
internals.py(299):         return self.values.dtype
generic.py(3733):                 'object') == len(_maybe_transposed_self.T):
--- modulename: base, funcname: transpose
base.py(808):         nv.validate_transpose(args, kwargs)
--- modulename: function, funcname: __call__
function.py(39):         fname = self.fname if fname is None else fname
function.py(41):                                max_fname_arg_count is None
function.py(43):         method = self.method if method is None else method
function.py(45):         if method == 'args':
function.py(47):         elif method == 'kwargs':
function.py(49):         elif method == 'both':
function.py(50):             validate_args_and_kwargs(fname, args, kwargs,
function.py(51):                                      max_fname_arg_count,
function.py(52):                                      self.defaults)
--- modulename: validators, funcname: validate_args_and_kwargs
validators.py(204):     _check_arg_length(fname, args + tuple(kwargs.values()),
validators.py(205):                       max_fname_arg_count, compat_args)
--- modulename: validators, funcname: _check_arg_length
validators.py(16):     if max_fname_arg_count < 0:
validators.py(19):     if len(args) > len(compat_args):
validators.py(209):     args_dict = dict(zip(compat_args, args))
validators.py(211):     for key in args_dict:
validators.py(216):     kwargs.update(args_dict)
validators.py(217):     validate_kwargs(fname, kwargs, compat_args)
--- modulename: validators, funcname: validate_kwargs
validators.py(154):     kwds = kwargs.copy()
validators.py(155):     _check_for_invalid_keys(fname, kwargs, compat_args)
--- modulename: validators, funcname: _check_for_invalid_keys
validators.py(120):     diff = set(kwargs) - set(compat_args)
validators.py(122):     if diff:
validators.py(156):     _check_for_default_values(fname, kwds, compat_args)
--- modulename: validators, funcname: _check_for_default_values
validators.py(40):     for key in arg_val_dict:
base.py(809):         return self
--- modulename: series, funcname: __len__
series.py(468):         return len(self._data)
--- modulename: internals, funcname: __len__
internals.py(2953):         return len(self.items)
--- modulename: internals, funcname: _get_items
internals.py(2864):         return self.axes[0]
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
generic.py(3737):         if method == 'linear':
generic.py(3739):             index = np.arange(len(_maybe_transposed_self._get_axis(alt_ax)))
--- modulename: generic, funcname: _get_axis
generic.py(354):         name = self._get_axis_name(axis)
--- modulename: generic, funcname: _get_axis_name
generic.py(341):         axis = self._AXIS_ALIASES.get(axis, axis)
generic.py(342):         if isinstance(axis, string_types):
generic.py(346):             try:
generic.py(347):                 return self._AXIS_NAMES[axis]
generic.py(355):         return getattr(self, name)
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
generic.py(3743):         if pd.isnull(index).any():
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(51):     elif isinstance(obj, ABCMultiIndex):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(53):     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(54):         return _isnull_ndarraylike(obj)
--- modulename: missing, funcname: _isnull_ndarraylike
missing.py(121):     values = getattr(obj, 'values', obj)
missing.py(122):     dtype = values.dtype
missing.py(124):     if is_string_dtype(dtype):
--- modulename: common, funcname: is_string_dtype
common.py(105):     dtype = _get_dtype(arr_or_dtype)
--- modulename: common, funcname: _get_dtype
common.py(345):     if isinstance(arr_or_dtype, np.dtype):
common.py(346):         return arr_or_dtype
common.py(106):     return dtype.kind in ('O', 'S', 'U') and not is_period_dtype(dtype)
missing.py(142):     elif needs_i8_conversion(obj):
--- modulename: common, funcname: needs_i8_conversion
common.py(276):     return (is_datetime_or_timedelta_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime_or_timedelta_dtype
common.py(200):     tipo = _get_dtype_type(arr_or_dtype)
--- modulename: common, funcname: _get_dtype_type
common.py(369):     if isinstance(arr_or_dtype, np.dtype):
common.py(371):     elif isinstance(arr_or_dtype, type):
common.py(373):     elif isinstance(arr_or_dtype, CategoricalDtype):
common.py(375):     elif isinstance(arr_or_dtype, DatetimeTZDtype):
common.py(377):     elif isinstance(arr_or_dtype, PeriodDtype):
common.py(379):     elif isinstance(arr_or_dtype, string_types):
common.py(387):     try:
common.py(388):         return arr_or_dtype.dtype.type
common.py(201):     return issubclass(tipo, (np.datetime64, np.timedelta64))
common.py(277):             is_datetime64tz_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime64tz_dtype
common.py(88):     return DatetimeTZDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
common.py(278):             is_period_dtype(arr_or_dtype))
--- modulename: common, funcname: is_period_dtype
common.py(97):     return PeriodDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(354):         if isinstance(dtype, compat.string_types):
dtypes.py(367):         return super(PeriodDtype, cls).is_dtype(dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
missing.py(146):         result = np.isnan(values)
missing.py(149):     if isinstance(obj, ABCSeries):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(153):     return result
--- modulename: _methods, funcname: _any
_methods.py(38):     return umr_any(a, axis, dtype, out, keepdims)
generic.py(3747):         data = _maybe_transposed_self._data
generic.py(3748):         new_data = data.interpolate(method=method, axis=ax, index=index,
generic.py(3749):                                     values=_maybe_transposed_self, limit=limit,
generic.py(3750):                                     limit_direction=limit_direction,
generic.py(3751):                                     inplace=inplace, downcast=downcast,
generic.py(3752):                                     **kwargs)
--- modulename: internals, funcname: interpolate
internals.py(3178):         return self.apply('interpolate', **kwargs)
--- modulename: internals, funcname: apply
internals.py(3001):         result_blocks = []
internals.py(3004):         if filter is not None:
internals.py(3012):         if consolidate:
internals.py(3013):             self._consolidate_inplace()
--- modulename: internals, funcname: _consolidate_inplace
internals.py(4205):         pass
internals.py(3015):         if f == 'where':
internals.py(3021):         elif f == 'putmask':
internals.py(3027):         elif f == 'eval':
internals.py(3030):         elif f == 'fillna':
internals.py(3036):             align_keys = []
internals.py(3038):         aligned_args = dict((k, kwargs[k])
internals.py(3039):                             for k in align_keys
--- modulename: internals, funcname: <genexpr>
internals.py(3038):         aligned_args = dict((k, kwargs[k])
internals.py(3042):         for b in self.blocks:
internals.py(3043):             if filter is not None:
internals.py(3048):             if aligned_args:
internals.py(3056):             kwargs['mgr'] = self
internals.py(3057):             applied = getattr(b, f)(**kwargs)
--- modulename: internals, funcname: interpolate
internals.py(894):         def check_int_bool(self, inplace):
internals.py(904):         try:
internals.py(905):             m = missing.clean_fill_method(method)
--- modulename: missing, funcname: clean_fill_method
missing.py(68):     if method in [None, 'asfreq']:
missing.py(71):     if isinstance(method, string_types):
missing.py(72):         method = method.lower()
missing.py(73):         if method == 'ffill':
missing.py(75):         elif method == 'bfill':
missing.py(78):     valid_methods = ['pad', 'backfill']
missing.py(79):     expecting = 'pad (ffill) or backfill (bfill)'
missing.py(80):     if allow_nearest:
missing.py(83):     if method not in valid_methods:
missing.py(84):         msg = ('Invalid fill method. Expecting %s. Got %s' %
missing.py(85):                (expecting, method))
missing.py(86):         raise ValueError(msg)
internals.py(906):         except:
internals.py(907):             m = None
internals.py(909):         if m is not None:
internals.py(919):         try:
internals.py(920):             m = missing.clean_interp_method(method, **kwargs)
--- modulename: missing, funcname: clean_interp_method
missing.py(91):     order = kwargs.get('order')
missing.py(92):     valid = ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear',
missing.py(93):              'quadratic', 'cubic', 'barycentric', 'polynomial', 'krogh',
missing.py(94):              'piecewise_polynomial', 'pchip', 'akima', 'spline',
missing.py(95):              'from_derivatives']
missing.py(96):     if method in ('spline', 'polynomial') and order is None:
missing.py(99):     if method not in valid:
missing.py(103):     return method
internals.py(924):         if m is not None:
internals.py(925):             r = check_int_bool(self, inplace)
--- modulename: internals, funcname: check_int_bool
internals.py(897):             if (self.is_bool or self.is_integer) and not self.is_timedelta:
internals.py(926):             if r is not None:
internals.py(928):             return self._interpolate(method=m, index=index, values=values,
internals.py(929):                                      axis=axis, limit=limit,
internals.py(930):                                      limit_direction=limit_direction,
internals.py(931):                                      fill_value=fill_value, inplace=inplace,
internals.py(932):                                      downcast=downcast, mgr=mgr, **kwargs)
--- modulename: internals, funcname: _interpolate
internals.py(967):         data = self.values if inplace else self.values.copy()
internals.py(970):         if not self.is_float:
internals.py(975):         if fill_value is None:
internals.py(976):             fill_value = self.fill_value
--- modulename: internals, funcname: fill_value
internals.py(177):         return np.nan
internals.py(978):         if method in ('krogh', 'piecewise_polynomial', 'pchip'):
internals.py(984):         def func(x):
internals.py(995):         interp_values = np.apply_along_axis(func, axis, data)
--- modulename: shape_base, funcname: apply_along_axis
shape_base.py(77):     arr = asarray(arr)
--- modulename: numeric, funcname: asarray
numeric.py(482):     return array(a, dtype, copy=False, order=order)
shape_base.py(78):     nd = arr.ndim
shape_base.py(79):     if axis < 0:
shape_base.py(81):     if (axis >= nd):
shape_base.py(84):     ind = [0]*(nd-1)
shape_base.py(85):     i = zeros(nd, 'O')
shape_base.py(86):     indlist = list(range(nd))
shape_base.py(87):     indlist.remove(axis)
shape_base.py(88):     i[axis] = slice(None, None)
shape_base.py(89):     outshape = asarray(arr.shape).take(indlist)
--- modulename: numeric, funcname: asarray
numeric.py(482):     return array(a, dtype, copy=False, order=order)
shape_base.py(90):     i.put(indlist, ind)
shape_base.py(91):     res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
--- modulename: internals, funcname: func
internals.py(989):             return missing.interpolate_1d(index, x, method=method, limit=limit,
internals.py(990):                                           limit_direction=limit_direction,
internals.py(991):                                           fill_value=fill_value,
internals.py(992):                                           bounds_error=False, **kwargs)
--- modulename: missing, funcname: interpolate_1d
missing.py(118):     invalid = isnull(yvalues)
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(51):     elif isinstance(obj, ABCMultiIndex):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(53):     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(54):         return _isnull_ndarraylike(obj)
--- modulename: missing, funcname: _isnull_ndarraylike
missing.py(121):     values = getattr(obj, 'values', obj)
missing.py(122):     dtype = values.dtype
missing.py(124):     if is_string_dtype(dtype):
--- modulename: common, funcname: is_string_dtype
common.py(105):     dtype = _get_dtype(arr_or_dtype)
--- modulename: common, funcname: _get_dtype
common.py(345):     if isinstance(arr_or_dtype, np.dtype):
common.py(346):         return arr_or_dtype
common.py(106):     return dtype.kind in ('O', 'S', 'U') and not is_period_dtype(dtype)
missing.py(142):     elif needs_i8_conversion(obj):
--- modulename: common, funcname: needs_i8_conversion
common.py(276):     return (is_datetime_or_timedelta_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime_or_timedelta_dtype
common.py(200):     tipo = _get_dtype_type(arr_or_dtype)
--- modulename: common, funcname: _get_dtype_type
common.py(369):     if isinstance(arr_or_dtype, np.dtype):
common.py(371):     elif isinstance(arr_or_dtype, type):
common.py(373):     elif isinstance(arr_or_dtype, CategoricalDtype):
common.py(375):     elif isinstance(arr_or_dtype, DatetimeTZDtype):
common.py(377):     elif isinstance(arr_or_dtype, PeriodDtype):
common.py(379):     elif isinstance(arr_or_dtype, string_types):
common.py(387):     try:
common.py(388):         return arr_or_dtype.dtype.type
common.py(201):     return issubclass(tipo, (np.datetime64, np.timedelta64))
common.py(277):             is_datetime64tz_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime64tz_dtype
common.py(88):     return DatetimeTZDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
common.py(278):             is_period_dtype(arr_or_dtype))
--- modulename: common, funcname: is_period_dtype
common.py(97):     return PeriodDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(354):         if isinstance(dtype, compat.string_types):
dtypes.py(367):         return super(PeriodDtype, cls).is_dtype(dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
missing.py(146):         result = np.isnan(values)
missing.py(149):     if isinstance(obj, ABCSeries):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(153):     return result
missing.py(119):     valid = ~invalid
missing.py(121):     if not valid.any():
--- modulename: _methods, funcname: _any
_methods.py(38):     return umr_any(a, axis, dtype, out, keepdims)
missing.py(128):     if valid.all():
--- modulename: _methods, funcname: _all
_methods.py(41):     return umr_all(a, axis, dtype, out, keepdims)
missing.py(131):     if method == 'time':
missing.py(139):     def _interp_limit(invalid, fw_limit, bw_limit):
missing.py(145):     valid_limit_directions = ['forward', 'backward', 'both']
missing.py(146):     limit_direction = limit_direction.lower()
missing.py(147):     if limit_direction not in valid_limit_directions:
missing.py(151):     from pandas import Series
missing.py(152):     ys = Series(yvalues)
--- modulename: series, funcname: __init__
series.py(140):         if fastpath:
series.py(152):             if index is not None:
series.py(155):             if data is None:
series.py(157):             if dtype is not None:
series.py(160):             if isinstance(data, MultiIndex):
series.py(163):             elif isinstance(data, Index):
series.py(170):             elif isinstance(data, np.ndarray):
series.py(171):                 pass
series.py(231):             if index is None:
series.py(232):                 if not is_list_like(data):
--- modulename: inference, funcname: is_list_like
inference.py(56):     return (hasattr(arg, '__iter__') and
inference.py(57):             not isinstance(arg, string_and_binary_types))
series.py(234):                 index = _default_index(len(data))
--- modulename: common, funcname: _default_index
common.py(228):     from pandas.core.index import RangeIndex
common.py(229):     return RangeIndex(0, n, name=None)
--- modulename: range, funcname: __new__
range.py(47):         if fastpath:
range.py(50):         cls._validate_dtype(dtype)
--- modulename: range, funcname: _validate_dtype
range.py(154):         if not (dtype is None or is_int64_dtype(dtype)):
range.py(53):         if isinstance(start, RangeIndex):
range.py(60):         def _ensure_int(value, field):
range.py(75):         if start is None and stop is None and step is None:
range.py(78):         elif start is None:
range.py(81):             start = _ensure_int(start, 'start')
--- modulename: range, funcname: _ensure_int
range.py(61):             msg = ("RangeIndex(...) must be called with integers,"
range.py(63):             if not is_scalar(value):
range.py(66):             try:
range.py(67):                 new_value = int(value)
range.py(68):                 assert(new_value == value)
range.py(73):             return new_value
range.py(82):         if stop is None:
range.py(86):             stop = _ensure_int(stop, 'stop')
--- modulename: range, funcname: _ensure_int
range.py(61):             msg = ("RangeIndex(...) must be called with integers,"
range.py(63):             if not is_scalar(value):
range.py(66):             try:
range.py(67):                 new_value = int(value)
range.py(68):                 assert(new_value == value)
range.py(73):             return new_value
range.py(87):         if step is None:
range.py(88):             step = 1
range.py(94):         return cls._simple_new(start, stop, step, name)
--- modulename: range, funcname: _simple_new
range.py(127):         result = object.__new__(cls)
range.py(130):         if start is None and stop is None:
range.py(134):         if start is None or not is_integer(start):
range.py(141):         result._start = start
range.py(142):         result._stop = stop or 0
range.py(143):         result._step = step or 1
range.py(144):         result.name = name
range.py(145):         for k, v in compat.iteritems(kwargs):
--- modulename: __init__, funcname: iteritems
__init__.py(165):         return obj.iteritems(**kw)
range.py(148):         result._reset_identity()
--- modulename: base, funcname: _reset_identity
base.py(487):         self._id = _Identity()
base.py(488):         return self
range.py(149):         return result
series.py(237):             if isinstance(data, SingleBlockManager):
series.py(243):                 data = _sanitize_array(data, index, dtype, copy,
series.py(244):                                        raise_cast_failure=True)
--- modulename: series, funcname: _sanitize_array
series.py(2835):     if dtype is not None:
series.py(2838):     if isinstance(data, ma.MaskedArray):
series.py(2846):     def _try_cast(arr, take_fast_path):
series.py(2867):     if isinstance(data, (np.ndarray, Index, Series)):
series.py(2869):         if dtype is not None:
series.py(2880):         elif isinstance(data, Index):
series.py(2887):             subarr = _try_cast(data, True)
--- modulename: series, funcname: _try_cast
series.py(2849):         if take_fast_path:
series.py(2850):             if _possibly_castable(arr) and not copy and dtype is None:
--- modulename: cast, funcname: _possibly_castable
cast.py(668):     kind = arr.dtype.kind
cast.py(669):     if kind == 'M' or kind == 'm':
cast.py(672):     return arr.dtype.name not in _POSSIBLY_CAST_DTYPES
series.py(2851):                 return arr
series.py(2889):         if copy:
series.py(2917):     def create_from_value(value, index, dtype):
series.py(2933):     if getattr(subarr, 'ndim', 0) == 0:
series.py(2952):     elif subarr.ndim == 1:
series.py(2953):         if index is not None:
series.py(2956):             if len(subarr) != len(index) and len(subarr) == 1:
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
series.py(2968):     if issubclass(subarr.dtype.type, compat.string_types):
series.py(2971):     return subarr
series.py(246):                 data = SingleBlockManager(data, index, fastpath=True)
--- modulename: internals, funcname: __init__
internals.py(4034):         if isinstance(axis, list):
internals.py(4041):         if fastpath:
internals.py(4042):             self.axes = [axis]
internals.py(4043):             if isinstance(block, list):
internals.py(4069):         if not isinstance(block, Block):
internals.py(4070):             block = make_block(block, placement=slice(0, len(axis)), ndim=1,
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
internals.py(4071):                                fastpath=True)
--- modulename: internals, funcname: make_block
internals.py(2652):     if klass is None:
internals.py(2653):         dtype = dtype or values.dtype
internals.py(2654):         vtype = dtype.type
internals.py(2656):         if isinstance(values, SparseArray):
internals.py(2658):         elif issubclass(vtype, np.floating):
internals.py(2659):             klass = FloatBlock
internals.py(2686):     return klass(values, ndim=ndim, fastpath=fastpath, placement=placement)
--- modulename: internals, funcname: __init__
internals.py(97):         if ndim is None:
internals.py(99):         elif values.ndim != ndim:
internals.py(101):         self.ndim = ndim
internals.py(103):         self.mgr_locs = placement
--- modulename: internals, funcname: mgr_locs
internals.py(218):         if not isinstance(new_mgr_locs, BlockPlacement):
internals.py(219):             new_mgr_locs = BlockPlacement(new_mgr_locs)
internals.py(221):         self._mgr_locs = new_mgr_locs
internals.py(104):         self.values = values
internals.py(106):         if ndim and len(self.mgr_locs) != len(self.values):
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(4073):         self.blocks = [block]
series.py(248):         generic.NDFrame.__init__(self, data, fastpath=True)
--- modulename: generic, funcname: __init__
generic.py(117):         if not fastpath:
generic.py(127):         object.__setattr__(self, 'is_copy', None)
generic.py(128):         object.__setattr__(self, '_data', data)
generic.py(129):         object.__setattr__(self, '_item_cache', {})
series.py(250):         self.name = name
--- modulename: generic, funcname: __setattr__
generic.py(2812):         try:
generic.py(2813):             object.__getattribute__(self, name)
--- modulename: series, funcname: name
series.py(325):         return self._name
--- modulename: generic, funcname: __getattr__
generic.py(2795):         if (name in self._internal_names_set or name in self._metadata or
generic.py(2797):             return object.__getattribute__(self, name)
generic.py(2815):         except AttributeError:
generic.py(2816):             pass
generic.py(2820):         if name in self._internal_names_set:
generic.py(2822):         elif name in self._metadata:
generic.py(2823):             object.__setattr__(self, name, value)
--- modulename: series, funcname: name
series.py(329):         if value is not None and not is_hashable(value):
series.py(331):         object.__setattr__(self, '_name', value)
series.py(251):         self._set_axis(0, index, fastpath=True)
--- modulename: series, funcname: _set_axis
series.py(290):         if not fastpath:
series.py(293):         is_all_dates = labels.is_all_dates
--- modulename: numeric, funcname: is_all_dates
numeric.py(136):         return False
series.py(294):         if is_all_dates:
series.py(307):         self._set_subtyp(is_all_dates)
--- modulename: series, funcname: _set_subtyp
series.py(314):         if is_all_dates:
series.py(317):             object.__setattr__(self, '_subtyp', 'series')
series.py(309):         object.__setattr__(self, '_index', labels)
series.py(310):         if not fastpath:
missing.py(153):     start_nans = set(range(ys.first_valid_index()))
--- modulename: series, funcname: first_valid_index
series.py(2676):         if len(self) == 0:
--- modulename: series, funcname: __len__
series.py(468):         return len(self._data)
--- modulename: internals, funcname: __len__
internals.py(2953):         return len(self.items)
--- modulename: internals, funcname: _get_items
internals.py(2864):         return self.axes[0]
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
series.py(2679):         mask = isnull(self._values)
--- modulename: series, funcname: _values
series.py(390):         return self._data.internal_values()
--- modulename: internals, funcname: internal_values
internals.py(4176):         return self._block.internal_values()
--- modulename: internals, funcname: _block
internals.py(4080):         return self.blocks[0]
--- modulename: internals, funcname: internal_values
internals.py(152):         return self.values
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(51):     elif isinstance(obj, ABCMultiIndex):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(53):     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(54):         return _isnull_ndarraylike(obj)
--- modulename: missing, funcname: _isnull_ndarraylike
missing.py(121):     values = getattr(obj, 'values', obj)
missing.py(122):     dtype = values.dtype
missing.py(124):     if is_string_dtype(dtype):
--- modulename: common, funcname: is_string_dtype
common.py(105):     dtype = _get_dtype(arr_or_dtype)
--- modulename: common, funcname: _get_dtype
common.py(345):     if isinstance(arr_or_dtype, np.dtype):
common.py(346):         return arr_or_dtype
common.py(106):     return dtype.kind in ('O', 'S', 'U') and not is_period_dtype(dtype)
missing.py(142):     elif needs_i8_conversion(obj):
--- modulename: common, funcname: needs_i8_conversion
common.py(276):     return (is_datetime_or_timedelta_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime_or_timedelta_dtype
common.py(200):     tipo = _get_dtype_type(arr_or_dtype)
--- modulename: common, funcname: _get_dtype_type
common.py(369):     if isinstance(arr_or_dtype, np.dtype):
common.py(371):     elif isinstance(arr_or_dtype, type):
common.py(373):     elif isinstance(arr_or_dtype, CategoricalDtype):
common.py(375):     elif isinstance(arr_or_dtype, DatetimeTZDtype):
common.py(377):     elif isinstance(arr_or_dtype, PeriodDtype):
common.py(379):     elif isinstance(arr_or_dtype, string_types):
common.py(387):     try:
common.py(388):         return arr_or_dtype.dtype.type
common.py(201):     return issubclass(tipo, (np.datetime64, np.timedelta64))
common.py(277):             is_datetime64tz_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime64tz_dtype
common.py(88):     return DatetimeTZDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
common.py(278):             is_period_dtype(arr_or_dtype))
--- modulename: common, funcname: is_period_dtype
common.py(97):     return PeriodDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(354):         if isinstance(dtype, compat.string_types):
dtypes.py(367):         return super(PeriodDtype, cls).is_dtype(dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
missing.py(146):         result = np.isnan(values)
missing.py(149):     if isinstance(obj, ABCSeries):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(153):     return result
series.py(2680):         i = mask.argmin()
series.py(2681):         if mask[i]:
series.py(2684):             return self.index[i]
--- modulename: range, funcname: __getitem__
range.py(472):         super_getitem = super(RangeIndex, self).__getitem__
range.py(474):         if is_scalar(key):
range.py(475):             n = int(key)
range.py(476):             if n != key:
range.py(478):             if n < 0:
range.py(480):             if n < 0 or n > len(self) - 1:
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
range.py(484):             return self._start + n * self._step
missing.py(154):     end_nans = set(range(1 + ys.last_valid_index(), len(valid)))
--- modulename: series, funcname: last_valid_index
series.py(2690):         if len(self) == 0:
--- modulename: series, funcname: __len__
series.py(468):         return len(self._data)
--- modulename: internals, funcname: __len__
internals.py(2953):         return len(self.items)
--- modulename: internals, funcname: _get_items
internals.py(2864):         return self.axes[0]
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
series.py(2693):         mask = isnull(self._values[::-1])
--- modulename: series, funcname: _values
series.py(390):         return self._data.internal_values()
--- modulename: internals, funcname: internal_values
internals.py(4176):         return self._block.internal_values()
--- modulename: internals, funcname: _block
internals.py(4080):         return self.blocks[0]
--- modulename: internals, funcname: internal_values
internals.py(152):         return self.values
--- modulename: missing, funcname: isnull
missing.py(44):     return _isnull(obj)
--- modulename: missing, funcname: _isnull_new
missing.py(48):     if is_scalar(obj):
missing.py(51):     elif isinstance(obj, ABCMultiIndex):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(53):     elif isinstance(obj, (ABCSeries, np.ndarray, ABCIndexClass)):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(54):         return _isnull_ndarraylike(obj)
--- modulename: missing, funcname: _isnull_ndarraylike
missing.py(121):     values = getattr(obj, 'values', obj)
missing.py(122):     dtype = values.dtype
missing.py(124):     if is_string_dtype(dtype):
--- modulename: common, funcname: is_string_dtype
common.py(105):     dtype = _get_dtype(arr_or_dtype)
--- modulename: common, funcname: _get_dtype
common.py(345):     if isinstance(arr_or_dtype, np.dtype):
common.py(346):         return arr_or_dtype
common.py(106):     return dtype.kind in ('O', 'S', 'U') and not is_period_dtype(dtype)
missing.py(142):     elif needs_i8_conversion(obj):
--- modulename: common, funcname: needs_i8_conversion
common.py(276):     return (is_datetime_or_timedelta_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime_or_timedelta_dtype
common.py(200):     tipo = _get_dtype_type(arr_or_dtype)
--- modulename: common, funcname: _get_dtype_type
common.py(369):     if isinstance(arr_or_dtype, np.dtype):
common.py(371):     elif isinstance(arr_or_dtype, type):
common.py(373):     elif isinstance(arr_or_dtype, CategoricalDtype):
common.py(375):     elif isinstance(arr_or_dtype, DatetimeTZDtype):
common.py(377):     elif isinstance(arr_or_dtype, PeriodDtype):
common.py(379):     elif isinstance(arr_or_dtype, string_types):
common.py(387):     try:
common.py(388):         return arr_or_dtype.dtype.type
common.py(201):     return issubclass(tipo, (np.datetime64, np.timedelta64))
common.py(277):             is_datetime64tz_dtype(arr_or_dtype) or
--- modulename: common, funcname: is_datetime64tz_dtype
common.py(88):     return DatetimeTZDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
common.py(278):             is_period_dtype(arr_or_dtype))
--- modulename: common, funcname: is_period_dtype
common.py(97):     return PeriodDtype.is_dtype(arr_or_dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(354):         if isinstance(dtype, compat.string_types):
dtypes.py(367):         return super(PeriodDtype, cls).is_dtype(dtype)
--- modulename: dtypes, funcname: is_dtype
dtypes.py(79):         if hasattr(dtype, 'dtype'):
dtypes.py(80):             dtype = dtype.dtype
dtypes.py(81):         if isinstance(dtype, cls):
dtypes.py(83):         elif isinstance(dtype, np.dtype):
dtypes.py(84):             return False
missing.py(146):         result = np.isnan(values)
missing.py(149):     if isinstance(obj, ABCSeries):
--- modulename: generic, funcname: _check
generic.py(9):         return getattr(inst, attr, '_typ') in comp
missing.py(153):     return result
series.py(2694):         i = mask.argmin()
series.py(2695):         if mask[i]:
series.py(2698):             return self.index[len(self) - i - 1]
--- modulename: series, funcname: __len__
series.py(468):         return len(self._data)
--- modulename: internals, funcname: __len__
internals.py(2953):         return len(self.items)
--- modulename: internals, funcname: _get_items
internals.py(2864):         return self.axes[0]
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
--- modulename: range, funcname: __getitem__
range.py(472):         super_getitem = super(RangeIndex, self).__getitem__
range.py(474):         if is_scalar(key):
range.py(475):             n = int(key)
range.py(476):             if n != key:
range.py(478):             if n < 0:
range.py(480):             if n < 0 or n > len(self) - 1:
--- modulename: range, funcname: __len__
range.py(462):         return max(0, -(-(self._stop - self._start) // self._step))
range.py(484):             return self._start + n * self._step
missing.py(170):     violate_limit = sorted(start_nans)
missing.py(172):     if limit:
missing.py(173):         if limit_direction == 'forward':
missing.py(174):             violate_limit = sorted(start_nans | set(_interp_limit(invalid,
missing.py(175):                                                                   limit, 0)))
--- modulename: missing, funcname: _interp_limit
missing.py(141):         for x in np.where(invalid)[0]:
missing.py(142):             if invalid[max(0, x - fw_limit):x + bw_limit + 1].all():
--- modulename: _methods, funcname: _all
_methods.py(41):     return umr_all(a, axis, dtype, out, keepdims)
missing.py(143):                 yield x
--- modulename: missing, funcname: _interp_limit
missing.py(141):         for x in np.where(invalid)[0]:
missing.py(176):         if limit_direction == 'backward':
missing.py(179):         if limit_direction == 'both':
missing.py(182):     xvalues = getattr(xvalues, 'values', xvalues)
missing.py(183):     yvalues = getattr(yvalues, 'values', yvalues)
missing.py(184):     result = yvalues.copy()
missing.py(186):     if method in ['linear', 'time', 'index', 'values']:
missing.py(187):         if method in ('values', 'index'):
missing.py(195):             inds = xvalues
missing.py(196):         result[invalid] = np.interp(inds[invalid], inds[valid], yvalues[valid])
--- modulename: function_base, funcname: interp
function_base.py(1668):     if period is None:
function_base.py(1669):         if isinstance(x, (float, int, number)):
function_base.py(1671):         elif isinstance(x, np.ndarray) and x.ndim == 0:
function_base.py(1674):             return compiled_interp(x, xp, fp, left, right)
missing.py(197):         result[violate_limit] = np.nan
missing.py(198):         return result
shape_base.py(93):     if isscalar(res):
--- modulename: numeric, funcname: isscalar
numeric.py(2088):     if isinstance(num, generic):
numeric.py(2091):         return type(num) in ScalarType
shape_base.py(112):         Ntot = product(outshape)
--- modulename: fromnumeric, funcname: product
fromnumeric.py(1860):     kwargs = {}
fromnumeric.py(1861):     if keepdims is not np._NoValue:
fromnumeric.py(1863):     return um.multiply.reduce(a, axis=axis, dtype=dtype, out=out, **kwargs)
shape_base.py(113):         holdshape = outshape
shape_base.py(114):         outshape = list(arr.shape)
shape_base.py(115):         outshape[axis] = len(res)
shape_base.py(116):         outarr = zeros(outshape, asarray(res).dtype)
--- modulename: numeric, funcname: asarray
numeric.py(482):     return array(a, dtype, copy=False, order=order)
shape_base.py(117):         outarr[tuple(i.tolist())] = res
shape_base.py(118):         k = 1
shape_base.py(119):         while k < Ntot:
shape_base.py(131):         return outarr
internals.py(997):         blocks = [self.make_block(interp_values, klass=self.__class__,
internals.py(998):                                   fastpath=True)]
--- modulename: internals, funcname: make_block
internals.py(195):         if placement is None:
internals.py(196):             placement = self.mgr_locs
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(197):         if ndim is None:
internals.py(198):             ndim = self.ndim
internals.py(200):         return make_block(values, placement=placement, ndim=ndim, **kwargs)
--- modulename: internals, funcname: make_block
internals.py(2652):     if klass is None:
internals.py(2682):     elif klass is DatetimeTZBlock and not is_datetimetz(values):
internals.py(2686):     return klass(values, ndim=ndim, fastpath=fastpath, placement=placement)
--- modulename: internals, funcname: __init__
internals.py(97):         if ndim is None:
internals.py(99):         elif values.ndim != ndim:
internals.py(101):         self.ndim = ndim
internals.py(103):         self.mgr_locs = placement
--- modulename: internals, funcname: mgr_locs
internals.py(218):         if not isinstance(new_mgr_locs, BlockPlacement):
internals.py(221):         self._mgr_locs = new_mgr_locs
internals.py(104):         self.values = values
internals.py(106):         if ndim and len(self.mgr_locs) != len(self.values):
--- modulename: internals, funcname: mgr_locs
internals.py(181):         return self._mgr_locs
internals.py(999):         return self._maybe_downcast(blocks, downcast)
--- modulename: internals, funcname: _maybe_downcast
internals.py(402):         if downcast is None and self.is_float:
internals.py(403):             return blocks
internals.py(3058):             result_blocks = _extend_blocks(applied, result_blocks)
--- modulename: internals, funcname: _extend_blocks
internals.py(4553):     if blocks is None:
internals.py(4555):     if isinstance(result, list):
internals.py(4556):         for r in result:
internals.py(4557):             if isinstance(r, list):
internals.py(4560):                 blocks.append(r)
internals.py(4556):         for r in result:
internals.py(4565):     return blocks
internals.py(3042):         for b in self.blocks:
internals.py(3060):         if len(result_blocks) == 0:
internals.py(3062):         bm = self.__class__(result_blocks, axes or self.axes,
internals.py(3063):                             do_integrity_check=do_integrity_check)
--- modulename: internals, funcname: __init__
internals.py(4034):         if isinstance(axis, list):
internals.py(4035):             if len(axis) != 1:
internals.py(4038):             axis = axis[0]
internals.py(4041):         if fastpath:
internals.py(4053):             self.axes = [_ensure_index(axis)]
--- modulename: base, funcname: _ensure_index
base.py(3661):     if isinstance(index_like, Index):
base.py(3662):         if copy:
base.py(3664):         return index_like
internals.py(4056):             if isinstance(block, list):
internals.py(4059):                 if len(block) > 1:
internals.py(4064):                 if len(block) != 1:
internals.py(4067):                 block = block[0]
internals.py(4069):         if not isinstance(block, Block):
internals.py(4073):         self.blocks = [block]
internals.py(3064):         bm._consolidate_inplace()
--- modulename: internals, funcname: _consolidate_inplace
internals.py(4205):         pass
internals.py(3065):         return bm
generic.py(3754):         if inplace:
generic.py(3759):             res = self._constructor(new_data).__finalize__(self)
--- modulename: series, funcname: _constructor
series.py(266):         return Series
--- modulename: series, funcname: __init__
series.py(140):         if fastpath:
series.py(152):             if index is not None:
series.py(155):             if data is None:
series.py(157):             if dtype is not None:
series.py(160):             if isinstance(data, MultiIndex):
series.py(163):             elif isinstance(data, Index):
series.py(170):             elif isinstance(data, np.ndarray):
series.py(172):             elif isinstance(data, Series):
series.py(180):             elif isinstance(data, dict):
series.py(207):             elif isinstance(data, SingleBlockManager):
series.py(208):                 if index is None:
series.py(209):                     index = data.index
--- modulename: internals, funcname: index
internals.py(4141):         return self.axes[0]
series.py(231):             if index is None:
series.py(237):             if isinstance(data, SingleBlockManager):
series.py(238):                 if dtype is not None:
series.py(240):                 elif copy:
series.py(248):         generic.NDFrame.__init__(self, data, fastpath=True)
--- modulename: generic, funcname: __init__
generic.py(117):         if not fastpath:
generic.py(127):         object.__setattr__(self, 'is_copy', None)
generic.py(128):         object.__setattr__(self, '_data', data)
generic.py(129):         object.__setattr__(self, '_item_cache', {})
series.py(250):         self.name = name
--- modulename: generic, funcname: __setattr__
generic.py(2812):         try:
generic.py(2813):             object.__getattribute__(self, name)
--- modulename: series, funcname: name
series.py(325):         return self._name
--- modulename: generic, funcname: __getattr__
generic.py(2795):         if (name in self._internal_names_set or name in self._metadata or
generic.py(2797):             return object.__getattribute__(self, name)
generic.py(2815):         except AttributeError:
generic.py(2816):             pass
generic.py(2820):         if name in self._internal_names_set:
generic.py(2822):         elif name in self._metadata:
generic.py(2823):             object.__setattr__(self, name, value)
--- modulename: series, funcname: name
series.py(329):         if value is not None and not is_hashable(value):
series.py(331):         object.__setattr__(self, '_name', value)
series.py(251):         self._set_axis(0, index, fastpath=True)
--- modulename: series, funcname: _set_axis
series.py(290):         if not fastpath:
series.py(293):         is_all_dates = labels.is_all_dates
--- modulename: numeric, funcname: is_all_dates
numeric.py(136):         return False
series.py(294):         if is_all_dates:
series.py(307):         self._set_subtyp(is_all_dates)
--- modulename: series, funcname: _set_subtyp
series.py(314):         if is_all_dates:
series.py(317):             object.__setattr__(self, '_subtyp', 'series')
series.py(309):         object.__setattr__(self, '_index', labels)
series.py(310):         if not fastpath:
--- modulename: generic, funcname: __finalize__
generic.py(2782):         if isinstance(other, NDFrame):
generic.py(2783):             for name in self._metadata:
generic.py(2784):                 object.__setattr__(self, name, getattr(other, name, None))
--- modulename: series, funcname: name
series.py(325):         return self._name
--- modulename: series, funcname: name
series.py(329):         if value is not None and not is_hashable(value):
series.py(331):         object.__setattr__(self, '_name', value)
generic.py(2783):             for name in self._metadata:
generic.py(2785):         return self
generic.py(3760):             if axis == 1:
generic.py(3762):             return res
--- modulename: trace, funcname: _unsettrace
trace.py(80):         sys.settrace(None)
```

</details>

For `interpolate()`, it looks like `limit` is utilized in the `_interp_limit` function: https://github.com/pandas-dev/pandas/blob/f3c5a427cc632e89cc5d2cb0df5b5e875cb6e23b/pandas/core/missing.py#L142

For `fillna()`, it looks like `limit` is utilized in `Block`'s `fillna` function: https://github.com/pandas-dev/pandas/blob/master/pandas/core/internals.py#L376

So if I've traced correctly, it doesn't appear that limit is passed through any `pad` function  where `limit < 0` should be caught.
can you rebase / update
Rebasing. 

As noted in my previous comment, it doesn't appear that `limit` gets passed through the `limit<0` check here: https://github.com/pandas-dev/pandas/blob/master/pandas/src/algos_common_helper.pxi.in#L85

For `interpolate`, `limit` passes through this line: https://github.com/pandas-dev/pandas/blob/f3c5a427cc632e89cc5d2cb0df5b5e875cb6e23b/pandas/core/missing.py#L142

For `fillna`, `limit` passes through this line: https://github.com/pandas-dev/pandas/blob/master/pandas/core/internals.py#L378

So I discovered negative limits are caught by cython if you specifically specify the fill method to be `pad`:

```
In [3]: s.interpolate(method='pad', limit=-1)

ValueError: Limit must be non-negative

In [4]: s.fillna(method='pad', limit=-1)

ValueError: Limit must be non-negative
```

I am guessing this is true if the user specifies the `pad` or `backfill` variants.

Otherwise, `fillna` with a value specified instead of a fill method doesn't go down the cython routine and negative limit won't be caught. Should `fillna` be adjusted to go through the cython routine if a value is specified instead of a fill method (maybe in a new issue)? This could be done similarly with `interpolate` but there plenty more interpolation methods... 


can you update?
Sure thing. I will also rebase to master as well.

Circling back to my last comment, I think the `assert limit > 0` is necessary in the beginning if `method` != pad or backfill since the other methods don't appear to go down the cython path where the `limit` check is made. 
@mroeschke ideally I'd like to have these validation on args occur when they are actually used. So might need to add these checks in ``pandas/core/missing.py`` when its not going down the cython route (and then enable the cython route). OR if its easier, remove checks in cython (well maybe leave them as assert statements and put in a comment of what the guarantees), and do the validation (still in pandas.core.missing). I don't want the validation in Series/DataFrame but in the actual implementation.
Ah I see, that makes sense. Okay I'll look into migrating the check to `pandas.core.missing`. Thanks!
Migrated the `limit > 0` check closer to where `limit` was actually used (`interpolate_1d` in `pandas/core/missing` and `fillna` in `pandas/core/internals`).
you need to edit the ``.in`` files, IOW ``algos_common.pxi.in`` (and not the .pxi as it says). These are not commited to the repo but generated from the ``.in`` ones.
Ah oops, apologies. I tried editing those error messages directly through github. I'll make those changes later tonight. 
Included `int` check for `limit` argument and added tests where floats should raise a `ValueError`
thanks @mroeschke