Skip to content

ERR: disallow non-hashables in Index/MultiIndex construction & rename #20548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Apr 23, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
9047d60
Check non-hashability on series construction and renaming
arminv Mar 30, 2018
df7650d
Removed changes from pandas/core/series.py
arminv Mar 30, 2018
dd64219
Check non-hashability on Index construction and renaming
arminv Mar 30, 2018
89e92ab
modified test_getitem_list example to disallow non-hashable names
arminv Mar 30, 2018
cd3e53a
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Mar 30, 2018
cd070e3
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 1, 2018
351691f
Changed ErrorType message for hashability requirement
arminv Apr 1, 2018
3a7b0b2
Fixed how rename calls set_names to allow for MultiIndex hashable typ…
arminv Apr 1, 2018
70933d5
Moved type checking from set_names back to rename
arminv Apr 1, 2018
56fd617
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 1, 2018
d4ed636
Moved hashable checking to set_names. Changed exception messages.
arminv Apr 1, 2018
b554bb3
Modified test_duplicate_level_names to pass with new (hashable names)…
arminv Apr 2, 2018
6efd6cc
Added test_constructor_nonhashable_names for checking hashability on …
arminv Apr 2, 2018
4fb3a6b
Fixed a typo
arminv Apr 2, 2018
786f43f
Minor refactoring of test_constructor_nonhashable_names
arminv Apr 2, 2018
01b712e
Added test_constructor_nonhashable_name for checking hashability on name
arminv Apr 2, 2018
6f13cd0
Added note in Other API Changes on hashability of names
arminv Apr 2, 2018
26433c3
Improved wording of the note
arminv Apr 2, 2018
91ef466
Addressed PEP 8 issues
arminv Apr 2, 2018
85e35ea
Modified exception message of Index
arminv Apr 2, 2018
5c2e240
Changed exception message format
arminv Apr 2, 2018
4ca2a52
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 2, 2018
840cd88
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 3, 2018
18bcf2a
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 6, 2018
d98014f
Refactoring
arminv Apr 8, 2018
b8a1d7e
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 9, 2018
edfbd1d
Added internal comment
arminv Apr 9, 2018
2322346
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 10, 2018
fa52655
Refactoring
arminv Apr 10, 2018
c0f6936
Moved check from set_names to _set_names
arminv Apr 10, 2018
a9c14e6
test with fixture
jreback Apr 11, 2018
30da596
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 12, 2018
667d495
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 16, 2018
c4c1011
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 16, 2018
bd75433
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 17, 2018
74a9b54
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 17, 2018
b1cb7fd
Refactoring. Internal docstring. Minor typos
arminv Apr 17, 2018
863f7d3
PEP 8
arminv Apr 17, 2018
0723009
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 17, 2018
7092d49
Improved docstring wording
arminv Apr 17, 2018
1d8f67a
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 19, 2018
12488ff
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 20, 2018
4a500ba
Shorten docstring
arminv Apr 21, 2018
9ec64b0
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 21, 2018
47903ae
Merge remote-tracking branch 'upstream/master' into non_hashable_err
arminv Apr 22, 2018
04f2eed
Added examples
arminv Apr 22, 2018
1a68188
remove examples from _set_names
jreback Apr 22, 2018
97a2b06
consolidate logic a bit
jreback Apr 22, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactoring. Internal docstring. Minor typos
  • Loading branch information
arminv committed Apr 17, 2018
commit b1cb7fd1c57036b7e5a3fce2b312175e7f23e0fa
49 changes: 42 additions & 7 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,6 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None,
if name is None and hasattr(data, 'name'):
name = data.name

if name is not None and not is_hashable(name):
raise TypeError('{}.name must be a hashable type'
.format(cls.__name__))

if fastpath:
return cls._simple_new(data, name)

Expand Down Expand Up @@ -478,7 +474,7 @@ def _simple_new(cls, values, name=None, dtype=None, **kwargs):

result = object.__new__(cls)
result._data = values
result.name = name
result._set_names([name])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jreback I wasn't sure if _set_names was getting called from _simple_new, so I made it explicit. Is this ok?

Also, we are not checking in __new__ anymore (as you suggested).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you shouldn't need to do this, and just leave the original code

setting .name name is a property that calls _set_names

for k, v in compat.iteritems(kwargs):
setattr(result, k, v)
return result._reset_identity()
Expand Down Expand Up @@ -1316,6 +1312,45 @@ def _get_names(self):
return FrozenList((self.name, ))

def _set_names(self, values, level=None):
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also add a mention on set_names itself that the names must be hashable (and examples if you want)

Set new names on index.

Parameters
----------
values : str or sequence
name(s) to set
level : int, level name, or sequence of int/level names (default None)
If the index is a MultiIndex (hierarchical), level(s) to set (None
for all levels). Otherwise level must be None

Returns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be Raises (and its a TypeError)

-------
index : Index

See Also
--------
Index.set_names : Set new names on index. Defaults to returning
new index.
Index.rename : Set new names on index. Defaults to returning new index.

Notes
-----
Both `set_names` and `rename` call this function.

Examples
--------
on an index with no names:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need the fulll doc string here (e.g. examples and such, leave Parameters and such), only on .set_names

>>> I1 = Index([1, 2, 3, 4])
>>> I1._set_names([0])
>>> I1
Int64Index([1, 2, 3, 4], dtype='int64', name=0)

set multiple names:
>>> I2 = Index([1, 2, 3, 4], name="foo")
>>> I2._set_names([(0, 1)])
>>> I2
Int64Index([1, 2, 3, 4], dtype='int64', name=(0, 1))
"""
# GH 20527
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a doc-string here

# All items in 'name' need to be hashable:
if values is not None:
Expand Down Expand Up @@ -1351,9 +1386,9 @@ def set_names(self, names, level=None, inplace=False):
Examples
--------
>>> Index([1, 2, 3, 4]).set_names('foo')
Int64Index([1, 2, 3, 4], dtype='int64')
Int64Index([1, 2, 3, 4], dtype='int64', name='foo')
>>> Index([1, 2, 3, 4]).set_names(['foo'])
Int64Index([1, 2, 3, 4], dtype='int64')
Int64Index([1, 2, 3, 4], dtype='int64', name='foo')
>>> idx = MultiIndex.from_tuples([(1, u'one'), (1, u'two'),
(2, u'one'), (2, u'two')],
names=['foo', 'bar'])
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ def test_constructor_nonhashable_name(self, indices):
# GH 20527

if isinstance(indices, MultiIndex):
pytest.skip("multiindex handled in test_multiindex.py")
pytest.skip("multiindex handled in test_multi.py")

name = ['0']
message = "Index.name must be a hashable type"
Expand Down