Skip to content
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

TST: add tests for keeping dtype in Series.update #23604

Merged
merged 19 commits into from
Nov 20, 2018
Merged
Changes from 1 commit
Commits
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
41 changes: 18 additions & 23 deletions pandas/tests/series/test_combine_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,33 +121,28 @@ def test_update(self):
columns=['a', 'b', 'c'])
assert_frame_equal(df, expected)

def test_update_dtypes(self):
s = Series([1., 2., False, True])
other = Series([45], index=[0])
@pytest.mark.parametrize('other_values', [
[61, 63], # int
[61., 63.], # float, but can be cast to int
[61.1, 63.1], # float, cannot be cast to int
[(61,), (63,)] # object
], ids=['int', 'float_castable', 'float', 'object'])
@pytest.mark.parametrize('caller_dtype', ['int', 'float', object])
def test_update_dtypes(self, caller_dtype, other_values):
caller_values = [10, 11, 12]
s = Series(caller_values, dtype=caller_dtype)
other = Series(other_values, index=[1, 3])
s.update(other)

expected = Series([45., 2., False, True])
expected_values = [caller_values[0], other_values[0], caller_values[2]]
try:
# we keep original dtype whenever possible
Copy link
Contributor

Choose a reason for hiding this comment

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

pls don't use a try except inside the test itself. you should explicity use pytest.raises if you want to catch an exception

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 know, but this is fully intended (I've made the same argument to @gfyoung in a conversation he marked "resolved" below).

The thing is that Series.update will maintain the dtype of the caller as much as it can. This means, when calling from an int Series, floats get cast to int, if possible. Only if that doesn't work, is the dtype changed to whatever the updated values require.

If I were to pass expected results through the parametrization, I wouldn't be able to parametrize separately, and would therefore need 12 expected results. This is neither easy to read nor extensible.

Please have another look at this test, I think it's quite clear that the try-catch is not about skipping, but about different expected values (which I explained with the comment).

expected = Series(expected_values, dtype=caller_dtype)
except ValueError:
expected = Series(expected_values)
gfyoung marked this conversation as resolved.
Show resolved Hide resolved
print(s, expected)
gfyoung marked this conversation as resolved.
Show resolved Hide resolved
assert_series_equal(s, expected)

s = Series([10, 11, 12])
s_copy = s.copy()
other = Series([61, 63], index=[1, 3])
s_copy.update(other)

expected = Series([10, 61, 12])
assert_series_equal(s_copy, expected)

# we always try to keep original dtype, even if other has different one
s_copy = s.copy()
s_copy.update(other.astype(float))
assert_series_equal(s_copy, expected)

# if keeping the dtype is not possible, we allow upcasting
s_copy = s.copy()
s_copy.update(other + 0.1)
expected = Series([10., 61.1, 12.])
assert_series_equal(s_copy, expected)

def test_concat_empty_series_dtypes_roundtrips(self):

# round-tripping with self & like self
Expand Down