Skip to content

Commit

Permalink
DEPR: Deprecate pandas.core.datetools
Browse files Browse the repository at this point in the history
Closes gh-14094.
  • Loading branch information
gfyoung committed Sep 3, 2016
1 parent 2bebc18 commit 2bb887d
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 6 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ Deprecations

- ``PeriodIndex.to_datetime`` has been deprecated in favour of ``PeriodIndex.to_timestamp`` (:issue:`8254`)
- ``Timestamp.to_datetime`` has been deprecated in favour of ``Timestamp.to_pydatetime`` (:issue:`8254`)
- ``pandas.core.datetools`` module has been deprecated and will be removed in a subsequent release (:issue:`14094`)
- ``Index.to_datetime`` and ``DatetimeIndex.to_datetime`` have been deprecated in favour of ``pd.to_datetime`` (:issue:`8254`)
- ``SparseList`` has been deprecated and will be removed in a future version (:issue:`13784`)
- ``DataFrame.to_html()`` and ``DataFrame.to_latex()`` have dropped the ``colSpace`` parameter in favor of ``col_space`` (:issue:`13857`)
Expand Down
21 changes: 17 additions & 4 deletions pandas/api/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class TestPDApi(Base, tm.TestCase):
'json', 'lib', 'index', 'parser']

# these are already deprecated; awaiting removal
deprecated_modules = ['ols', 'stats']
deprecated_modules = ['ols', 'stats', 'datetools']

# misc
misc = ['IndexSlice', 'NaT']
Expand All @@ -61,14 +61,14 @@ class TestPDApi(Base, tm.TestCase):
'SparseTimeSeries', 'Panel4D',
'SparseList']

# these should be deperecated in the future
# these should be deprecated in the future
deprecated_classes_in_future = ['Term', 'Panel']

# these should be removed from top-level namespace
remove_classes_from_top_level_namespace = ['Expr']

# external modules exposed in pandas namespace
modules = ['np', 'datetime', 'datetools']
modules = ['np', 'datetime']

# top-level functions
funcs = ['bdate_range', 'concat', 'crosstab', 'cut',
Expand Down Expand Up @@ -99,7 +99,7 @@ class TestPDApi(Base, tm.TestCase):
funcs_to = ['to_datetime', 'to_msgpack',
'to_numeric', 'to_pickle', 'to_timedelta']

# these should be deperecated in the future
# these should be deprecated in the future
deprecated_funcs_in_future = ['pnow', 'groupby', 'info']

# these are already deprecated; awaiting removal
Expand Down Expand Up @@ -208,6 +208,19 @@ def test_removed_from_core_common(self):
'ensure_float']:
self.assertRaises(AttributeError, lambda: getattr(com, t))


class TestDatetools(tm.TestCase):

def test_deprecation_access_func(self):
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
pd.datetools.to_datetime('2016-01-01')

def test_deprecation_access_obj(self):
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
pd.datetools.monthEnd

if __name__ == '__main__':
import nose
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
Expand Down
14 changes: 12 additions & 2 deletions pandas/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@
from pandas.tseries.tdi import TimedeltaIndex, Timedelta
from pandas.tseries.period import Period, PeriodIndex

# legacy
import pandas.core.datetools as datetools
# see gh-14094.
from pandas.util.depr_module import _DeprecatedModule

_alts = ['pandas.tseries.tools', 'pandas.tseries.offsets',
'pandas.tseries.frequencies']
_removals = ['day', 'bday', 'businessDay', 'cday', 'customBusinessDay',
'customBusinessMonthEnd', 'customBusinessMonthBegin',
'monthEnd', 'yearEnd', 'yearBegin', 'bmonthEnd', 'bmonthBegin',
'cbmonthEnd', 'cbmonthBegin', 'bquarterEnd', 'quarterEnd',
'byearEnd', 'week']
datetools = _DeprecatedModule(deprmod='pandas.core.datetools', alts=_alts,
removals=_removals)

from pandas.core.config import (get_option, set_option, reset_option,
describe_option, option_context, options)
6 changes: 6 additions & 0 deletions pandas/core/datetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

# flake8: noqa

import warnings

from pandas.tseries.tools import *
from pandas.tseries.offsets import *
from pandas.tseries.frequencies import *

warnings.warn("The pandas.core.datetools module is deprecated and will be "
"removed in a future version. Please use the pandas.tseries "
"module instead.", FutureWarning, stacklevel=2)

day = DateOffset()
bday = BDay()
businessDay = bday
Expand Down
79 changes: 79 additions & 0 deletions pandas/util/depr_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
This module houses a utility class for mocking deprecated modules.
It is for internal use only and should not be used beyond this purpose.
"""

import warnings
import importlib


class _DeprecatedModule(object):
""" Class for mocking deprecated modules.
Parameters
----------
deprmod : name of module to be deprecated.
alts : alternative modules to be used to access objects or methods
available in module.
removals : objects or methods in module that will no longer be
accessible once module is removed.
"""
def __init__(self, deprmod, alts=None, removals=None):
self.deprmod = deprmod

self.alts = alts
if self.alts is not None:
self.alts = frozenset(self.alts)

self.removals = removals
if self.removals is not None:
self.removals = frozenset(self.removals)

# For introspection purposes.
self.self_dir = frozenset(dir(self.__class__))

def __dir__(self):
_dir = object.__dir__(self)

if self.removals is not None:
_dir.extend(list(self.removals))

if self.alts is not None:
for modname in self.alts:
module = importlib.import_module(modname)
_dir.extend(dir(module))

return _dir

def __getattr__(self, name):
if name in self.self_dir:
return object.__getattribute__(self, name)

if self.removals is not None and name in self.removals:
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=FutureWarning)
module = importlib.import_module(self.deprmod)

warnings.warn(
"{deprmod}.{name} is deprecated and will be removed in "
"a future version.".format(deprmod=self.deprmod, name=name),
FutureWarning, stacklevel=2)

return object.__getattribute__(module, name)

if self.alts is not None:
for modname in self.alts:
module = importlib.import_module(modname)

if hasattr(module, name):
warnings.warn(
"{deprmod}.{name} is deprecated. Please use "
"{modname}.{name} instead.".format(
deprmod=self.deprmod, modname=modname, name=name),
FutureWarning, stacklevel=2)

return getattr(module, name)

raise AttributeError("module '{deprmod}' has no attribute "
"'{name}'".format(deprmod=self.deprmod,
name=name))

0 comments on commit 2bb887d

Please sign in to comment.