From 4c18d08221446ac4fb3cc9e8fae8b1fc35b2107e Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 8 Nov 2022 05:16:36 +0000 Subject: [PATCH 1/4] BUG: Series(index=[]) should have dtype=object --- pandas/core/series.py | 5 +++- pandas/tests/series/test_constructors.py | 30 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 8716170594a80..080bb6db5d4f8 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -511,7 +511,10 @@ def _init_dict( elif index is not None: # fastpath for Series(data=None). Just use broadcasting a scalar # instead of reindexing. - values = na_value_for_dtype(pandas_dtype(dtype), compat=False) + if len(index): + values = na_value_for_dtype(pandas_dtype(dtype), compat=False) + else: + values = [] keys = index else: keys, values = (), [] diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index abb0ca5407505..b2c520f7e34f8 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -101,6 +101,36 @@ def test_empty_constructor(self, constructor, check_index_type): expected = Series() result = constructor() + assert result.dtype == object + assert len(result.index) == 0 + tm.assert_series_equal(result, expected, check_index_type=check_index_type) + + @pytest.mark.parametrize( + "constructor,check_index_type", + [ + # NOTE: some overlap with test_constructor_empty but that test does not + # test for None or an empty generator. + # test_constructor_pass_none tests None but only with the index also + # passed. + (lambda: Series(index=[]), True), + (lambda: Series(None, index=[]), True), + (lambda: Series({}, index=[]), True), + (lambda: Series((), index=[]), False), # creates a RangeIndex + (lambda: Series([], index=[]), False), # creates a RangeIndex + (lambda: Series((_ for _ in []), index=[]), False), # creates a RangeIndex + (lambda: Series(data=None, index=[]), True), + (lambda: Series(data={}, index=[]), True), + (lambda: Series(data=(), index=[]), False), # creates a RangeIndex + (lambda: Series(data=[], index=[]), False), # creates a RangeIndex + (lambda: Series(data=(_ for _ in []), index=[]), False), # RangeIndex + ], + ) + def test_empty_constructor_with_index(self, constructor, check_index_type): + # GH 49573 + expected = Series() + result = constructor() + + assert result.dtype == object assert len(result.index) == 0 tm.assert_series_equal(result, expected, check_index_type=check_index_type) From 357d9949857f2f6664f5af766a1b5c9f034fae77 Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 8 Nov 2022 05:39:40 +0000 Subject: [PATCH 2/4] parametrize tests --- pandas/tests/series/test_constructors.py | 59 +++++++----------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index b2c520f7e34f8..acd74f52054bc 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -83,52 +83,25 @@ def test_unparseable_strings_with_dt64_dtype(self): # test for None or an empty generator. # test_constructor_pass_none tests None but only with the index also # passed. - (lambda: Series(), True), - (lambda: Series(None), True), - (lambda: Series({}), True), - (lambda: Series(()), False), # creates a RangeIndex - (lambda: Series([]), False), # creates a RangeIndex - (lambda: Series(_ for _ in []), False), # creates a RangeIndex - (lambda: Series(data=None), True), - (lambda: Series(data={}), True), - (lambda: Series(data=()), False), # creates a RangeIndex - (lambda: Series(data=[]), False), # creates a RangeIndex - (lambda: Series(data=(_ for _ in [])), False), # creates a RangeIndex + (lambda idx: Series(index=idx), True), + (lambda idx: Series(None, index=idx), True), + (lambda idx: Series({}, index=idx), True), + (lambda idx: Series((), index=idx), False), # creates a RangeIndex + (lambda idx: Series([], index=idx), False), # creates a RangeIndex + (lambda idx: Series((_ for _ in []), index=idx), False), # RangeIndex + (lambda idx: Series(data=None, index=idx), True), + (lambda idx: Series(data={}, index=idx), True), + (lambda idx: Series(data=(), index=idx), False), # creates a RangeIndex + (lambda idx: Series(data=[], index=idx), False), # creates a RangeIndex + (lambda idx: Series(data=(_ for _ in []), index=idx), False), # RangeIndex ], ) - def test_empty_constructor(self, constructor, check_index_type): + @pytest.mark.parametrize("empty_index", [None, None]) + def test_empty_constructor(self, constructor, check_index_type, empty_index): # TODO: share with frame test of the same name - expected = Series() - result = constructor() - - assert result.dtype == object - assert len(result.index) == 0 - tm.assert_series_equal(result, expected, check_index_type=check_index_type) - - @pytest.mark.parametrize( - "constructor,check_index_type", - [ - # NOTE: some overlap with test_constructor_empty but that test does not - # test for None or an empty generator. - # test_constructor_pass_none tests None but only with the index also - # passed. - (lambda: Series(index=[]), True), - (lambda: Series(None, index=[]), True), - (lambda: Series({}, index=[]), True), - (lambda: Series((), index=[]), False), # creates a RangeIndex - (lambda: Series([], index=[]), False), # creates a RangeIndex - (lambda: Series((_ for _ in []), index=[]), False), # creates a RangeIndex - (lambda: Series(data=None, index=[]), True), - (lambda: Series(data={}, index=[]), True), - (lambda: Series(data=(), index=[]), False), # creates a RangeIndex - (lambda: Series(data=[], index=[]), False), # creates a RangeIndex - (lambda: Series(data=(_ for _ in []), index=[]), False), # RangeIndex - ], - ) - def test_empty_constructor_with_index(self, constructor, check_index_type): - # GH 49573 - expected = Series() - result = constructor() + # GH 49573 (addition of empty_index parameter) + expected = Series(index=empty_index) + result = constructor(empty_index) assert result.dtype == object assert len(result.index) == 0 From d6d40e8638e6016ef068ec3ecc2656144594c4e4 Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 8 Nov 2022 07:37:40 +0000 Subject: [PATCH 3/4] accept dtype --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 080bb6db5d4f8..0755866afc1d4 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -511,7 +511,7 @@ def _init_dict( elif index is not None: # fastpath for Series(data=None). Just use broadcasting a scalar # instead of reindexing. - if len(index): + if len(index) or dtype is not None: values = na_value_for_dtype(pandas_dtype(dtype), compat=False) else: values = [] From cf220db46c9953e7f471ef1a4aacf2aefbe2e775 Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 8 Nov 2022 08:03:06 +0000 Subject: [PATCH 4/4] fix --- pandas/tests/series/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index acd74f52054bc..65a2261d0d334 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -96,7 +96,7 @@ def test_unparseable_strings_with_dt64_dtype(self): (lambda idx: Series(data=(_ for _ in []), index=idx), False), # RangeIndex ], ) - @pytest.mark.parametrize("empty_index", [None, None]) + @pytest.mark.parametrize("empty_index", [None, []]) def test_empty_constructor(self, constructor, check_index_type, empty_index): # TODO: share with frame test of the same name # GH 49573 (addition of empty_index parameter)