From 63e44e10ab0c1371bf4e457ed8e2bc30ac77f974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 17 Aug 2022 13:32:36 -0400 Subject: [PATCH 1/4] DEPR: positional arguments of read/to_state --- doc/source/whatsnew/v1.5.0.rst | 1 + pandas/core/frame.py | 1 + pandas/io/stata.py | 2 ++ 3 files changed, 4 insertions(+) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 0ceac8aeb9db8..d083264d95ef6 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -850,6 +850,7 @@ Other Deprecations - Deprecated producing a single element when iterating over a :class:`DataFrameGroupBy` or a :class:`SeriesGroupBy` that has been grouped by a list of length 1; A tuple of length one will be returned instead (:issue:`42795`) - Fixed up warning message of deprecation of :meth:`MultiIndex.lesort_depth` as public method, as the message previously referred to :meth:`MultiIndex.is_lexsorted` instead (:issue:`38701`) - Deprecated the ``sort_columns`` argument in :meth:`DataFrame.plot` and :meth:`Series.plot` (:issue:`47563`). +- Deprecated positional arguments for all but the frist argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`XXXXX`). .. --------------------------------------------------------------------------- .. _whatsnew_150.performance: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 7a4f41da5840c..8eb43d95ea1ec 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2576,6 +2576,7 @@ def _from_arrays( compression_options=_shared_docs["compression_options"] % "path", ) @deprecate_kwarg(old_arg_name="fname", new_arg_name="path") + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "path"]) def to_stata( self, path: FilePath | WriteBuffer[bytes], diff --git a/pandas/io/stata.py b/pandas/io/stata.py index e59b6c8770389..011e2e631feef 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -29,6 +29,7 @@ ) import warnings +from pandas.util._decorators import deprecate_nonkeyword_arguments from dateutil.relativedelta import relativedelta import numpy as np @@ -1980,6 +1981,7 @@ def value_labels(self) -> dict[str, dict[float, str]]: @Appender(_read_stata_doc) +@deprecate_nonkeyword_arguments(version=None, allowed_args=["filepath_or_buffer"]) def read_stata( filepath_or_buffer: FilePath | ReadBuffer[bytes], convert_dates: bool = True, From 161bc42de757d8df79594642b57e0ade19edf365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 17 Aug 2022 13:33:59 -0400 Subject: [PATCH 2/4] pr number --- doc/source/whatsnew/v1.5.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index d083264d95ef6..c196066bd9cdc 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -850,7 +850,7 @@ Other Deprecations - Deprecated producing a single element when iterating over a :class:`DataFrameGroupBy` or a :class:`SeriesGroupBy` that has been grouped by a list of length 1; A tuple of length one will be returned instead (:issue:`42795`) - Fixed up warning message of deprecation of :meth:`MultiIndex.lesort_depth` as public method, as the message previously referred to :meth:`MultiIndex.is_lexsorted` instead (:issue:`38701`) - Deprecated the ``sort_columns`` argument in :meth:`DataFrame.plot` and :meth:`Series.plot` (:issue:`47563`). -- Deprecated positional arguments for all but the frist argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`XXXXX`). +- Deprecated positional arguments for all but the frist argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`48128`). .. --------------------------------------------------------------------------- .. _whatsnew_150.performance: From 8ccb1cca3fb575ccc351925f1e49599b1ada8747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 17 Aug 2022 13:34:39 -0400 Subject: [PATCH 3/4] isort --- pandas/io/stata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 011e2e631feef..eb3993d13b7b0 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -29,7 +29,6 @@ ) import warnings -from pandas.util._decorators import deprecate_nonkeyword_arguments from dateutil.relativedelta import relativedelta import numpy as np @@ -50,6 +49,7 @@ ) from pandas.util._decorators import ( Appender, + deprecate_nonkeyword_arguments, doc, ) From b2027881c1a7f518a2e768aa68c445ba516e7cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20W=C3=B6rtwein?= Date: Wed, 17 Aug 2022 14:57:15 -0400 Subject: [PATCH 4/4] use keyword arguments in tests and fix typo --- doc/source/whatsnew/v1.5.0.rst | 2 +- pandas/tests/io/test_stata.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index c196066bd9cdc..bad5b15bf45d6 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -850,7 +850,7 @@ Other Deprecations - Deprecated producing a single element when iterating over a :class:`DataFrameGroupBy` or a :class:`SeriesGroupBy` that has been grouped by a list of length 1; A tuple of length one will be returned instead (:issue:`42795`) - Fixed up warning message of deprecation of :meth:`MultiIndex.lesort_depth` as public method, as the message previously referred to :meth:`MultiIndex.is_lexsorted` instead (:issue:`38701`) - Deprecated the ``sort_columns`` argument in :meth:`DataFrame.plot` and :meth:`Series.plot` (:issue:`47563`). -- Deprecated positional arguments for all but the frist argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`48128`). +- Deprecated positional arguments for all but the first argument of :meth:`DataFrame.to_stata` and :func:`read_stata`, use keyword arguments instead (:issue:`48128`). .. --------------------------------------------------------------------------- .. _whatsnew_150.performance: diff --git a/pandas/tests/io/test_stata.py b/pandas/tests/io/test_stata.py index f06bf0035c7dc..6e8c415825c89 100644 --- a/pandas/tests/io/test_stata.py +++ b/pandas/tests/io/test_stata.py @@ -285,7 +285,7 @@ def test_read_write_dta5(self): original.index.name = "index" with tm.ensure_clean() as path: - original.to_stata(path, None) + original.to_stata(path, convert_dates=None) written_and_read_again = self.read_dta(path) tm.assert_frame_equal(written_and_read_again.set_index("index"), original) @@ -297,7 +297,7 @@ def test_write_dta6(self, datapath): original["quarter"] = original["quarter"].astype(np.int32) with tm.ensure_clean() as path: - original.to_stata(path, None) + original.to_stata(path, convert_dates=None) written_and_read_again = self.read_dta(path) tm.assert_frame_equal( written_and_read_again.set_index("index"), @@ -317,7 +317,7 @@ def test_read_write_dta10(self, version): original["integer"] = original["integer"].astype(np.int32) with tm.ensure_clean() as path: - original.to_stata(path, {"datetime": "tc"}, version=version) + original.to_stata(path, convert_dates={"datetime": "tc"}, version=version) written_and_read_again = self.read_dta(path) # original.index is np.int32, read index is np.int64 tm.assert_frame_equal( @@ -377,7 +377,7 @@ def test_read_write_dta11(self): with tm.ensure_clean() as path: with tm.assert_produces_warning(InvalidColumnName): - original.to_stata(path, None) + original.to_stata(path, convert_dates=None) written_and_read_again = self.read_dta(path) tm.assert_frame_equal(written_and_read_again.set_index("index"), formatted) @@ -412,7 +412,7 @@ def test_read_write_dta12(self, version): with tm.ensure_clean() as path: with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", InvalidColumnName) - original.to_stata(path, None, version=version) + original.to_stata(path, convert_dates=None, version=version) # should get a warning for that format. assert len(w) == 1 @@ -453,7 +453,7 @@ def test_read_write_reread_dta14(self, file, parsed_114, version, datapath): tm.assert_frame_equal(parsed_114, parsed) with tm.ensure_clean() as path: - parsed_114.to_stata(path, {"date_td": "td"}, version=version) + parsed_114.to_stata(path, convert_dates={"date_td": "td"}, version=version) written_and_read_again = self.read_dta(path) tm.assert_frame_equal(written_and_read_again.set_index("index"), parsed_114) @@ -573,7 +573,7 @@ def test_dates_invalid_column(self): original.index.name = "index" with tm.ensure_clean() as path: with tm.assert_produces_warning(InvalidColumnName): - original.to_stata(path, {0: "tc"}) + original.to_stata(path, convert_dates={0: "tc"}) written_and_read_again = self.read_dta(path) modified = original.copy() @@ -623,7 +623,7 @@ def test_date_export_formats(self): expected = DataFrame([expected_values], columns=columns) expected.index.name = "index" with tm.ensure_clean() as path: - original.to_stata(path, conversions) + original.to_stata(path, convert_dates=conversions) written_and_read_again = self.read_dta(path) tm.assert_frame_equal(written_and_read_again.set_index("index"), expected)