1"""
2The config module holds package-wide configurables and provides
3a uniform API for working with them.
4
5Overview
6========
7
8This module supports the following requirements:
9- options are referenced using keys in dot.notation, e.g. "x.y.option - z".
10- keys are case-insensitive.
11- functions should accept partial/regex keys, when unambiguous.
12- options can be registered by modules at import time.
13- options can be registered at init-time (via core.config_init)
14- options have a default value, and (optionally) a description and
15 validation function associated with them.
16- options can be deprecated, in which case referencing them
17 should produce a warning.
18- deprecated options can optionally be rerouted to a replacement
19 so that accessing a deprecated option reroutes to a differently
20 named option.
21- options can be reset to their default value.
22- all option can be reset to their default value at once.
23- all options in a certain sub - namespace can be reset at once.
24- the user can set / get / reset or ask for the description of an option.
25- a developer can register and mark an option as deprecated.
26- you can register a callback to be invoked when the option value
27 is set or reset. Changing the stored value is considered misuse, but
28 is not verboten.
29
30Implementation
31==============
32
33- Data is stored using nested dictionaries, and should be accessed
34 through the provided API.
35
36- "Registered options" and "Deprecated options" have metadata associated
37 with them, which are stored in auxiliary dictionaries keyed on the
38 fully-qualified key, e.g. "x.y.z.option".
39
40- the config_init module is imported by the package's __init__.py file.
41 placing any register_option() calls there will ensure those options
42 are available as soon as pandas is loaded. If you use register_option
43 in a module, it will only be available after that module is imported,
44 which you should be aware of.
45
46- `config_prefix` is a context_manager (for use with the `with` keyword)
47 which can save developers some typing, see the docstring.
48
49"""
50
51from __future__ import annotations
52
53from contextlib import contextmanager
54import re
55from typing import (
56 TYPE_CHECKING,
57 Any,
58 NamedTuple,
59 cast,
60)
61import warnings
62
63from pandas._typing import F
64from pandas.util._exceptions import find_stack_level
65
66if TYPE_CHECKING:
67 from collections.abc import (
68 Callable,
69 Generator,
70 Sequence,
71 )
72
73
74class DeprecatedOption(NamedTuple):
75 key: str
76 category: type[Warning]
77 msg: str | None
78 rkey: str | None
79 removal_ver: str | None
80
81
82class RegisteredOption(NamedTuple):
83 key: str
84 defval: Any
85 doc: str
86 validator: Callable[[object], Any] | None
87 cb: Callable[[str], Any] | None
88
89
90# holds deprecated option metadata
91_deprecated_options: dict[str, DeprecatedOption] = {}
92
93# holds registered option metadata
94_registered_options: dict[str, RegisteredOption] = {}
95
96# holds the current values for registered options
97_global_config: dict[str, Any] = {}
98
99# keys which have a special meaning
100_reserved_keys: list[str] = ["all"]
101
102
103class OptionError(AttributeError, KeyError):
104 """
105 Exception raised for pandas.options.
106
107 Backwards compatible with KeyError checks.
108
109 See Also
110 --------
111 options : Access and modify global pandas settings.
112
113 Examples
114 --------
115 >>> pd.options.context
116 Traceback (most recent call last):
117 OptionError: No such option
118 """
119
120 __module__ = "pandas.errors"
121
122
123#
124# User API
125
126
127def _get_single_key(pat: str) -> str:
128 keys = _select_options(pat)
129 if len(keys) == 0:
130 _warn_if_deprecated(pat)
131 raise OptionError(f"No such keys(s): {pat!r}")
132 if len(keys) > 1:
133 raise OptionError("Pattern matched multiple keys")
134 key = keys[0]
135
136 _warn_if_deprecated(key)
137
138 key = _translate_key(key)
139
140 return key
141
142
143def get_option(pat: str) -> Any:
144 """
145 Retrieve the value of the specified option.
146
147 This method allows users to query the current value of a given option
148 in the pandas configuration system. Options control various display,
149 performance, and behavior-related settings within pandas.
150
151 Parameters
152 ----------
153 pat : str
154 Regexp which should match a single option.
155
156 .. warning::
157
158 Partial matches are supported for convenience, but unless you use the
159 full option name (e.g. x.y.z.option_name), your code may break in future
160 versions if new options with similar names are introduced.
161
162 Returns
163 -------
164 Any
165 The value of the option.
166
167 Raises
168 ------
169 OptionError : if no such option exists
170
171 See Also
172 --------
173 set_option : Set the value of the specified option or options.
174 reset_option : Reset one or more options to their default value.
175 describe_option : Print the description for one or more registered options.
176
177 Notes
178 -----
179 For all available options, please view the :ref:`User Guide <options.available>`
180 or use ``pandas.describe_option()``.
181
182 Examples
183 --------
184 >>> pd.get_option("display.max_columns") # doctest: +SKIP
185 4
186 """
187 key = _get_single_key(pat)
188
189 # walk the nested dict
190 root, k = _get_root(key)
191 return root[k]
192
193
194def set_option(*args) -> None:
195 """
196 Set the value of the specified option or options.
197
198 This method allows fine-grained control over the behavior and display settings
199 of pandas. Options affect various functionalities such as output formatting,
200 display limits, and operational behavior. Settings can be modified at runtime
201 without requiring changes to global configurations or environment variables.
202
203 Parameters
204 ----------
205 *args : str | object | dict
206 Arguments provided in pairs, which will be interpreted as (pattern, value),
207 or as a single dictionary containing multiple option-value pairs.
208 pattern: str
209 Regexp which should match a single option
210 value: object
211 New value of option
212
213 .. warning::
214
215 Partial pattern matches are supported for convenience, but unless you
216 use the full option name (e.g. x.y.z.option_name), your code may break in
217 future versions if new options with similar names are introduced.
218
219 Returns
220 -------
221 None
222 No return value.
223
224 Raises
225 ------
226 ValueError if odd numbers of non-keyword arguments are provided
227 TypeError if keyword arguments are provided
228 OptionError if no such option exists
229
230 See Also
231 --------
232 get_option : Retrieve the value of the specified option.
233 reset_option : Reset one or more options to their default value.
234 describe_option : Print the description for one or more registered options.
235 option_context : Context manager to temporarily set options in a ``with``
236 statement.
237
238 Notes
239 -----
240 For all available options, please view the :ref:`User Guide <options.available>`
241 or use ``pandas.describe_option()``.
242
243 Examples
244 --------
245 Option-Value Pair Input:
246
247 >>> pd.set_option("display.max_columns", 4)
248 >>> df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
249 >>> df
250 0 1 ... 3 4
251 0 1 2 ... 4 5
252 1 6 7 ... 9 10
253 [2 rows x 5 columns]
254 >>> pd.reset_option("display.max_columns")
255
256 Dictionary Input:
257
258 >>> pd.set_option({"display.max_columns": 4, "display.precision": 1})
259 >>> df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
260 >>> df
261 0 1 ... 3 4
262 0 1 2 ... 4 5
263 1 6 7 ... 9 10
264 [2 rows x 5 columns]
265 >>> pd.reset_option("display.max_columns")
266 >>> pd.reset_option("display.precision")
267 """
268 # Handle dictionary input
269 if len(args) == 1 and isinstance(args[0], dict):
270 args = tuple(kv for item in args[0].items() for kv in item)
271
272 nargs = len(args)
273 if not nargs or nargs % 2 != 0:
274 raise ValueError("Must provide an even number of non-keyword arguments")
275
276 for k, v in zip(args[::2], args[1::2], strict=True):
277 key = _get_single_key(k)
278
279 opt = _get_registered_option(key)
280 if opt and opt.validator:
281 opt.validator(v)
282
283 # walk the nested dict
284 root, k_root = _get_root(key)
285 root[k_root] = v
286
287 if opt.cb:
288 opt.cb(key)
289
290
291def describe_option(pat: str = "", _print_desc: bool = True) -> str | None:
292 """
293 Print the description for one or more registered options.
294
295 Call with no arguments to get a listing for all registered options.
296
297 Parameters
298 ----------
299 pat : str, default ""
300 String or string regexp pattern.
301 Empty string will return all options.
302 For regexp strings, all matching keys will have their description displayed.
303 _print_desc : bool, default True
304 If True (default) the description(s) will be printed to stdout.
305 Otherwise, the description(s) will be returned as a string
306 (for testing).
307
308 Returns
309 -------
310 None
311 If ``_print_desc=True``.
312 str
313 If the description(s) as a string if ``_print_desc=False``.
314
315 See Also
316 --------
317 get_option : Retrieve the value of the specified option.
318 set_option : Set the value of the specified option or options.
319 reset_option : Reset one or more options to their default value.
320
321 Notes
322 -----
323 For all available options, please view the
324 :ref:`User Guide <options.available>`.
325
326 Examples
327 --------
328 >>> pd.describe_option("display.max_columns") # doctest: +SKIP
329 display.max_columns : int
330 If max_cols is exceeded, switch to truncate view...
331 """
332 keys = _select_options(pat)
333 if len(keys) == 0:
334 raise OptionError(f"No such keys(s) for {pat=}")
335
336 s = "\n".join([_build_option_description(k) for k in keys])
337
338 if _print_desc:
339 print(s)
340 return None
341 return s
342
343
344def reset_option(pat: str) -> None:
345 """
346 Reset one or more options to their default value.
347
348 This method resets the specified pandas option(s) back to their default
349 values. It allows partial string matching for convenience, but users should
350 exercise caution to avoid unintended resets due to changes in option names
351 in future versions.
352
353 Parameters
354 ----------
355 pat : str/regex
356 If specified only options matching ``pat*`` will be reset.
357 Pass ``"all"`` as argument to reset all options.
358
359 .. warning::
360
361 Partial matches are supported for convenience, but unless you
362 use the full option name (e.g. x.y.z.option_name), your code may break
363 in future versions if new options with similar names are introduced.
364
365 Returns
366 -------
367 None
368 No return value.
369
370 See Also
371 --------
372 get_option : Retrieve the value of the specified option.
373 set_option : Set the value of the specified option or options.
374 describe_option : Print the description for one or more registered options.
375
376 Notes
377 -----
378 For all available options, please view the
379 :ref:`User Guide <options.available>`.
380
381 Examples
382 --------
383 >>> pd.reset_option("display.max_columns") # doctest: +SKIP
384 """
385 keys = _select_options(pat)
386
387 if len(keys) == 0:
388 raise OptionError(f"No such keys(s) for {pat=}")
389
390 if len(keys) > 1 and len(pat) < 4 and pat != "all":
391 raise ValueError(
392 "You must specify at least 4 characters when "
393 "resetting multiple keys, use the special keyword "
394 '"all" to reset all the options to their default value'
395 )
396
397 for k in keys:
398 set_option(k, _registered_options[k].defval)
399
400
401def get_default_val(pat: str):
402 key = _get_single_key(pat)
403 return _get_registered_option(key).defval
404
405
406class DictWrapper:
407 """provide attribute-style access to a nested dict"""
408
409 d: dict[str, Any]
410
411 def __init__(self, d: dict[str, Any], prefix: str = "") -> None:
412 object.__setattr__(self, "d", d)
413 object.__setattr__(self, "prefix", prefix)
414
415 def __setattr__(self, key: str, val: Any) -> None:
416 prefix = object.__getattribute__(self, "prefix")
417 if prefix:
418 prefix += "."
419 prefix += key
420 # you can't set new keys
421 # can you can't overwrite subtrees
422 if key in self.d and not isinstance(self.d[key], dict):
423 set_option(prefix, val)
424 else:
425 raise OptionError("You can only set the value of existing options")
426
427 def __getattr__(self, key: str):
428 prefix = object.__getattribute__(self, "prefix")
429 if prefix:
430 prefix += "."
431 prefix += key
432 try:
433 v = object.__getattribute__(self, "d")[key]
434 except KeyError as err:
435 raise OptionError("No such option") from err
436 if isinstance(v, dict):
437 return DictWrapper(v, prefix)
438 else:
439 return get_option(prefix)
440
441 def __dir__(self) -> list[str]:
442 return list(self.d.keys())
443
444
445options = DictWrapper(_global_config)
446# DictWrapper defines a custom setattr
447object.__setattr__(options, "__module__", "pandas")
448
449#
450# Functions for use by pandas developers, in addition to User - api
451
452
453@contextmanager
454def option_context(*args) -> Generator[None]:
455 """
456 Context manager to temporarily set options in a ``with`` statement.
457
458 This method allows users to set one or more pandas options temporarily
459 within a controlled block. The previous options' values are restored
460 once the block is exited. This is useful when making temporary adjustments
461 to pandas' behavior without affecting the global state.
462
463 Parameters
464 ----------
465 *args : str | object | dict
466 An even amount of arguments provided in pairs which will be
467 interpreted as (pattern, value) pairs. Alternatively, a single
468 dictionary of {pattern: value} may be provided.
469
470 Returns
471 -------
472 None
473 No return value.
474
475 Yields
476 ------
477 None
478 No yield value.
479
480 See Also
481 --------
482 get_option : Retrieve the value of the specified option.
483 set_option : Set the value of the specified option.
484 reset_option : Reset one or more options to their default value.
485 describe_option : Print the description for one or more registered options.
486
487 Notes
488 -----
489 For all available options, please view the :ref:`User Guide <options.available>`
490 or use ``pandas.describe_option()``.
491
492 Examples
493 --------
494 >>> from pandas import option_context
495 >>> with option_context("display.max_rows", 10, "display.max_columns", 5):
496 ... pass
497 >>> with option_context({"display.max_rows": 10, "display.max_columns": 5}):
498 ... pass
499 """
500 if len(args) == 1 and isinstance(args[0], dict):
501 args = tuple(kv for item in args[0].items() for kv in item)
502
503 if len(args) % 2 != 0 or len(args) < 2:
504 raise ValueError(
505 "Provide an even amount of arguments as "
506 "option_context(pat, val, pat, val...)."
507 )
508
509 ops = tuple(zip(args[::2], args[1::2], strict=True))
510 undo: tuple[tuple[Any, Any], ...] = ()
511 try:
512 undo = tuple((pat, get_option(pat)) for pat, val in ops)
513 for pat, val in ops:
514 set_option(pat, val)
515 yield
516 finally:
517 for pat, val in undo:
518 set_option(pat, val)
519
520
521def register_option(
522 key: str,
523 defval: object,
524 doc: str = "",
525 validator: Callable[[object], Any] | None = None,
526 cb: Callable[[str], Any] | None = None,
527) -> None:
528 """
529 Register an option in the package-wide pandas config object
530
531 Parameters
532 ----------
533 key : str
534 Fully-qualified key, e.g. "x.y.option - z".
535 defval : object
536 Default value of the option.
537 doc : str
538 Description of the option.
539 validator : Callable, optional
540 Function of a single argument, should raise `ValueError` if
541 called with a value which is not a legal value for the option.
542 cb
543 a function of a single argument "key", which is called
544 immediately after an option value is set/reset. key is
545 the full name of the option.
546
547 Raises
548 ------
549 ValueError if `validator` is specified and `defval` is not a valid value.
550
551 """
552 import keyword
553 import tokenize
554
555 key = key.lower()
556
557 if key in _registered_options:
558 raise OptionError(f"Option '{key}' has already been registered")
559 if key in _reserved_keys:
560 raise OptionError(f"Option '{key}' is a reserved key")
561
562 # the default value should be legal
563 if validator:
564 validator(defval)
565
566 # walk the nested dict, creating dicts as needed along the path
567 path = key.split(".")
568
569 for k in path:
570 if not re.match("^" + tokenize.Name + "$", k):
571 raise ValueError(f"{k} is not a valid identifier")
572 if keyword.iskeyword(k):
573 raise ValueError(f"{k} is a python keyword")
574
575 cursor = _global_config
576 msg = "Path prefix to option '{option}' is already an option"
577
578 for i, p in enumerate(path[:-1]):
579 if not isinstance(cursor, dict):
580 raise OptionError(msg.format(option=".".join(path[:i])))
581 if p not in cursor:
582 cursor[p] = {}
583 cursor = cursor[p]
584
585 if not isinstance(cursor, dict):
586 raise OptionError(msg.format(option=".".join(path[:-1])))
587
588 cursor[path[-1]] = defval # initialize
589
590 # save the option metadata
591 _registered_options[key] = RegisteredOption(
592 key=key, defval=defval, doc=doc, validator=validator, cb=cb
593 )
594
595
596def deprecate_option(
597 key: str,
598 category: type[Warning],
599 msg: str | None = None,
600 rkey: str | None = None,
601 removal_ver: str | None = None,
602) -> None:
603 """
604 Mark option `key` as deprecated, if code attempts to access this option,
605 a warning will be produced, using `msg` if given, or a default message
606 if not.
607 if `rkey` is given, any access to the key will be re-routed to `rkey`.
608
609 Neither the existence of `key` nor that if `rkey` is checked. If they
610 do not exist, any subsequence access will fail as usual, after the
611 deprecation warning is given.
612
613 Parameters
614 ----------
615 key : str
616 Name of the option to be deprecated.
617 must be a fully-qualified option name (e.g "x.y.z.rkey").
618 category : Warning
619 Warning class for the deprecation.
620 msg : str, optional
621 Warning message to output when the key is referenced.
622 if no message is given a default message will be emitted.
623 rkey : str, optional
624 Name of an option to reroute access to.
625 If specified, any referenced `key` will be
626 re-routed to `rkey` including set/get/reset.
627 rkey must be a fully-qualified option name (e.g "x.y.z.rkey").
628 used by the default message if no `msg` is specified.
629 removal_ver : str, optional
630 Specifies the version in which this option will
631 be removed. used by the default message if no `msg` is specified.
632
633 Raises
634 ------
635 OptionError
636 If the specified key has already been deprecated.
637 """
638 key = key.lower()
639
640 if key in _deprecated_options:
641 raise OptionError(f"Option '{key}' has already been defined as deprecated.")
642
643 _deprecated_options[key] = DeprecatedOption(key, category, msg, rkey, removal_ver)
644
645
646#
647# functions internal to the module
648
649
650def _select_options(pat: str) -> list[str]:
651 """
652 returns a list of keys matching `pat`
653
654 if pat=="all", returns all registered options
655 """
656 # short-circuit for exact key
657 if pat in _registered_options:
658 return [pat]
659
660 # else look through all of them
661 keys = sorted(_registered_options.keys())
662 if pat == "all": # reserved key
663 return keys
664
665 return [k for k in keys if re.search(pat, k, re.I)]
666
667
668def _get_root(key: str) -> tuple[dict[str, Any], str]:
669 path = key.split(".")
670 cursor = _global_config
671 for p in path[:-1]:
672 cursor = cursor[p]
673 return cursor, path[-1]
674
675
676def _get_deprecated_option(key: str):
677 """
678 Retrieves the metadata for a deprecated option, if `key` is deprecated.
679
680 Returns
681 -------
682 DeprecatedOption (namedtuple) if key is deprecated, None otherwise
683 """
684 try:
685 d = _deprecated_options[key]
686 except KeyError:
687 return None
688 else:
689 return d
690
691
692def _get_registered_option(key: str):
693 """
694 Retrieves the option metadata if `key` is a registered option.
695
696 Returns
697 -------
698 RegisteredOption (namedtuple) if key is deprecated, None otherwise
699 """
700 return _registered_options.get(key)
701
702
703def _translate_key(key: str) -> str:
704 """
705 if `key` is deprecated and a replacement key defined, will return the
706 replacement key, otherwise returns `key` as-is
707 """
708 d = _get_deprecated_option(key)
709 if d:
710 return d.rkey or key
711 else:
712 return key
713
714
715def _warn_if_deprecated(key: str) -> bool:
716 """
717 Checks if `key` is a deprecated option and if so, prints a warning.
718
719 Returns
720 -------
721 bool - True if `key` is deprecated, False otherwise.
722 """
723 d = _get_deprecated_option(key)
724 if d:
725 if d.msg:
726 warnings.warn(
727 d.msg,
728 d.category,
729 stacklevel=find_stack_level(),
730 )
731 else:
732 msg = f"'{key}' is deprecated"
733 if d.removal_ver:
734 msg += f" and will be removed in {d.removal_ver}"
735 if d.rkey:
736 msg += f", please use '{d.rkey}' instead."
737 else:
738 msg += ", please refrain from using it."
739
740 warnings.warn(
741 msg,
742 d.category,
743 stacklevel=find_stack_level(),
744 )
745 return True
746 return False
747
748
749def _build_option_description(k: str) -> str:
750 """Builds a formatted description of a registered option and prints it"""
751 o = _get_registered_option(k)
752 d = _get_deprecated_option(k)
753
754 s = f"{k} "
755
756 if o.doc:
757 s += "\n".join(o.doc.strip().split("\n"))
758 else:
759 s += "No description available."
760
761 if o:
762 with warnings.catch_warnings():
763 warnings.simplefilter("ignore", FutureWarning)
764 warnings.simplefilter("ignore", DeprecationWarning)
765 s += f"\n [default: {o.defval}] [currently: {get_option(k)}]"
766
767 if d:
768 rkey = d.rkey or ""
769 s += "\n (Deprecated"
770 s += f", use `{rkey}` instead."
771 s += ")"
772
773 return s
774
775
776# helpers
777
778
779@contextmanager
780def config_prefix(prefix: str) -> Generator[None]:
781 """
782 contextmanager for multiple invocations of API with a common prefix
783
784 supported API functions: (register / get / set )__option
785
786 Warning: This is not thread - safe, and won't work properly if you import
787 the API functions into your module using the "from x import y" construct.
788
789 Example
790 -------
791 import pandas._config.config as cf
792 with cf.config_prefix("display.font"):
793 cf.register_option("color", "red")
794 cf.register_option("size", " 5 pt")
795 cf.set_option(size, " 6 pt")
796 cf.get_option(size)
797 ...
798
799 etc'
800
801 will register options "display.font.color", "display.font.size", set the
802 value of "display.font.size"... and so on.
803 """
804 # Note: reset_option relies on set_option, and on key directly
805 # it does not fit in to this monkey-patching scheme
806
807 global register_option, get_option, set_option
808
809 def wrap(func: F) -> F:
810 def inner(key: str, *args, **kwds):
811 pkey = f"{prefix}.{key}"
812 return func(pkey, *args, **kwds)
813
814 return cast(F, inner)
815
816 _register_option = register_option
817 _get_option = get_option
818 _set_option = set_option
819 set_option = wrap(set_option)
820 get_option = wrap(get_option)
821 register_option = wrap(register_option)
822 try:
823 yield
824 finally:
825 set_option = _set_option
826 get_option = _get_option
827 register_option = _register_option
828
829
830# These factories and methods are handy for use as the validator
831# arg in register_option
832
833
834def is_type_factory(_type: type[Any]) -> Callable[[Any], None]:
835 """
836
837 Parameters
838 ----------
839 `_type` - a type to be compared against (e.g. type(x) == `_type`)
840
841 Returns
842 -------
843 validator - a function of a single argument x , which raises
844 ValueError if type(x) is not equal to `_type`
845
846 """
847
848 def inner(x) -> None:
849 if type(x) != _type:
850 raise ValueError(f"Value must have type '{_type}'")
851
852 return inner
853
854
855def is_instance_factory(_type: type | tuple[type, ...]) -> Callable[[Any], None]:
856 """
857
858 Parameters
859 ----------
860 `_type` - the type to be checked against
861
862 Returns
863 -------
864 validator - a function of a single argument x , which raises
865 ValueError if x is not an instance of `_type`
866
867 """
868 if isinstance(_type, tuple):
869 type_repr = "|".join(map(str, _type))
870 else:
871 type_repr = f"'{_type}'"
872
873 def inner(x) -> None:
874 if not isinstance(x, _type):
875 raise ValueError(f"Value must be an instance of {type_repr}")
876
877 return inner
878
879
880def is_one_of_factory(legal_values: Sequence) -> Callable[[Any], None]:
881 callables = [c for c in legal_values if callable(c)]
882 legal_values = [c for c in legal_values if not callable(c)]
883
884 def inner(x) -> None:
885 if x not in legal_values:
886 if not any(c(x) for c in callables):
887 uvals = [str(lval) for lval in legal_values]
888 pp_values = "|".join(uvals)
889 msg = f"Value must be one of {pp_values}"
890 if len(callables):
891 msg += " or a callable"
892 raise ValueError(msg)
893
894 return inner
895
896
897def is_nonnegative_int(value: object) -> None:
898 """
899 Verify that value is None or a positive int.
900
901 Parameters
902 ----------
903 value : None or int
904 The `value` to be checked.
905
906 Raises
907 ------
908 ValueError
909 When the value is not None or is a negative integer
910 """
911 if value is None:
912 return
913
914 elif isinstance(value, int):
915 if value >= 0:
916 return
917
918 msg = "Value must be a nonnegative integer or None"
919 raise ValueError(msg)
920
921
922# common type validators, for convenience
923# usage: register_option(... , validator = is_int)
924is_int = is_type_factory(int)
925is_bool = is_type_factory(bool)
926is_float = is_type_factory(float)
927is_str = is_type_factory(str)
928is_text = is_instance_factory((str, bytes))
929
930
931def is_callable(obj: object) -> bool:
932 """
933
934 Parameters
935 ----------
936 `obj` - the object to be checked
937
938 Returns
939 -------
940 validator - returns True if object is callable
941 raises ValueError otherwise.
942
943 """
944 if not callable(obj):
945 raise ValueError("Value must be a callable")
946 return True
947
948
949# import set_module here would cause circular import
950get_option.__module__ = "pandas"
951set_option.__module__ = "pandas"
952describe_option.__module__ = "pandas"
953reset_option.__module__ = "pandas"
954option_context.__module__ = "pandas"