diff --git a/pandas/_typing.py b/pandas/_typing.py index 5afe64f719b8a..445eff9e19e47 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -1,5 +1,15 @@ from pathlib import Path -from typing import IO, TYPE_CHECKING, AnyStr, Iterable, Optional, TypeVar, Union +from typing import ( + IO, + TYPE_CHECKING, + AnyStr, + Dict, + Iterable, + List, + Optional, + TypeVar, + Union, +) import numpy as np @@ -25,6 +35,7 @@ Scalar = Union[str, int, float, bool] Axis = Union[str, int] Ordered = Optional[bool] +JSONSerializable = Union[Scalar, List, Dict] # use Collection after we drop support for py35 Axes = Iterable diff --git a/pandas/core/dtypes/dtypes.py b/pandas/core/dtypes/dtypes.py index ae6f2ed289248..5c8dbd6d68a50 100644 --- a/pandas/core/dtypes/dtypes.py +++ b/pandas/core/dtypes/dtypes.py @@ -1,6 +1,6 @@ """ define extension dtypes """ import re -from typing import Any, Dict, List, Optional, Tuple, Type, Union, cast +from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Type, Union, cast import warnings import numpy as np @@ -351,7 +351,7 @@ def _finalize(self, categories, ordered: Ordered, fastpath: bool = False) -> Non self._ordered = ordered if ordered is not ordered_sentinel else None self._ordered_from_sentinel = ordered is ordered_sentinel - def __setstate__(self, state: Dict[str_type, Any]) -> None: + def __setstate__(self, state: MutableMapping[str_type, Any]) -> None: # for pickle compat. __get_state__ is defined in the # PandasExtensionDtype superclass and uses the public properties to # pickle -> need to set the settable private ones here (see GH26067) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a300748ee5bc8..5e123b73f60f8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -14,6 +14,7 @@ FrozenSet, Hashable, List, + Mapping, Optional, Sequence, Set, @@ -65,7 +66,7 @@ from pandas.core.dtypes.missing import isna, notna import pandas as pd -from pandas._typing import Dtype, FilePathOrBuffer, Scalar +from pandas._typing import Dtype, FilePathOrBuffer, JSONSerializable from pandas.core import missing, nanops import pandas.core.algorithms as algos from pandas.core.base import PandasObject, SelectionMixin @@ -2268,7 +2269,7 @@ def to_json( double_precision: int = 10, force_ascii: bool_t = True, date_unit: str = "ms", - default_handler: Optional[Callable[[Any], Union[Scalar, List, Dict]]] = None, + default_handler: Optional[Callable[[Any], JSONSerializable]] = None, lines: bool_t = False, compression: Optional[str] = "infer", index: bool_t = True, @@ -3133,7 +3134,7 @@ def to_csv( index_label: Optional[Union[bool_t, str, Sequence[Hashable]]] = None, mode: str = "w", encoding: Optional[str] = None, - compression: Optional[Union[str, Dict[str, str]]] = "infer", + compression: Optional[Union[str, Mapping[str, str]]] = "infer", quoting: Optional[int] = None, quotechar: str = '"', line_terminator: Optional[str] = None, diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index 8c9a4b94446c0..46c3b8b575af9 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -3,7 +3,7 @@ ExtensionArrays. """ import operator -from typing import Any, Dict, Union +from typing import Any, Mapping, Union import numpy as np @@ -161,7 +161,7 @@ def arithmetic_op( right: Any, op, str_rep: str, - eval_kwargs: Dict[str, bool], + eval_kwargs: Mapping[str, bool], ): """ Evaluate an arithmetic operation `+`, `-`, `*`, `/`, `//`, `%`, `**`, ... diff --git a/pandas/io/common.py b/pandas/io/common.py index 2ca2007e2925f..0b8594bbbd3e4 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -15,6 +15,7 @@ BinaryIO, Dict, List, + Mapping, Optional, TextIO, Tuple, @@ -276,16 +277,16 @@ def file_path_to_url(path: str) -> str: def _get_compression_method( - compression: Optional[Union[str, Dict[str, str]]] + compression: Optional[Union[str, Mapping[str, str]]] ) -> Tuple[Optional[str], Dict[str, str]]: """ Simplifies a compression argument to a compression method string and - a dict containing additional arguments. + a mapping containing additional arguments. Parameters ---------- - compression : str or dict - If string, specifies the compression method. If dict, value at key + compression : str or mapping + If string, specifies the compression method. If mapping, value at key 'method' specifies compression method. Returns @@ -295,15 +296,14 @@ def _get_compression_method( Raises ------ - ValueError on dict missing 'method' key + ValueError on mapping missing 'method' key """ - # Handle dict - if isinstance(compression, dict): - compression_args = compression.copy() + if isinstance(compression, Mapping): + compression_args = dict(compression) try: compression = compression_args.pop("method") except KeyError: - raise ValueError("If dict, compression must have key 'method'") + raise ValueError("If mapping, compression must have key 'method'") else: compression_args = {} return compression, compression_args @@ -368,7 +368,7 @@ def _get_handle( path_or_buf, mode: str, encoding=None, - compression: Optional[Union[str, Dict[str, Any]]] = None, + compression: Optional[Union[str, Mapping[str, Any]]] = None, memory_map: bool = False, is_text: bool = True, ): diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index b8c40e3f62221..6ddba6a297bdc 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -20,6 +20,7 @@ Dict, Iterable, List, + Mapping, Optional, Sequence, Tuple, @@ -78,7 +79,7 @@ from pandas import Series, DataFrame, Categorical formatters_type = Union[ - List[Callable], Tuple[Callable, ...], Dict[Union[str, int], Callable] + List[Callable], Tuple[Callable, ...], Mapping[Union[str, int], Callable] ] float_format_type = Union[str, Callable, "EngFormatter"] diff --git a/pandas/io/formats/html.py b/pandas/io/formats/html.py index 50fa4796f8d72..38f2e332017f0 100644 --- a/pandas/io/formats/html.py +++ b/pandas/io/formats/html.py @@ -4,7 +4,7 @@ from collections import OrderedDict from textwrap import dedent -from typing import IO, Any, Dict, Iterable, List, Optional, Tuple, Union, cast +from typing import IO, Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union, cast from pandas._config import get_option @@ -394,7 +394,7 @@ def _write_body(self, indent: int) -> None: self.write("", indent) def _write_regular_rows( - self, fmt_values: Dict[int, List[str]], indent: int + self, fmt_values: Mapping[int, List[str]], indent: int ) -> None: truncate_h = self.fmt.truncate_h truncate_v = self.fmt.truncate_v @@ -440,7 +440,7 @@ def _write_regular_rows( ) def _write_hierarchical_rows( - self, fmt_values: Dict[int, List[str]], indent: int + self, fmt_values: Mapping[int, List[str]], indent: int ) -> None: template = 'rowspan="{span}" valign="top"' diff --git a/pandas/io/formats/printing.py b/pandas/io/formats/printing.py index ead51693da791..061103820ca83 100644 --- a/pandas/io/formats/printing.py +++ b/pandas/io/formats/printing.py @@ -3,13 +3,23 @@ """ import sys -from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union +from typing import ( + Any, + Callable, + Iterable, + List, + Mapping, + Optional, + Sequence, + Tuple, + Union, +) from pandas._config import get_option from pandas.core.dtypes.inference import is_sequence -EscapeChars = Union[Dict[str, str], Iterable[str]] +EscapeChars = Union[Mapping[str, str], Iterable[str]] def adjoin(space: int, *lists: List[str], **kwargs) -> str: @@ -119,7 +129,7 @@ def _pprint_seq( def _pprint_dict( - seq: Dict, _nest_lvl: int = 0, max_seq_items: Optional[int] = None, **kwds + seq: Mapping, _nest_lvl: int = 0, max_seq_items: Optional[int] = None, **kwds ) -> str: """ internal. pprinter for iterables. you should probably use pprint_thing() diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index c71677fa3b570..6e9e0a0b01200 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -2,7 +2,7 @@ from io import StringIO from itertools import islice import os -from typing import Any, Callable, Dict, List, Optional, Type, Union +from typing import Any, Callable, Optional, Type import numpy as np @@ -13,7 +13,7 @@ from pandas.core.dtypes.common import ensure_str, is_period_dtype from pandas import DataFrame, MultiIndex, Series, compat, isna, to_datetime -from pandas._typing import Scalar +from pandas._typing import JSONSerializable from pandas.core.reshape.concat import concat from pandas.io.common import ( @@ -34,8 +34,6 @@ TABLE_SCHEMA_VERSION = "0.20.0" -Serializable = Union[Scalar, List, Dict] - # interface to/from def to_json( @@ -46,7 +44,7 @@ def to_json( double_precision: int = 10, force_ascii: bool = True, date_unit: str = "ms", - default_handler: Optional[Callable[[Any], Serializable]] = None, + default_handler: Optional[Callable[[Any], JSONSerializable]] = None, lines: bool = False, compression: Optional[str] = "infer", index: bool = True, @@ -110,7 +108,7 @@ def __init__( ensure_ascii: bool, date_unit: str, index: bool, - default_handler: Optional[Callable[[Any], Serializable]] = None, + default_handler: Optional[Callable[[Any], JSONSerializable]] = None, indent: int = 0, ): self.obj = obj @@ -153,7 +151,7 @@ def _write( ensure_ascii: bool, date_unit: str, iso_dates: bool, - default_handler: Optional[Callable[[Any], Serializable]], + default_handler: Optional[Callable[[Any], JSONSerializable]], indent: int, ): return dumps( @@ -186,7 +184,7 @@ def _write( ensure_ascii: bool, date_unit: str, iso_dates: bool, - default_handler: Optional[Callable[[Any], Serializable]], + default_handler: Optional[Callable[[Any], JSONSerializable]], indent: int, ): if not self.index and orient == "split": @@ -233,7 +231,7 @@ def _write( ensure_ascii: bool, date_unit: str, iso_dates: bool, - default_handler: Optional[Callable[[Any], Serializable]], + default_handler: Optional[Callable[[Any], JSONSerializable]], indent: int, ): if not self.index and orient == "split": @@ -263,7 +261,7 @@ def __init__( ensure_ascii: bool, date_unit: str, index: bool, - default_handler: Optional[Callable[[Any], Serializable]] = None, + default_handler: Optional[Callable[[Any], JSONSerializable]] = None, indent: int = 0, ): """ diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index ebc015c820c14..f8c08ed8c099f 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -4,8 +4,8 @@ from typing import ( Any, Callable, - Dict, List, + Mapping, Optional, Tuple, Type, @@ -104,7 +104,7 @@ def wrapper(*args, **kwargs) -> Callable[..., Any]: def deprecate_kwarg( old_arg_name: str, new_arg_name: Optional[str], - mapping: Optional[Union[Dict[Any, Any], Callable[[Any], Any]]] = None, + mapping: Optional[Union[Mapping[Any, Any], Callable[[Any], Any]]] = None, stacklevel: int = 2, ) -> Callable[..., Any]: """