From 3dbf53d4b56dbec8143dd344c71128c640ec0beb Mon Sep 17 00:00:00 2001 From: Pedro Cunial Date: Tue, 20 Aug 2019 08:04:23 -0300 Subject: [PATCH 1/4] support names keyword in Index --- pandas/core/indexes/base.py | 18 +++++++++++++++--- pandas/tests/indexes/test_base.py | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 4e098b2f8be9b..a816b448b60f6 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -176,8 +176,10 @@ class Index(IndexOpsMixin, PandasObject): Otherwise, an error will be raised. copy : bool Make a copy of input ndarray - name : object + name : object, optional Name to be stored in the index + names: tuple of objects, optional + Names to be stored in the index (only accepts tuple of length 1) tupleize_cols : bool (default: True) When True, attempt to create a MultiIndex if possible @@ -259,12 +261,22 @@ def __new__( dtype=None, copy=False, name=None, + names=None, fastpath=None, tupleize_cols=True, **kwargs ): - if name is None and hasattr(data, "name"): + if names is not None: + if name is not None: + raise TypeError("Using name and names is unsupported") + elif names is not None and not is_list_like(names): + raise TypeError("names must be list-like") + elif len(names) > 1: + raise TypeError("names must be list-like of size 1") + # infer name from names when MultiIndex cannot be created + name = names[0] + elif hasattr(data, "name") and name is None: name = data.name if fastpath is not None: @@ -493,7 +505,7 @@ def __new__( from .multi import MultiIndex return MultiIndex.from_tuples( - data, names=name or kwargs.get("names") + data, names=names or name ) # other iterable of some kind subarr = com.asarray_tuplesafe(data, dtype=object) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index d1ed79118d2fa..b5001cc2ea8a9 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -371,6 +371,29 @@ def test_constructor_simple_new(self, vals, dtype): result = index._simple_new(index.values, dtype) tm.assert_index_equal(result, index) + def test_constructor_names(self): + # test both `name` and `names` + with pytest.raises(TypeError): + idx = Index([1, 2, 3], name='a', names=('a',)) + + # test non-list-like `names` + with pytest.raises(TypeError): + idx = Index([1, 2, 3], names='a') + + # test list-like with length > 1 + with pytest.raises(TypeError): + idx = Index([1, 2, 3], names=('a', 'b')) + + # test using `name` for a flat `Index` + idx = Index([1, 2, 3], name='a') + assert idx.name == 'a' + assert idx.names == ('a',) + + # test using `names` for a flat `Index` + idx = Index([1, 2, 3], names=('a',)) + assert idx.name == 'a' + assert idx.names == ('a',) + @pytest.mark.parametrize( "vals", [ From 9100b36b17c723b50ea54972e891e98595a5ba9d Mon Sep 17 00:00:00 2001 From: Pedro Cunial Date: Tue, 20 Aug 2019 08:16:31 -0300 Subject: [PATCH 2/4] black pandas --- pandas/core/indexes/base.py | 4 +--- pandas/tests/indexes/test_base.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index a816b448b60f6..487c736b0c391 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -504,9 +504,7 @@ def __new__( # 10697 from .multi import MultiIndex - return MultiIndex.from_tuples( - data, names=names or name - ) + return MultiIndex.from_tuples(data, names=names or name) # other iterable of some kind subarr = com.asarray_tuplesafe(data, dtype=object) return Index(subarr, dtype=dtype, copy=copy, name=name, **kwargs) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index b5001cc2ea8a9..93e5fb332f534 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -374,25 +374,25 @@ def test_constructor_simple_new(self, vals, dtype): def test_constructor_names(self): # test both `name` and `names` with pytest.raises(TypeError): - idx = Index([1, 2, 3], name='a', names=('a',)) + idx = Index([1, 2, 3], name="a", names=("a",)) # test non-list-like `names` with pytest.raises(TypeError): - idx = Index([1, 2, 3], names='a') + idx = Index([1, 2, 3], names="a") # test list-like with length > 1 with pytest.raises(TypeError): - idx = Index([1, 2, 3], names=('a', 'b')) + idx = Index([1, 2, 3], names=("a", "b")) # test using `name` for a flat `Index` - idx = Index([1, 2, 3], name='a') - assert idx.name == 'a' - assert idx.names == ('a',) + idx = Index([1, 2, 3], name="a") + assert idx.name == "a" + assert idx.names == ("a",) # test using `names` for a flat `Index` - idx = Index([1, 2, 3], names=('a',)) - assert idx.name == 'a' - assert idx.names == ('a',) + idx = Index([1, 2, 3], names=("a",)) + assert idx.name == "a" + assert idx.names == ("a",) @pytest.mark.parametrize( "vals", From 326c4991e2dcca6a2b018d98b80cbfc048e66758 Mon Sep 17 00:00:00 2001 From: Pedro Cunial Date: Thu, 22 Aug 2019 07:48:03 -0300 Subject: [PATCH 3/4] fixed docstring style --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 487c736b0c391..c9b310564711a 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -178,7 +178,7 @@ class Index(IndexOpsMixin, PandasObject): Make a copy of input ndarray name : object, optional Name to be stored in the index - names: tuple of objects, optional + names : tuple of objects, optional Names to be stored in the index (only accepts tuple of length 1) tupleize_cols : bool (default: True) When True, attempt to create a MultiIndex if possible From b8bae6afc76bac9f5909404b3b33c8cc7600621b Mon Sep 17 00:00:00 2001 From: Pedro Cunial Date: Tue, 27 Aug 2019 09:01:09 -0300 Subject: [PATCH 4/4] small fixes as suggested by @willayd --- pandas/core/indexes/base.py | 8 +++----- pandas/tests/indexes/test_base.py | 4 ---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c9b310564711a..69c89635cc828 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -178,10 +178,10 @@ class Index(IndexOpsMixin, PandasObject): Make a copy of input ndarray name : object, optional Name to be stored in the index - names : tuple of objects, optional - Names to be stored in the index (only accepts tuple of length 1) tupleize_cols : bool (default: True) When True, attempt to create a MultiIndex if possible + names : tuple of objects, optional + Names to be stored in the index (only accepts tuple of length 1) See Also -------- @@ -261,17 +261,15 @@ def __new__( dtype=None, copy=False, name=None, - names=None, fastpath=None, tupleize_cols=True, + names=None, **kwargs ): if names is not None: if name is not None: raise TypeError("Using name and names is unsupported") - elif names is not None and not is_list_like(names): - raise TypeError("names must be list-like") elif len(names) > 1: raise TypeError("names must be list-like of size 1") # infer name from names when MultiIndex cannot be created diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 93e5fb332f534..d116b45e20121 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -376,10 +376,6 @@ def test_constructor_names(self): with pytest.raises(TypeError): idx = Index([1, 2, 3], name="a", names=("a",)) - # test non-list-like `names` - with pytest.raises(TypeError): - idx = Index([1, 2, 3], names="a") - # test list-like with length > 1 with pytest.raises(TypeError): idx = Index([1, 2, 3], names=("a", "b"))