Skip to content

Commit

Permalink
DEPR: Deprecate pandas.datetime (#30489)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryankarlos authored and jreback committed Jan 2, 2020
1 parent 9871bdd commit 0913ed0
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 26 deletions.
3 changes: 3 additions & 0 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ Other enhancements
- :meth:`DataFrame.drop_duplicates` has gained ``ignore_index`` keyword to reset index (:issue:`30114`)
- Added new writer for exporting Stata dta files in version 118, ``StataWriter118``. This format supports exporting strings containing Unicode characters (:issue:`23573`)
- :meth:`Series.map` now accepts ``collections.abc.Mapping`` subclasses as a mapper (:issue:`29733`)
- The ``pandas.datetime`` class is now deprecated. Import from ``datetime`` instead (:issue:`30296`)



Build Changes
^^^^^^^^^^^^^
Expand Down
41 changes: 39 additions & 2 deletions pandas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
"the C extensions first."
)

from datetime import datetime

from pandas._config import (
get_option,
set_option,
Expand Down Expand Up @@ -210,6 +208,19 @@ class Panel:

return Panel

elif name == "datetime":
warnings.warn(
"The pandas.datetime class is deprecated "
"and will be removed from pandas in a future version. "
"Import from datetime module instead.",
FutureWarning,
stacklevel=2,
)

from datetime import datetime as dt

return dt

elif name == "np":

warnings.warn(
Expand Down Expand Up @@ -264,13 +275,39 @@ def __getattr__(self, item):
FutureWarning,
stacklevel=2,
)

try:
return getattr(self.np, item)
except AttributeError:
raise AttributeError(f"module numpy has no attribute {item}")

np = __numpy()

class __Datetime:
def __init__(self):
from datetime import datetime as dt

self.datetime = dt

def __getattr__(self, item):
import warnings

warnings.warn(
"The pandas.datetime class is deprecated "
"and will be removed from pandas in a future version. "
"Import from datetime instead.",
FutureWarning,
stacklevel=2,
)

try:
return getattr(self.datetime, item)
except AttributeError:
raise AttributeError(f"module datetime has no attribute {item}")

datetime = __Datetime().datetime


# module level doc-string
__doc__ = """
pandas - a powerful data analysis and manipulation library for Python
Expand Down
16 changes: 14 additions & 2 deletions pandas/tests/api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class TestPDApi(Base):
]
if not compat.PY37:
classes.extend(["Panel", "SparseSeries", "SparseDataFrame"])
deprecated_modules.append("np")
deprecated_modules.extend(["np", "datetime"])

# these are already deprecated; awaiting removal
deprecated_classes: List[str] = []
Expand All @@ -101,7 +101,7 @@ class TestPDApi(Base):
deprecated_classes_in_future: List[str] = []

# external modules exposed in pandas namespace
modules = ["datetime"]
modules: List[str] = []

# top-level functions
funcs = [
Expand Down Expand Up @@ -232,11 +232,23 @@ def test_depr(self):
with tm.assert_produces_warning(FutureWarning):
if compat.PY37:
getattr(pd, depr)
elif depr == "datetime":
deprecated = getattr(pd, "__Datetime")
deprecated().__getattr__(dir(pd.datetime)[-1])
else:
deprecated = getattr(pd, depr)
deprecated.__getattr__(dir(deprecated)[-1])


def test_datetime():
from datetime import datetime
import warnings

with warnings.catch_warnings():
warnings.simplefilter("ignore", FutureWarning)
assert datetime(2015, 1, 2, 0, 0) == pd.datetime(2015, 1, 2, 0, 0)


def test_np():
import numpy as np
import warnings
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/dtypes/test_common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from typing import List

import numpy as np
Expand Down Expand Up @@ -490,7 +491,7 @@ def test_is_numeric_v_string_like():


def test_is_datetimelike_v_numeric():
dt = np.datetime64(pd.datetime(2017, 1, 1))
dt = np.datetime64(datetime(2017, 1, 1))

assert not com.is_datetimelike_v_numeric(1, 1)
assert not com.is_datetimelike_v_numeric(dt, dt)
Expand Down
8 changes: 4 additions & 4 deletions pandas/tests/frame/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,18 +1146,18 @@ def test_setitem_mixed_datetime(self):
{
"a": [0, 0, 0, 0, 13, 14],
"b": [
pd.datetime(2012, 1, 1),
datetime(2012, 1, 1),
1,
"x",
"y",
pd.datetime(2013, 1, 1),
pd.datetime(2014, 1, 1),
datetime(2013, 1, 1),
datetime(2014, 1, 1),
],
}
)
df = pd.DataFrame(0, columns=list("ab"), index=range(6))
df["b"] = pd.NaT
df.loc[0, "b"] = pd.datetime(2012, 1, 1)
df.loc[0, "b"] = datetime(2012, 1, 1)
df.loc[1, "b"] = 1
df.loc[[2, 3], "b"] = "x", "y"
A = np.array(
Expand Down
4 changes: 1 addition & 3 deletions pandas/tests/groupby/test_groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -1729,9 +1729,7 @@ def test_pivot_table_values_key_error():
# This test is designed to replicate the error in issue #14938
df = pd.DataFrame(
{
"eventDate": pd.date_range(
pd.datetime.today(), periods=20, freq="M"
).tolist(),
"eventDate": pd.date_range(datetime.today(), periods=20, freq="M").tolist(),
"thename": range(0, 20),
}
)
Expand Down
12 changes: 2 additions & 10 deletions pandas/tests/indexes/datetimes/test_constructors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import timedelta
from datetime import datetime, timedelta
from functools import partial
from operator import attrgetter

Expand All @@ -10,15 +10,7 @@
from pandas._libs.tslibs import OutOfBoundsDatetime, conversion

import pandas as pd
from pandas import (
DatetimeIndex,
Index,
Timestamp,
date_range,
datetime,
offsets,
to_datetime,
)
from pandas import DatetimeIndex, Index, Timestamp, date_range, offsets, to_datetime
from pandas.core.arrays import DatetimeArray, period_array
import pandas.util.testing as tm

Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/indexes/datetimes/test_misc.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import calendar
from datetime import datetime
import locale
import unicodedata

import numpy as np
import pytest

import pandas as pd
from pandas import DatetimeIndex, Index, Timestamp, date_range, datetime, offsets
from pandas import DatetimeIndex, Index, Timestamp, date_range, offsets
import pandas.util.testing as tm


Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/indexing/test_iloc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" test positional based indexing with iloc """

from datetime import datetime
from warnings import catch_warnings, simplefilter

import numpy as np
Expand Down Expand Up @@ -122,7 +123,7 @@ def check(result, expected):
[
([slice(None), ["A", "D"]]),
(["1", "2"], slice(None)),
([pd.datetime(2019, 1, 1)], slice(None)),
([datetime(2019, 1, 1)], slice(None)),
],
)
def test_iloc_non_integer_raises(self, index, columns, index_vals, column_vals):
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/io/excel/test_writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def test_read_excel_parse_dates(self, ext):
res = pd.read_excel(pth, parse_dates=["date_strings"], index_col=0)
tm.assert_frame_equal(df, res)

date_parser = lambda x: pd.datetime.strptime(x, "%m/%d/%Y")
date_parser = lambda x: datetime.strptime(x, "%m/%d/%Y")
res = pd.read_excel(
pth, parse_dates=["date_strings"], date_parser=date_parser, index_col=0
)
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/io/sas/test_sas7bdat.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
import io
import os
from pathlib import Path
Expand All @@ -23,7 +24,7 @@ def setup_method(self, datapath):
for j in 1, 2:
fname = os.path.join(self.dirpath, f"test_sas7bdat_{j}.csv")
df = pd.read_csv(fname)
epoch = pd.datetime(1960, 1, 1)
epoch = datetime(1960, 1, 1)
t1 = pd.to_timedelta(df["Column4"], unit="d")
df["Column4"] = epoch + t1
t2 = pd.to_timedelta(df["Column12"], unit="d")
Expand Down

0 comments on commit 0913ed0

Please sign in to comment.