Skip to content

Commit

Permalink
DEPR: Remove sql.execute, *args/**kwargs in resample, unrecognized ti…
Browse files Browse the repository at this point in the history
…mezones (pandas-dev#57241)
  • Loading branch information
mroeschke authored Feb 6, 2024
1 parent 6725e37 commit cece8c6
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 206 deletions.
3 changes: 3 additions & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ Removal of prior version deprecations/changes
- Removed ``DataFrameGroupBy.grouper`` and ``SeriesGroupBy.grouper`` (:issue:`56521`)
- Removed ``axis`` argument from :meth:`DataFrame.groupby`, :meth:`Series.groupby`, :meth:`DataFrame.rolling`, :meth:`Series.rolling`, :meth:`DataFrame.resample`, and :meth:`Series.resample` (:issue:`51203`)
- Removed ``axis`` argument from all groupby operations (:issue:`50405`)
- Removed ``pandas.io.sql.execute`` (:issue:`50185`)
- Removed deprecated argument ``obj`` in :meth:`.DataFrameGroupBy.get_group` and :meth:`.SeriesGroupBy.get_group` (:issue:`53545`)
- Removed the ``ArrayManager`` (:issue:`55043`)
- Removed unused arguments ``*args`` and ``**kwargs`` in :class:`Resampler` methods (:issue:`50977`)
- Unrecognized timezones when parsing strings to datetimes now raises a ``ValueError`` (:issue:`51477`)

.. ---------------------------------------------------------------------------
.. _whatsnew_300.performance:
Expand Down
11 changes: 3 additions & 8 deletions pandas/_libs/tslibs/parsing.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -733,15 +733,10 @@ cdef datetime dateutil_parse(
)
elif res.tzname is not None:
# e.g. "1994 Jan 15 05:16 FOO" where FOO is not recognized
# GH#18702
warnings.warn(
# GH#18702, # GH 50235 enforced in 3.0
raise ValueError(
f'Parsed string "{timestr}" included an un-recognized timezone '
f'"{res.tzname}". Dropping unrecognized timezones is deprecated; '
"in a future version this will raise. Instead pass the string "
"without the timezone, then use .tz_localize to convert to a "
"recognized timezone.",
FutureWarning,
stacklevel=find_stack_level()
f'"{res.tzname}".'
)

out_bestunit[0] = attrname_to_npy_unit[reso]
Expand Down
97 changes: 3 additions & 94 deletions pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
)
from pandas._libs.tslibs.dtypes import freq_to_period_freqstr
from pandas._typing import NDFrameT
from pandas.compat.numpy import function as nv
from pandas.errors import AbstractMethodError
from pandas.util._decorators import (
Appender,
Expand Down Expand Up @@ -1156,8 +1155,6 @@ def sum(
self,
numeric_only: bool = False,
min_count: int = 0,
*args,
**kwargs,
):
"""
Compute sum of group values.
Expand Down Expand Up @@ -1195,17 +1192,13 @@ def sum(
2023-02-01 7
Freq: MS, dtype: int64
"""
maybe_warn_args_and_kwargs(type(self), "sum", args, kwargs)
nv.validate_resampler_func("sum", args, kwargs)
return self._downsample("sum", numeric_only=numeric_only, min_count=min_count)

@final
def prod(
self,
numeric_only: bool = False,
min_count: int = 0,
*args,
**kwargs,
):
"""
Compute prod of group values.
Expand Down Expand Up @@ -1243,17 +1236,13 @@ def prod(
2023-02-01 12
Freq: MS, dtype: int64
"""
maybe_warn_args_and_kwargs(type(self), "prod", args, kwargs)
nv.validate_resampler_func("prod", args, kwargs)
return self._downsample("prod", numeric_only=numeric_only, min_count=min_count)

@final
def min(
self,
numeric_only: bool = False,
min_count: int = 0,
*args,
**kwargs,
):
"""
Compute min value of group.
Expand All @@ -1277,18 +1266,13 @@ def min(
2023-02-01 3
Freq: MS, dtype: int64
"""

maybe_warn_args_and_kwargs(type(self), "min", args, kwargs)
nv.validate_resampler_func("min", args, kwargs)
return self._downsample("min", numeric_only=numeric_only, min_count=min_count)

@final
def max(
self,
numeric_only: bool = False,
min_count: int = 0,
*args,
**kwargs,
):
"""
Compute max value of group.
Expand All @@ -1312,8 +1296,6 @@ def max(
2023-02-01 4
Freq: MS, dtype: int64
"""
maybe_warn_args_and_kwargs(type(self), "max", args, kwargs)
nv.validate_resampler_func("max", args, kwargs)
return self._downsample("max", numeric_only=numeric_only, min_count=min_count)

@final
Expand All @@ -1323,11 +1305,7 @@ def first(
numeric_only: bool = False,
min_count: int = 0,
skipna: bool = True,
*args,
**kwargs,
):
maybe_warn_args_and_kwargs(type(self), "first", args, kwargs)
nv.validate_resampler_func("first", args, kwargs)
return self._downsample(
"first", numeric_only=numeric_only, min_count=min_count, skipna=skipna
)
Expand All @@ -1339,28 +1317,20 @@ def last(
numeric_only: bool = False,
min_count: int = 0,
skipna: bool = True,
*args,
**kwargs,
):
maybe_warn_args_and_kwargs(type(self), "last", args, kwargs)
nv.validate_resampler_func("last", args, kwargs)
return self._downsample(
"last", numeric_only=numeric_only, min_count=min_count, skipna=skipna
)

@final
@doc(GroupBy.median)
def median(self, numeric_only: bool = False, *args, **kwargs):
maybe_warn_args_and_kwargs(type(self), "median", args, kwargs)
nv.validate_resampler_func("median", args, kwargs)
def median(self, numeric_only: bool = False):
return self._downsample("median", numeric_only=numeric_only)

@final
def mean(
self,
numeric_only: bool = False,
*args,
**kwargs,
):
"""
Compute mean of groups, excluding missing values.
Expand Down Expand Up @@ -1395,17 +1365,13 @@ def mean(
2023-02-01 3.5
Freq: MS, dtype: float64
"""
maybe_warn_args_and_kwargs(type(self), "mean", args, kwargs)
nv.validate_resampler_func("mean", args, kwargs)
return self._downsample("mean", numeric_only=numeric_only)

@final
def std(
self,
ddof: int = 1,
numeric_only: bool = False,
*args,
**kwargs,
):
"""
Compute standard deviation of groups, excluding missing values.
Expand Down Expand Up @@ -1443,17 +1409,13 @@ def std(
2023-02-01 2.645751
Freq: MS, dtype: float64
"""
maybe_warn_args_and_kwargs(type(self), "std", args, kwargs)
nv.validate_resampler_func("std", args, kwargs)
return self._downsample("std", ddof=ddof, numeric_only=numeric_only)

@final
def var(
self,
ddof: int = 1,
numeric_only: bool = False,
*args,
**kwargs,
):
"""
Compute variance of groups, excluding missing values.
Expand Down Expand Up @@ -1497,8 +1459,6 @@ def var(
2023-02-01 4.666667
Freq: MS, dtype: float64
"""
maybe_warn_args_and_kwargs(type(self), "var", args, kwargs)
nv.validate_resampler_func("var", args, kwargs)
return self._downsample("var", ddof=ddof, numeric_only=numeric_only)

@final
Expand All @@ -1507,23 +1467,12 @@ def sem(
self,
ddof: int = 1,
numeric_only: bool = False,
*args,
**kwargs,
):
maybe_warn_args_and_kwargs(type(self), "sem", args, kwargs)
nv.validate_resampler_func("sem", args, kwargs)
return self._downsample("sem", ddof=ddof, numeric_only=numeric_only)

@final
@doc(GroupBy.ohlc)
def ohlc(
self,
*args,
**kwargs,
):
maybe_warn_args_and_kwargs(type(self), "ohlc", args, kwargs)
nv.validate_resampler_func("ohlc", args, kwargs)

def ohlc(self):
ax = self.ax
obj = self._obj_with_exclusions
if len(ax) == 0:
Expand All @@ -1544,13 +1493,7 @@ def ohlc(

@final
@doc(SeriesGroupBy.nunique)
def nunique(
self,
*args,
**kwargs,
):
maybe_warn_args_and_kwargs(type(self), "nunique", args, kwargs)
nv.validate_resampler_func("nunique", args, kwargs)
def nunique(self):
return self._downsample("nunique")

@final
Expand Down Expand Up @@ -2874,40 +2817,6 @@ def _asfreq_compat(index: DatetimeIndex | PeriodIndex | TimedeltaIndex, freq):
return new_index


def maybe_warn_args_and_kwargs(cls, kernel: str, args, kwargs) -> None:
"""
Warn for deprecation of args and kwargs in resample functions.
Parameters
----------
cls : type
Class to warn about.
kernel : str
Operation name.
args : tuple or None
args passed by user. Will be None if and only if kernel does not have args.
kwargs : dict or None
kwargs passed by user. Will be None if and only if kernel does not have kwargs.
"""
warn_args = args is not None and len(args) > 0
warn_kwargs = kwargs is not None and len(kwargs) > 0
if warn_args and warn_kwargs:
msg = "args and kwargs"
elif warn_args:
msg = "args"
elif warn_kwargs:
msg = "kwargs"
else:
return
warnings.warn(
f"Passing additional {msg} to {cls.__name__}.{kernel} has "
"no impact on the result and is deprecated. This will "
"raise a TypeError in a future version of pandas.",
category=FutureWarning,
stacklevel=find_stack_level(),
)


def _apply(
grouped: GroupBy, how: Callable, *args, include_groups: bool, **kwargs
) -> DataFrame:
Expand Down
31 changes: 0 additions & 31 deletions pandas/io/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,37 +235,6 @@ def _wrap_result_adbc(
return df


def execute(sql, con, params=None):
"""
Execute the given SQL query using the provided connection object.
Parameters
----------
sql : string
SQL query to be executed.
con : SQLAlchemy connection or sqlite3 connection
If a DBAPI2 object, only sqlite3 is supported.
params : list or tuple, optional, default: None
List of parameters to pass to execute method.
Returns
-------
Results Iterable
"""
warnings.warn(
"`pandas.io.sql.execute` is deprecated and "
"will be removed in the future version.",
FutureWarning,
stacklevel=find_stack_level(),
) # GH50185
sqlalchemy = import_optional_dependency("sqlalchemy", errors="ignore")

if sqlalchemy is not None and isinstance(con, (str, sqlalchemy.engine.Engine)):
raise TypeError("pandas.io.sql.execute requires a connection") # GH50185
with pandasSQL_builder(con, need_transaction=True) as pandas_sql:
return pandas_sql.execute(sql, params)


# -----------------------------------------------------------------------------
# -- Read and write to DataFrames

Expand Down
20 changes: 0 additions & 20 deletions pandas/tests/io/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1487,26 +1487,6 @@ def test_read_view_sqlite(sqlite_buildin):
tm.assert_frame_equal(result, expected)


def test_execute_typeerror(sqlite_engine_iris):
with pytest.raises(TypeError, match="pandas.io.sql.execute requires a connection"):
with tm.assert_produces_warning(
FutureWarning,
match="`pandas.io.sql.execute` is deprecated and "
"will be removed in the future version.",
):
sql.execute("select * from iris", sqlite_engine_iris)


def test_execute_deprecated(sqlite_conn_iris):
# GH50185
with tm.assert_produces_warning(
FutureWarning,
match="`pandas.io.sql.execute` is deprecated and "
"will be removed in the future version.",
):
sql.execute("select * from iris", sqlite_conn_iris)


def flavor(conn_name):
if "postgresql" in conn_name:
return "postgresql"
Expand Down
41 changes: 0 additions & 41 deletions pandas/tests/resample/test_resample_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pytest

from pandas._libs import lib
from pandas.errors import UnsupportedFunctionCall

import pandas as pd
from pandas import (
Expand Down Expand Up @@ -987,46 +986,6 @@ def test_series_downsample_method(method, numeric_only, expected_data):
tm.assert_series_equal(result, expected)


@pytest.mark.parametrize(
"method, raises",
[
("sum", True),
("prod", True),
("min", True),
("max", True),
("first", False),
("last", False),
("median", False),
("mean", True),
("std", True),
("var", True),
("sem", False),
("ohlc", False),
("nunique", False),
],
)
def test_args_kwargs_depr(method, raises):
index = date_range("20180101", periods=3, freq="h")
df = Series([2, 4, 6], index=index)
resampled = df.resample("30min")
args = ()

func = getattr(resampled, method)

error_msg = "numpy operations are not valid with resample."
error_msg_type = "too many arguments passed in"
warn_msg = f"Passing additional args to DatetimeIndexResampler.{method}"

if raises:
with tm.assert_produces_warning(FutureWarning, match=warn_msg):
with pytest.raises(UnsupportedFunctionCall, match=error_msg):
func(*args, 1, 2, 3, 4)
else:
with tm.assert_produces_warning(FutureWarning, match=warn_msg):
with pytest.raises(TypeError, match=error_msg_type):
func(*args, 1, 2, 3, 4)


def test_resample_empty():
# GH#52484
df = DataFrame(
Expand Down
Loading

0 comments on commit cece8c6

Please sign in to comment.