From b58765d0157a51ebed784ef22b30fce21a3c9845 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 12 Oct 2018 16:39:53 +0200 Subject: [PATCH 1/4] DEPR: deprecate fastpath keyword in Index constructors --- pandas/core/indexes/base.py | 9 ++++++--- pandas/core/indexes/category.py | 10 +++++++--- pandas/core/indexes/numeric.py | 11 ++++++++--- pandas/core/indexes/period.py | 2 +- pandas/core/indexes/range.py | 32 ++++++++++++++++++-------------- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 51c84d6e28cb4..e9def653dca42 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -252,13 +252,16 @@ class Index(IndexOpsMixin, PandasObject): str = CachedAccessor("str", StringMethods) def __new__(cls, data=None, dtype=None, copy=False, name=None, - fastpath=False, tupleize_cols=True, **kwargs): + fastpath=None, tupleize_cols=True, **kwargs): if name is None and hasattr(data, 'name'): name = data.name - if fastpath: - return cls._simple_new(data, name) + if fastpath is not None: + warnings.warn("The 'fastpath' keyword is deprecated, and will be " + "removed in a future version.", FutureWarning) + if fastpath: + return cls._simple_new(data, name) from .range import RangeIndex diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 45703c220a4be..b01930b00d89b 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -1,4 +1,5 @@ import operator +import warnings import numpy as np from pandas._libs import index as libindex @@ -87,10 +88,13 @@ class CategoricalIndex(Index, accessor.PandasDelegate): _attributes = ['name'] def __new__(cls, data=None, categories=None, ordered=None, dtype=None, - copy=False, name=None, fastpath=False): + copy=False, name=None, fastpath=None): - if fastpath: - return cls._simple_new(data, name=name, dtype=dtype) + if fastpath is not None: + warnings.warn("The 'fastpath' keyword is deprecated, and will be " + "removed in a future version.", FutureWarning) + if fastpath: + return cls._simple_new(data, name=name, dtype=dtype) if name is None and hasattr(data, 'name'): name = data.name diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 7f64fb744c682..79d981bf8a2b6 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -1,3 +1,5 @@ +import warnings + import numpy as np from pandas._libs import (index as libindex, join as libjoin) @@ -35,10 +37,13 @@ class NumericIndex(Index): _is_numeric_dtype = True def __new__(cls, data=None, dtype=None, copy=False, name=None, - fastpath=False): + fastpath=None): - if fastpath: - return cls._simple_new(data, name=name) + if fastpath is not None: + warnings.warn("The 'fastpath' keyword is deprecated, and will be " + "removed in a future version.", FutureWarning) + if fastpath: + return cls._simple_new(data, name=name) # is_scalar, generators handled in coerce_to_ndarray data = cls._coerce_to_ndarray(data) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index f151389b02463..5afa23e2b11e2 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -306,7 +306,7 @@ def __contains__(self, key): @cache_readonly def _int64index(self): - return Int64Index(self.asi8, name=self.name, fastpath=True) + return Int64Index._simple_new(self.asi8, name=self.name) @property def values(self): diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index a0c3243ddbc3c..a0186e8df4556 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -1,6 +1,7 @@ import operator from datetime import timedelta from sys import getsizeof +import warnings import numpy as np @@ -68,10 +69,13 @@ class RangeIndex(Int64Index): _engine_type = libindex.Int64Engine def __new__(cls, start=None, stop=None, step=None, - dtype=None, copy=False, name=None, fastpath=False): + dtype=None, copy=False, name=None, fastpath=None): - if fastpath: - return cls._simple_new(start, stop, step, name=name) + if fastpath is not None: + warnings.warn("The 'fastpath' keyword is deprecated, and will be " + "removed in a future version.", FutureWarning) + if fastpath: + return cls._simple_new(start, stop, step, name=name) cls._validate_dtype(dtype) @@ -174,7 +178,7 @@ def _data(self): @cache_readonly def _int64index(self): - return Int64Index(self._data, name=self.name, fastpath=True) + return Int64Index._simple_new(self._data, name=self.name) def _get_data_as_items(self): """ return a list of tuples of start, stop, step """ @@ -262,8 +266,8 @@ def tolist(self): @Appender(_index_shared_docs['_shallow_copy']) def _shallow_copy(self, values=None, **kwargs): if values is None: - return RangeIndex(name=self.name, fastpath=True, - **dict(self._get_data_as_items())) + return RangeIndex._simple_new( + name=self.name, **dict(self._get_data_as_items())) else: kwargs.setdefault('name', self.name) return self._int64index._shallow_copy(values, **kwargs) @@ -273,8 +277,8 @@ def copy(self, name=None, deep=False, dtype=None, **kwargs): self._validate_dtype(dtype) if name is None: name = self.name - return RangeIndex(name=name, fastpath=True, - **dict(self._get_data_as_items())) + return RangeIndex._simple_new( + name=name, **dict(self._get_data_as_items())) def _minmax(self, meth): no_steps = len(self) - 1 @@ -374,7 +378,7 @@ def intersection(self, other): tmp_start = first._start + (second._start - first._start) * \ first._step // gcd * s new_step = first._step * second._step // gcd - new_index = RangeIndex(tmp_start, int_high, new_step, fastpath=True) + new_index = RangeIndex._simple_new(tmp_start, int_high, new_step) # adjust index to limiting interval new_index._start = new_index._min_fitting_element(int_low) @@ -552,7 +556,7 @@ def __getitem__(self, key): stop = self._start + self._step * stop step = self._step * step - return RangeIndex(start, stop, step, name=self.name, fastpath=True) + return RangeIndex._simple_new(start, stop, step, name=self.name) # fall back to Int64Index return super_getitem(key) @@ -565,12 +569,12 @@ def __floordiv__(self, other): start = self._start // other step = self._step // other stop = start + len(self) * step - return RangeIndex(start, stop, step, name=self.name, - fastpath=True) + return RangeIndex._simple_new( + start, stop, step, name=self.name) if len(self) == 1: start = self._start // other - return RangeIndex(start, start + 1, 1, name=self.name, - fastpath=True) + return RangeIndex._simple_new( + start, start + 1, 1, name=self.name) return self._int64index // other @classmethod From 293917a53f176ce5d0507ca42f4213beffb4b2e0 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 12 Oct 2018 16:54:36 +0200 Subject: [PATCH 2/4] add tests --- pandas/core/indexes/base.py | 3 ++- pandas/core/indexes/category.py | 3 ++- pandas/core/indexes/numeric.py | 3 ++- pandas/core/indexes/range.py | 3 ++- pandas/tests/indexes/test_base.py | 29 +++++++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index e9def653dca42..e5a379166e581 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -259,7 +259,8 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, if fastpath is not None: warnings.warn("The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", FutureWarning) + "removed in a future version.", + FutureWarning, stacklevel=2) if fastpath: return cls._simple_new(data, name) diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index b01930b00d89b..715b8eae12656 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -92,7 +92,8 @@ def __new__(cls, data=None, categories=None, ordered=None, dtype=None, if fastpath is not None: warnings.warn("The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", FutureWarning) + "removed in a future version.", + FutureWarning, stacklevel=2) if fastpath: return cls._simple_new(data, name=name, dtype=dtype) diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 79d981bf8a2b6..5d9e99b19bee0 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -41,7 +41,8 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, if fastpath is not None: warnings.warn("The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", FutureWarning) + "removed in a future version.", + FutureWarning, stacklevel=2) if fastpath: return cls._simple_new(data, name=name) diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index a0186e8df4556..eae1f03f22de0 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -73,7 +73,8 @@ def __new__(cls, start=None, stop=None, step=None, if fastpath is not None: warnings.warn("The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", FutureWarning) + "removed in a future version.", + FutureWarning, stacklevel=2) if fastpath: return cls._simple_new(start, stop, step, name=name) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index a753e925b0ed8..2eaa43e049f62 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -2530,3 +2530,32 @@ def test_index_subclass_constructor_wrong_kwargs(index_maker): # GH #19348 with tm.assert_raises_regex(TypeError, 'unexpected keyword argument'): index_maker(foo='bar') + + +def test_deprecated_fastpath(): + + with tm.assert_produces_warning(FutureWarning): + idx = pd.Index( + np.array(['a', 'b'], dtype=object), name='test', fastpath=True) + + expected = pd.Index(['a', 'b'], name='test') + tm.assert_index_equal(idx, expected) + + with tm.assert_produces_warning(FutureWarning): + idx = pd.Int64Index( + np.array([1, 2, 3], dtype='int64'), name='test', fastpath=True) + + expected = pd.Index([1, 2, 3], name='test', dtype='int64') + tm.assert_index_equal(idx, expected) + + with tm.assert_produces_warning(FutureWarning): + idx = pd.RangeIndex(0, 5, 2, name='test', fastpath=True) + + expected = pd.RangeIndex(0, 5, 2, name='test') + tm.assert_index_equal(idx, expected) + + with tm.assert_produces_warning(FutureWarning): + idx = pd.CategoricalIndex(['a', 'b', 'c'], name='test', fastpath=True) + + expected = pd.CategoricalIndex(['a', 'b', 'c'], name='test') + tm.assert_index_equal(idx, expected) From a27da847d67e04f7c566c3d9051190d169665894 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 12 Oct 2018 16:55:33 +0200 Subject: [PATCH 3/4] add whatsnew --- doc/source/whatsnew/v0.24.0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 9b70dd4ba549f..43994613eb78d 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -664,6 +664,7 @@ Deprecations many ``Series``, ``Index`` or 1-dimensional ``np.ndarray``, or alternatively, only scalar values. (:issue:`21950`) - :meth:`FrozenNDArray.searchsorted` has deprecated the ``v`` parameter in favor of ``value`` (:issue:`14645`) - :func:`DatetimeIndex.shift` and :func:`PeriodIndex.shift` now accept ``periods`` argument instead of ``n`` for consistency with :func:`Index.shift` and :func:`Series.shift`. Using ``n`` throws a deprecation warning (:issue:`22458`, :issue:`22912`) +- The ``fastpath`` keyword of the different Index constructors is deprecated. .. _whatsnew_0240.prior_deprecations: From 45758473d550279e22ab0acc877c7b4f7b13b2d6 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Sat, 13 Oct 2018 10:30:31 +0200 Subject: [PATCH 4/4] add PR number in whatsnew --- doc/source/whatsnew/v0.24.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 43994613eb78d..4da7ebb3eff36 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -664,7 +664,7 @@ Deprecations many ``Series``, ``Index`` or 1-dimensional ``np.ndarray``, or alternatively, only scalar values. (:issue:`21950`) - :meth:`FrozenNDArray.searchsorted` has deprecated the ``v`` parameter in favor of ``value`` (:issue:`14645`) - :func:`DatetimeIndex.shift` and :func:`PeriodIndex.shift` now accept ``periods`` argument instead of ``n`` for consistency with :func:`Index.shift` and :func:`Series.shift`. Using ``n`` throws a deprecation warning (:issue:`22458`, :issue:`22912`) -- The ``fastpath`` keyword of the different Index constructors is deprecated. +- The ``fastpath`` keyword of the different Index constructors is deprecated (:issue:`23110`). .. _whatsnew_0240.prior_deprecations: