From 2610ba2753d615a313f325f4b1126d78ec6aaff4 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 6 Jan 2020 13:12:30 +0200 Subject: [PATCH 1/9] TYP: pandas/core/apply.py --- pandas/core/apply.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 14a3c3c008e92..ca1be3154757a 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -1,10 +1,11 @@ import abc import inspect -from typing import TYPE_CHECKING, Any, Dict, Iterator, Tuple, Type, Union +from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional, Tuple, Type, Union import numpy as np from pandas._libs import reduction as libreduction +from pandas._typing import Axis from pandas.util._decorators import cache_readonly from pandas.core.dtypes.common import ( @@ -26,9 +27,9 @@ def frame_apply( obj: "DataFrame", func, - axis=0, + axis: Axis = 0, raw: bool = False, - result_type=None, + result_type: Optional[str] = None, ignore_failures: bool = False, args=None, kwds=None, @@ -87,7 +88,7 @@ def __init__( obj: "DataFrame", func, raw: bool, - result_type, + result_type: Optional[str], ignore_failures: bool, args, kwds, From c399d1d26542a037f3b1d1bccacf541550f4f022 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 6 Jan 2020 13:17:56 +0200 Subject: [PATCH 2/9] TYP: pandas/core/construction.py --- pandas/core/construction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/construction.py b/pandas/core/construction.py index cc8311cf3e21d..695d9d9cb840e 100644 --- a/pandas/core/construction.py +++ b/pandas/core/construction.py @@ -334,7 +334,7 @@ def array( return result -def extract_array(obj, extract_numpy=False): +def extract_array(obj, extract_numpy: bool = False): """ Extract the ndarray or ExtensionArray from a Series or Index. From bcf9d76a13b66c8c49529b42ddf0d344ac4bea79 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 6 Jan 2020 15:06:17 +0200 Subject: [PATCH 3/9] TYP: pandas/_config/config.py --- pandas/_config/config.py | 139 ++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 68 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 0a3009f74492f..d768e6b14afb2 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -51,7 +51,7 @@ from collections import namedtuple from contextlib import contextmanager import re -from typing import Any, Dict, Iterable, List +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple import warnings DeprecatedOption = namedtuple("DeprecatedOption", "key msg rkey removal_ver") @@ -80,7 +80,7 @@ class OptionError(AttributeError, KeyError): # User API -def _get_single_key(pat, silent): +def _get_single_key(pat: str, silent: bool) -> str: keys = _select_options(pat) if len(keys) == 0: if not silent: @@ -98,7 +98,7 @@ def _get_single_key(pat, silent): return key -def _get_option(pat, silent=False): +def _get_option(pat: str, silent: bool = False): key = _get_single_key(pat, silent) # walk the nested dict @@ -106,7 +106,7 @@ def _get_option(pat, silent=False): return root[k] -def _set_option(*args, **kwargs): +def _set_option(*args, **kwargs) -> None: # must at least 1 arg deal with constraints later nargs = len(args) if not nargs or nargs % 2 != 0: @@ -138,7 +138,7 @@ def _set_option(*args, **kwargs): o.cb(key) -def _describe_option(pat="", _print_desc=True): +def _describe_option(pat: str = "", _print_desc: bool = True): keys = _select_options(pat) if len(keys) == 0: @@ -154,7 +154,7 @@ def _describe_option(pat="", _print_desc=True): return s -def _reset_option(pat, silent=False): +def _reset_option(pat: str, silent: bool = False) -> None: keys = _select_options(pat) @@ -173,7 +173,7 @@ def _reset_option(pat, silent=False): _set_option(k, _registered_options[k].defval, silent=silent) -def get_default_val(pat): +def get_default_val(pat: str): key = _get_single_key(pat, silent=True) return _get_registered_option(key).defval @@ -181,11 +181,11 @@ def get_default_val(pat): class DictWrapper: """ provide attribute-style access to a nested dict""" - def __init__(self, d, prefix=""): + def __init__(self, d: Any, prefix: str = ""): object.__setattr__(self, "d", d) object.__setattr__(self, "prefix", prefix) - def __setattr__(self, key, val): + def __setattr__(self, key: str, val: Any) -> None: prefix = object.__getattribute__(self, "prefix") if prefix: prefix += "." @@ -211,7 +211,7 @@ def __getattr__(self, key: str): else: return _get_option(prefix) - def __dir__(self): + def __dir__(self) -> Iterable[str]: return list(self.d.keys()) @@ -412,23 +412,31 @@ def __exit__(self, *args): _set_option(pat, val, silent=True) -def register_option(key: str, defval: object, doc="", validator=None, cb=None): - """Register an option in the package-wide pandas config object +def register_option( + key: str, + defval: object, + doc: str = "", + validator: Optional[Callable] = None, + cb: Optional[Callable] = None, +) -> None: + """ + Register an option in the package-wide pandas config object Parameters ---------- - key - a fully-qualified key, e.g. "x.y.option - z". - defval - the default value of the option - doc - a string description of the option - validator - a function of a single argument, should raise `ValueError` if - called with a value which is not a legal value for the option. - cb - a function of a single argument "key", which is called - immediately after an option value is set/reset. key is - the full name of the option. - - Returns - ------- - Nothing. + key : str + Fully-qualified key, e.g. "x.y.option - z". + defval : object + Default value of the option. + doc : str + Description of the option. + validator : Callable, optional + Function of a single argument, should raise `ValueError` if + called with a value which is not a legal value for the option. + cb + a function of a single argument "key", which is called + immediately after an option value is set/reset. key is + the full name of the option. Raises ------ @@ -481,7 +489,9 @@ def register_option(key: str, defval: object, doc="", validator=None, cb=None): ) -def deprecate_option(key, msg=None, rkey=None, removal_ver=None): +def deprecate_option( + key: str, msg: Optional[str] = None, rkey: Optional[str] = None, removal_ver=None +) -> None: """ Mark option `key` as deprecated, if code attempts to access this option, a warning will be produced, using `msg` if given, or a default message @@ -494,32 +504,27 @@ def deprecate_option(key, msg=None, rkey=None, removal_ver=None): Parameters ---------- - key - the name of the option to be deprecated. must be a fully-qualified - option name (e.g "x.y.z.rkey"). - - msg - (Optional) a warning message to output when the key is referenced. - if no message is given a default message will be emitted. - - rkey - (Optional) the name of an option to reroute access to. - If specified, any referenced `key` will be re-routed to `rkey` - including set/get/reset. - rkey must be a fully-qualified option name (e.g "x.y.z.rkey"). - used by the default message if no `msg` is specified. - - removal_ver - (Optional) specifies the version in which this option will - be removed. used by the default message if no `msg` - is specified. - - Returns - ------- - Nothing + key : str + Name of the option to be deprecated. + must be a fully-qualified option name (e.g "x.y.z.rkey"). + msg : str, optional + Warning message to output when the key is referenced. + if no message is given a default message will be emitted. + rkey : str, optional + Name of an option to reroute access to. + If specified, any referenced `key` will be + re-routed to `rkey` including set/get/reset. + rkey must be a fully-qualified option name (e.g "x.y.z.rkey"). + used by the default message if no `msg` is specified. + removal_ver : optional + Specifies the version in which this option will + be removed. used by the default message if no `msg` is specified. Raises ------ - OptionError - if key has already been deprecated. - + OptionError + If the specified key has already been deprecated. """ - key = key.lower() if key in _deprecated_options: @@ -532,7 +537,7 @@ def deprecate_option(key, msg=None, rkey=None, removal_ver=None): # functions internal to the module -def _select_options(pat): +def _select_options(pat: str) -> List[str]: """returns a list of keys matching `pat` if pat=="all", returns all registered options @@ -550,7 +555,7 @@ def _select_options(pat): return [k for k in keys if re.search(pat, k, re.I)] -def _get_root(key): +def _get_root(key: str) -> Tuple[Any, str]: path = key.split(".") cursor = _global_config for p in path[:-1]: @@ -558,14 +563,14 @@ def _get_root(key): return cursor, path[-1] -def _is_deprecated(key): +def _is_deprecated(key: str) -> bool: """ Returns True if the given option has been deprecated """ key = key.lower() return key in _deprecated_options -def _get_deprecated_option(key): +def _get_deprecated_option(key: str): """ Retrieves the metadata for a deprecated option, if `key` is deprecated. @@ -582,7 +587,7 @@ def _get_deprecated_option(key): return d -def _get_registered_option(key): +def _get_registered_option(key: str): """ Retrieves the option metadata if `key` is a registered option. @@ -593,7 +598,7 @@ def _get_registered_option(key): return _registered_options.get(key) -def _translate_key(key): +def _translate_key(key: str) -> str: """ if key id deprecated and a replacement key defined, will return the replacement key, otherwise returns `key` as - is @@ -606,7 +611,7 @@ def _translate_key(key): return key -def _warn_if_deprecated(key): +def _warn_if_deprecated(key: str) -> bool: """ Checks if `key` is a deprecated option and if so, prints a warning. @@ -634,7 +639,7 @@ def _warn_if_deprecated(key): return False -def _build_option_description(k): +def _build_option_description(k: str) -> str: """ Builds a formatted description of a registered option and prints it """ o = _get_registered_option(k) @@ -652,14 +657,12 @@ def _build_option_description(k): if d: rkey = d.rkey if d.rkey else "" - s += "\n (Deprecated" - s += f", use `{rkey}` instead." - s += ")" + s += f"\n (Deprecated, use `{rkey}` instead.)" return s -def pp_options_list(keys, width=80, _print=False): +def pp_options_list(keys: List[str], width=80, _print: bool = False): """ Builds a concise listing of available options, grouped by prefix """ from textwrap import wrap @@ -729,7 +732,7 @@ def config_prefix(prefix): global register_option, get_option, set_option, reset_option def wrap(func): - def inner(key, *args, **kwds): + def inner(key: str, *args, **kwds) -> Callable: pkey = f"{prefix}.{key}" return func(pkey, *args, **kwds) @@ -751,7 +754,7 @@ def inner(key, *args, **kwds): # arg in register_option -def is_type_factory(_type): +def is_type_factory(_type) -> Callable: """ Parameters @@ -765,14 +768,14 @@ def is_type_factory(_type): """ - def inner(x): + def inner(x) -> None: if type(x) != _type: raise ValueError(f"Value must have type '{_type}'") return inner -def is_instance_factory(_type): +def is_instance_factory(_type) -> Callable: """ Parameters @@ -792,19 +795,19 @@ def is_instance_factory(_type): else: type_repr = f"'{_type}'" - def inner(x): + def inner(x) -> None: if not isinstance(x, _type): raise ValueError(f"Value must be an instance of {type_repr}") return inner -def is_one_of_factory(legal_values): +def is_one_of_factory(legal_values) -> Callable: callables = [c for c in legal_values if callable(c)] legal_values = [c for c in legal_values if not callable(c)] - def inner(x): + def inner(x) -> None: if x not in legal_values: if not any(c(x) for c in callables): @@ -818,7 +821,7 @@ def inner(x): return inner -def is_nonnegative_int(value): +def is_nonnegative_int(value: Optional[int]) -> None: """ Verify that value is None or a positive int. @@ -853,7 +856,7 @@ def is_nonnegative_int(value): is_text = is_instance_factory((str, bytes)) -def is_callable(obj): +def is_callable(obj) -> bool: """ Parameters From d1f3fe90f9f5d27db9cb07288a6721b61a73a125 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Mon, 6 Jan 2020 15:36:11 +0200 Subject: [PATCH 4/9] Fix unwanted patterns --- pandas/_config/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index d768e6b14afb2..2806caad5b542 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -657,7 +657,9 @@ def _build_option_description(k: str) -> str: if d: rkey = d.rkey if d.rkey else "" - s += f"\n (Deprecated, use `{rkey}` instead.)" + s += "\n (Deprecated" + s += f", use `{rkey}` instead." + s += ")" return s From 15d6135a902c1c7513b62acca5d9f257f2317925 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 00:17:59 +0200 Subject: [PATCH 5/9] TYP: Applied @simonjayhawkins suggestions --- pandas/_config/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 2806caad5b542..7a1664c07f4e8 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -181,7 +181,7 @@ def get_default_val(pat: str): class DictWrapper: """ provide attribute-style access to a nested dict""" - def __init__(self, d: Any, prefix: str = ""): + def __init__(self, d: Dict[str, Any], prefix: str = ""): object.__setattr__(self, "d", d) object.__setattr__(self, "prefix", prefix) @@ -555,7 +555,7 @@ def _select_options(pat: str) -> List[str]: return [k for k in keys if re.search(pat, k, re.I)] -def _get_root(key: str) -> Tuple[Any, str]: +def _get_root(key: str) -> Tuple[Dict[str, Any], str]: path = key.split(".") cursor = _global_config for p in path[:-1]: @@ -664,7 +664,7 @@ def _build_option_description(k: str) -> str: return s -def pp_options_list(keys: List[str], width=80, _print: bool = False): +def pp_options_list(keys: Iterable[str], width=80, _print: bool = False): """ Builds a concise listing of available options, grouped by prefix """ from textwrap import wrap From 0ad85dfe42cb992dcb44f17c6dfd36b11a361474 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 00:54:29 +0200 Subject: [PATCH 6/9] TYP: Removed some generics typings --- pandas/_config/config.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 7a1664c07f4e8..602fea0bc84fc 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -416,8 +416,8 @@ def register_option( key: str, defval: object, doc: str = "", - validator: Optional[Callable] = None, - cb: Optional[Callable] = None, + validator=None, + cb: Optional[Callable[[str], None]] = None, ) -> None: """ Register an option in the package-wide pandas config object @@ -734,7 +734,7 @@ def config_prefix(prefix): global register_option, get_option, set_option, reset_option def wrap(func): - def inner(key: str, *args, **kwds) -> Callable: + def inner(key: str, *args, **kwds) -> Callable[[str, Any, Any], Any]: pkey = f"{prefix}.{key}" return func(pkey, *args, **kwds) @@ -756,7 +756,7 @@ def inner(key: str, *args, **kwds) -> Callable: # arg in register_option -def is_type_factory(_type) -> Callable: +def is_type_factory(_type) -> Callable[..., None]: """ Parameters @@ -777,7 +777,7 @@ def inner(x) -> None: return inner -def is_instance_factory(_type) -> Callable: +def is_instance_factory(_type) -> Callable[..., None]: """ Parameters @@ -804,7 +804,7 @@ def inner(x) -> None: return inner -def is_one_of_factory(legal_values) -> Callable: +def is_one_of_factory(legal_values) -> Callable[..., None]: callables = [c for c in legal_values if callable(c)] legal_values = [c for c in legal_values if not callable(c)] From 27b8e244a7a5ac42ccea8ffd2dbcb43883f456ae Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 7 Jan 2020 01:07:36 +0200 Subject: [PATCH 7/9] TYP: Typed 'validator' --- pandas/_config/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 602fea0bc84fc..8997b01cd81af 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -51,7 +51,7 @@ from collections import namedtuple from contextlib import contextmanager import re -from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, Union import warnings DeprecatedOption = namedtuple("DeprecatedOption", "key msg rkey removal_ver") @@ -416,7 +416,7 @@ def register_option( key: str, defval: object, doc: str = "", - validator=None, + validator: Optional[Union[Callable[..., None], Type[str]]] = None, cb: Optional[Callable[[str], None]] = None, ) -> None: """ From 8b54e825227c89083ad974c09593da704437df40 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Thu, 9 Jan 2020 01:54:20 +0200 Subject: [PATCH 8/9] TYP: Apllied WillAyd's suggestion from https://github.com/pandas-dev/pandas/pull/30734#discussion_r364500158 --- pandas/_config/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 8997b01cd81af..7222d77c68e49 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -734,7 +734,7 @@ def config_prefix(prefix): global register_option, get_option, set_option, reset_option def wrap(func): - def inner(key: str, *args, **kwds) -> Callable[[str, Any, Any], Any]: + def inner(key: str, *args, **kwds) -> Callable[[str], Any]: pkey = f"{prefix}.{key}" return func(pkey, *args, **kwds) From 5d2c111722ada560095692cbb781e1c8f976e02b Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 12 Jan 2020 21:21:44 +0200 Subject: [PATCH 9/9] TYP: Applied simonjawhawkins suggetions --- pandas/_config/config.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 7222d77c68e49..aceb41c65fde0 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -51,7 +51,18 @@ from collections import namedtuple from contextlib import contextmanager import re -from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, Union +from typing import ( + Any, + Callable, + Dict, + Iterable, + List, + Optional, + Tuple, + Type, + TypeVar, + cast, +) import warnings DeprecatedOption = namedtuple("DeprecatedOption", "key msg rkey removal_ver") @@ -416,8 +427,8 @@ def register_option( key: str, defval: object, doc: str = "", - validator: Optional[Union[Callable[..., None], Type[str]]] = None, - cb: Optional[Callable[[str], None]] = None, + validator: Optional[Callable[[Any], Any]] = None, + cb: Optional[Callable[[str], Any]] = None, ) -> None: """ Register an option in the package-wide pandas config object @@ -702,6 +713,9 @@ def pp(name: str, ks: Iterable[str]) -> List[str]: # # helpers +FuncType = Callable[..., Any] +F = TypeVar("F", bound=FuncType) + @contextmanager def config_prefix(prefix): @@ -733,12 +747,12 @@ def config_prefix(prefix): global register_option, get_option, set_option, reset_option - def wrap(func): - def inner(key: str, *args, **kwds) -> Callable[[str], Any]: + def wrap(func: F) -> F: + def inner(key: str, *args, **kwds): pkey = f"{prefix}.{key}" return func(pkey, *args, **kwds) - return inner + return cast(F, inner) _register_option = register_option _get_option = get_option @@ -756,7 +770,7 @@ def inner(key: str, *args, **kwds) -> Callable[[str], Any]: # arg in register_option -def is_type_factory(_type) -> Callable[..., None]: +def is_type_factory(_type: Type[Any]) -> Callable[[Any], None]: """ Parameters @@ -777,7 +791,7 @@ def inner(x) -> None: return inner -def is_instance_factory(_type) -> Callable[..., None]: +def is_instance_factory(_type) -> Callable[[Any], None]: """ Parameters @@ -804,7 +818,7 @@ def inner(x) -> None: return inner -def is_one_of_factory(legal_values) -> Callable[..., None]: +def is_one_of_factory(legal_values) -> Callable[[Any], None]: callables = [c for c in legal_values if callable(c)] legal_values = [c for c in legal_values if not callable(c)]