Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: Deprecate pandas.datetime #30489

Merged
merged 13 commits into from
Jan 2, 2020
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ Other enhancements
- :meth:`DataFrame.to_markdown` and :meth:`Series.to_markdown` added (:issue:`11052`)
- :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`)
- The ``pandas.datetime`` class is now deprecated. Import from ``datetime`` instead(:issue:`30296`)
ryankarlos marked this conversation as resolved.
Show resolved Hide resolved

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why two underscores instead of one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just to make it consistent with how __numpy() was being used - same for get__attr as thats how its used in pandas/tests/api/test_api.py::TestPDApi::test_depr
but i can revert if still needed

def __init__(self):
from datetime import datetime as dt
import warnings

self.datetime = dt
self.warnings = warnings

def __getattr__(self, item):
self.warnings.warn(
"The pandas.datetime class is deprecated "
"and will be removed from pandas in a future version. "
"Import from datetime instead",
ryankarlos marked this conversation as resolved.
Show resolved Hide resolved
FutureWarning,
stacklevel=2,
)

try:
return getattr(dt, 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
13 changes: 11 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 @@ -237,6 +237,15 @@ def test_depr(self):
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