Skip to content

BUG: Add type check for width parameter in str.pad method GH13598 #13690

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,4 @@ Bug Fixes
- Bug in ``groupby`` with ``as_index=False`` returns all NaN's when grouping on multiple columns including a categorical one (:issue:`13204`)

- Bug where ``pd.read_gbq()`` could throw ``ImportError: No module named discovery`` as a result of a naming conflict with another python package called apiclient (:issue:`13454`)
- Bug in ``pandas.Series.str.zfill``, when ``width`` was not of integer type no ``TypeError`` was raised, which resulted in a series with all NaN values (:issue:`13598`)
4 changes: 4 additions & 0 deletions pandas/core/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,10 @@ def str_pad(arr, width, side='left', fillchar=' '):
if len(fillchar) != 1:
raise TypeError('fillchar must be a character, not str')

if not isinstance(width, compat.integer_types):
msg = 'width must be of integer type, not {0}'
Copy link
Contributor

Choose a reason for hiding this comment

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

use is_integer

raise TypeError(msg.format(type(width).__name__))

if side == 'left':
f = lambda x: x.rjust(width, fillchar)
elif side == 'right':
Expand Down
50 changes: 50 additions & 0 deletions pandas/tests/test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,18 @@ def test_pad_fillchar(self):
"fillchar must be a character, not int"):
result = values.str.pad(5, fillchar=5)

def test_pad_width(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

you can just put them all in a single test method and iterate over the functions asserting that they raise

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'm relatively new to OOP in python, so could you let me know if there's anything I could do to improve my current implementation?
Thanks


values = Series(['1', '22', 'a', 'bb'])

result = values.str.pad(5, side='left', fillchar='0')
expected = Series(['00001', '00022', '0000a', '000bb'])
tm.assert_almost_equal(result, expected)

with tm.assertRaisesRegexp(TypeError,
"width must be of integer type, not*"):
result = values.str.pad('f', fillchar='0')

def test_translate(self):

def _check(result, expected):
Expand Down Expand Up @@ -1745,6 +1757,33 @@ def test_center_ljust_rjust_fillchar(self):
"fillchar must be a character, not int"):
result = values.str.rjust(5, fillchar=1)

def test_center_ljust_rjust_width(self):
values = Series(['a', 'bb', 'ccc', NA, 'eeeee'])

result = values.str.center(4, fillchar='X')
expected = Series(['XaXX', 'XbbX', 'cccX', NA, 'eeeee'])
tm.assert_almost_equal(result, expected)

result = values.str.ljust(4, fillchar='X')
expected = Series(['aXXX', 'bbXX', 'cccX', NA, 'eeeee'])
tm.assert_almost_equal(result, expected)

result = values.str.rjust(4, fillchar='X')
expected = Series(['XXXa', 'XXbb', 'Xccc', NA, 'eeeee'])
tm.assert_almost_equal(result, expected)

with tm.assertRaisesRegexp(TypeError,
"width must be of integer type, not*"):
result = values.str.center('f', fillchar='X')

with tm.assertRaisesRegexp(TypeError,
"width must be of integer type, not*"):
result = values.str.ljust('f', fillchar='X')

with tm.assertRaisesRegexp(TypeError,
"width must be of integer type, not*"):
result = values.str.rjust('f', fillchar='X')

def test_zfill(self):
values = Series(['1', '22', 'aaa', '333', '45678'])

Expand All @@ -1767,6 +1806,17 @@ def test_zfill(self):
expected = Series(['00001', np.nan, '00aaa', np.nan, '45678'])
tm.assert_series_equal(result, expected)

def test_zfill_width(self):
values = Series(['1', '22', 'ccc', NA, 'eeeee'])

result = values.str.zfill(5)
expected = Series(['00001', '00022', '00ccc', NA, 'eeeee'])
tm.assert_almost_equal(result, expected)

with tm.assertRaisesRegexp(TypeError,
"width must be of integer type, not*"):
result = values.str.zfill('f')

def test_split(self):
values = Series(['a_b_c', 'c_d_e', NA, 'f_g_h'])

Expand Down