Skip to content

Commit 086a824

Browse files
committed
BUG: Validate float_format setting as callable or None
The `float_format` setting takes either None or a callable object that returns a formatted string given a float value. Currently, the setting isn't validated, so cryptic error messages are returned if, for example, a format non-callable format string is given (see \pandas-dev#12704). Add a standard validation method and use it to validate the `float_format` setting.
1 parent 4e7974a commit 086a824

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

doc/source/whatsnew/v0.18.1.txt

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ Bug Fixes
124124
- Bug in numpy compatibility of ``np.round()`` on a ``Series`` (:issue:`12600`)
125125
- Bug in ``Series`` construction with ``Categorical`` and ``dtype='category'`` is specified (:issue:`12574`)
126126
- Bugs in concatenation with a coercable dtype was too aggressive. (:issue:`12411`, :issue:`12045`, :issue:`11594`, :issue:`10571`)
127+
- Bug in ``float_format`` option with option not being validated as callable. (:issue:`12706`)
127128

128129

129130

pandas/core/config.py

+18
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,21 @@ def inner(x):
803803
is_str = is_type_factory(str)
804804
is_unicode = is_type_factory(compat.text_type)
805805
is_text = is_instance_factory((str, bytes))
806+
807+
808+
def is_callable_or_none(obj):
809+
"""
810+
811+
Parameters
812+
----------
813+
`obj` - the object to be checked
814+
815+
Returns
816+
-------
817+
validator - returns True if object is callable or None, and
818+
raises ValueError otherwise.
819+
820+
"""
821+
if not (callable(obj) or obj is None):
822+
raise ValueError("Value must be an callable or None")
823+
return True

pandas/core/config_init.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
import pandas.core.config as cf
1515
from pandas.core.config import (is_int, is_bool, is_text, is_instance_factory,
16-
is_one_of_factory, get_default_val)
16+
is_one_of_factory, get_default_val,
17+
is_callable_or_none)
1718
from pandas.core.format import detect_console_encoding
1819

1920
#
@@ -279,7 +280,8 @@ def mpl_style_cb(key):
279280

280281
with cf.config_prefix('display'):
281282
cf.register_option('precision', 6, pc_precision_doc, validator=is_int)
282-
cf.register_option('float_format', None, float_format_doc)
283+
cf.register_option('float_format', None, float_format_doc,
284+
validator=is_callable_or_none)
283285
cf.register_option('column_space', 12, validator=is_int)
284286
cf.register_option('max_info_rows', 1690785, pc_max_info_rows_doc,
285287
validator=is_instance_factory((int, type(None))))

pandas/tests/test_config.py

+6
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ def test_validation(self):
206206
self.assertRaises(ValueError, self.cf.set_option, 'a', 'ab')
207207
self.assertRaises(ValueError, self.cf.set_option, 'b.c', 1)
208208

209+
self.cf.register_option('b', lambda: None, 'doc',
210+
validator=self.cf.is_callable_or_none)
211+
self.cf.set_option('b', '%.1f'.format) # Formatter is callable
212+
self.cf.set_option('b', None) # Formatter is none (default)
213+
self.assertRaises(ValueError, self.cf.set_option, 'b', '%.1f')
214+
209215
def test_reset_option(self):
210216
self.cf.register_option('a', 1, 'doc', validator=self.cf.is_int)
211217
self.cf.register_option('b.c', 'hullo', 'doc2',

0 commit comments

Comments
 (0)