From 62cfbad2a1304bfba446fa4708ba16e8de9d6abe Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 10 Aug 2017 11:26:27 -0400 Subject: [PATCH 1/5] FIX: define `DataFrame.items` for all versions of python Closes #17213 This leaves a slight semantic difference between `dict.items` and `DateFrame.items` in python2, however there is no code currently expecting `DataFrame.items` to return a list and in python3 there is no `dict.iteritems`. This eases writing 'native' python3 code that also runs under python2. --- pandas/core/frame.py | 3 +-- pandas/tests/frame/test_api.py | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 467ef52de234e..b5b3df64d24c0 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -802,8 +802,7 @@ def itertuples(self, index=True, name="Pandas"): # fallback to regular tuples return zip(*arrays) - if compat.PY3: # pragma: no cover - items = iteritems + items = iteritems def __len__(self): """Returns length of info axis, but here we use the index """ diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index 53a1b9525a0dd..7c92b24811d6f 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -173,6 +173,11 @@ def test_iteritems(self): for k, v in compat.iteritems(df): assert type(v) == self.klass._constructor_sliced + def test_items(self): + df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=['a', 'a', 'b']) + for k, v in df.items(): + assert type(v) == Series + def test_iter(self): assert tm.equalContents(list(self.frame), self.frame.columns) From 764cf55fe1b428ed87929dde41262aef3cb938dd Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 10 Aug 2017 11:40:08 -0400 Subject: [PATCH 2/5] TST: extend test and add issue reference --- pandas/tests/frame/test_api.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index 7c92b24811d6f..386a48da66c1a 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -174,9 +174,13 @@ def test_iteritems(self): assert type(v) == self.klass._constructor_sliced def test_items(self): - df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=['a', 'a', 'b']) - for k, v in df.items(): + # issue #17213, #13918 + cols = ['a', 'b', 'c'] + df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=cols) + for c, (k, v) in zip(cols, df.items()): + assert c == k assert type(v) == Series + assert (df[k] == v).all() def test_iter(self): assert tm.equalContents(list(self.frame), self.frame.columns) From b1f46f8a2483964111bef600913470f3a40c8f4c Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 10 Aug 2017 15:50:41 -0400 Subject: [PATCH 3/5] DOC: add whatsnew entry --- doc/source/whatsnew/v0.21.0.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 6008ea5d4cbcd..67d5ef84a75e4 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -128,6 +128,8 @@ Other Enhancements - :func:`DataFrame.add_prefix` and :func:`DataFrame.add_suffix` now accept strings containing the '%' character. (:issue:`17151`) - `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`). - :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). +- :func:`DataFrame.items` is present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) + .. _whatsnew_0210.api_breaking: From 32aa0898c533d97556aa91d09815d5b5d029d0bc Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 19 Aug 2017 14:04:51 -0400 Subject: [PATCH 4/5] DOC/TST: trivial changes --- doc/source/whatsnew/v0.21.0.txt | 3 ++- pandas/tests/frame/test_api.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 67d5ef84a75e4..a64e0f0380d0d 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -128,7 +128,8 @@ Other Enhancements - :func:`DataFrame.add_prefix` and :func:`DataFrame.add_suffix` now accept strings containing the '%' character. (:issue:`17151`) - `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`). - :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). -- :func:`DataFrame.items` is present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) +- :func:`DataFrame.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) + .. _whatsnew_0210.api_breaking: diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index 386a48da66c1a..a62fcb506a34b 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -171,7 +171,7 @@ def test_nonzero(self): def test_iteritems(self): df = self.klass([[1, 2, 3], [4, 5, 6]], columns=['a', 'a', 'b']) for k, v in compat.iteritems(df): - assert type(v) == self.klass._constructor_sliced + assert isinstance(v, self.klass._constructor_sliced) def test_items(self): # issue #17213, #13918 @@ -179,7 +179,7 @@ def test_items(self): df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=cols) for c, (k, v) in zip(cols, df.items()): assert c == k - assert type(v) == Series + assert isinstance(v, Series) assert (df[k] == v).all() def test_iter(self): From b8a9ab7ae49b3d452195e702d39fa1f5ac86d73d Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 19 Aug 2017 14:31:29 -0400 Subject: [PATCH 5/5] FIX: support lazy `items` on Series in all versions of python --- doc/source/whatsnew/v0.21.0.txt | 3 ++- pandas/core/series.py | 3 +-- pandas/tests/series/test_api.py | 10 ++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index a64e0f0380d0d..c5fe89282bf52 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -128,7 +128,8 @@ Other Enhancements - :func:`DataFrame.add_prefix` and :func:`DataFrame.add_suffix` now accept strings containing the '%' character. (:issue:`17151`) - `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`). - :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). -- :func:`DataFrame.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) +- :func:`DataFrame.items` and :func:`Series.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`) + diff --git a/pandas/core/series.py b/pandas/core/series.py index c8282450b77a9..75dc3d6403650 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1110,8 +1110,7 @@ def iteritems(self): """ return zip(iter(self.index), iter(self)) - if compat.PY3: # pragma: no cover - items = iteritems + items = iteritems # ---------------------------------------------------------------------- # Misc public methods diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 8e22dd38030ee..b7fbe803f8d3b 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -301,6 +301,16 @@ def test_iteritems(self): # assert is lazy (genrators don't define reverse, lists do) assert not hasattr(self.series.iteritems(), 'reverse') + def test_items(self): + for idx, val in self.series.items(): + assert val == self.series[idx] + + for idx, val in self.ts.items(): + assert val == self.ts[idx] + + # assert is lazy (genrators don't define reverse, lists do) + assert not hasattr(self.series.items(), 'reverse') + def test_raise_on_info(self): s = Series(np.random.randn(10)) with pytest.raises(AttributeError):