From 5c9340bf3a3a61dc8ed6d933f872c0a44273740b Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 5 Oct 2020 16:08:24 -0700 Subject: [PATCH 1/6] TYPO: pandas.util._decorators --- pandas/plotting/_matplotlib/converter.py | 4 ++-- pandas/util/_decorators.py | 3 ++- setup.cfg | 4 ---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pandas/plotting/_matplotlib/converter.py b/pandas/plotting/_matplotlib/converter.py index 3db7c38eced65..27c7b931b7136 100644 --- a/pandas/plotting/_matplotlib/converter.py +++ b/pandas/plotting/_matplotlib/converter.py @@ -2,7 +2,7 @@ import datetime as pydt from datetime import datetime, timedelta, tzinfo import functools -from typing import Any, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple from dateutil.relativedelta import relativedelta import matplotlib.dates as dates @@ -1002,7 +1002,7 @@ def __init__( self.format = None self.freq = freq self.locs: List[Any] = [] # unused, for matplotlib compat - self.formatdict = None + self.formatdict: Optional[Dict[Any, Any]] = None self.isminor = minor_locator self.isdynamic = dynamic_mode self.offset = 0 diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index f81bca7e85156..bd857a09d279d 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -278,7 +278,8 @@ def decorate(func): allow_args = allowed_args else: spec = inspect.getfullargspec(func) - allow_args = spec.args[: -len(spec.defaults)] + # mypy doesn't know that spec.defaults is Sized + allow_args = spec.args[: -len(spec.defaults)] # type:ignore [arg-type] @wraps(func) def wrapper(*args, **kwargs): diff --git a/setup.cfg b/setup.cfg index e125eea226b10..1e9906ab8fe7c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -291,7 +291,3 @@ check_untyped_defs=False [mypy-pandas.plotting._misc] check_untyped_defs=False - -[mypy-pandas.util._decorators] -check_untyped_defs=False - From 401768161a889fb10890cfc7dd7836e695e11d5c Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 5 Oct 2020 16:20:18 -0700 Subject: [PATCH 2/6] TYP: pandas.io.json._json --- pandas/io/json/_json.py | 42 +++++++++++++++++++++++++++++------------ setup.cfg | 2 -- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index ef684469dffbb..f0bc9b7a8fe6e 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -3,7 +3,7 @@ from io import BytesIO, StringIO from itertools import islice import os -from typing import IO, Any, Callable, List, Optional, Type +from typing import IO, Any, Callable, List, Optional, Tuple, Type import numpy as np @@ -777,8 +777,8 @@ def read(self): obj = self._get_object_parser(lines_json) else: data = ensure_str(self.data) - data = data.split("\n") - obj = self._get_object_parser(self._combine_lines(data)) + data_lines = data.split("\n") + obj = self._get_object_parser(self._combine_lines(data_lines)) else: obj = self._get_object_parser(self.data) self.close() @@ -848,6 +848,8 @@ def __next__(self): class Parser: + _split_keys: Tuple[str, ...] + _default_orient: str _STAMP_UNITS = ("s", "ms", "us", "ns") _MIN_STAMPS = { @@ -873,6 +875,7 @@ def __init__( if orient is None: orient = self._default_orient + self.orient = orient self.dtype = dtype @@ -902,8 +905,8 @@ def check_keys_split(self, decoded): """ bad_keys = set(decoded.keys()).difference(set(self._split_keys)) if bad_keys: - bad_keys = ", ".join(bad_keys) - raise ValueError(f"JSON data had unexpected key(s): {bad_keys}") + bad_keys_joined = ", ".join(bad_keys) + raise ValueError(f"JSON data had unexpected key(s): {bad_keys_joined}") def parse(self): @@ -922,14 +925,22 @@ def parse(self): self._try_convert_types() return self.obj + def _parse_numpy(self): + raise AbstractMethodError(self) + + def _parse_no_numpy(self): + raise AbstractMethodError(self) + def _convert_axes(self): """ Try to convert axes. """ - for axis_name in self.obj._AXIS_ORDERS: + obj = self.obj + assert obj is not None # for mypy + for axis_name in obj: new_axis, result = self._try_convert_data( name=axis_name, - data=self.obj._get_axis(axis_name), + data=obj._get_axis(axis_name), use_dtypes=False, convert_dates=True, ) @@ -1083,7 +1094,11 @@ def _parse_numpy(self): self.check_keys_split(decoded) self.obj = create_series_with_explicit_dtype(**decoded) elif self.orient in ["columns", "index"]: - self.obj = create_series_with_explicit_dtype(*data, dtype_if_empty=object) + # error: "create_series_with_explicit_dtype" + # gets multiple values for keyword argument "dtype_if_empty + self.obj = create_series_with_explicit_dtype( + *data, dtype_if_empty=object + ) # type:ignore [misc] else: self.obj = create_series_with_explicit_dtype(data, dtype_if_empty=object) @@ -1175,9 +1190,12 @@ def _process_converter(self, f, filt=None): if filt is None: filt = lambda col, c: True + obj = self.obj + assert obj is not None # for mypy + needs_new_obj = False new_obj = dict() - for i, (col, c) in enumerate(self.obj.items()): + for i, (col, c) in enumerate(obj.items()): if filt(col, c): new_data, result = f(col, c) if result: @@ -1188,9 +1206,9 @@ def _process_converter(self, f, filt=None): if needs_new_obj: # possibly handle dup columns - new_obj = DataFrame(new_obj, index=self.obj.index) - new_obj.columns = self.obj.columns - self.obj = new_obj + new_frame = DataFrame(new_obj, index=obj.index) + new_frame.columns = obj.columns + self.obj = new_frame def _try_convert_types(self): if self.obj is None: diff --git a/setup.cfg b/setup.cfg index 1e9906ab8fe7c..1d74aba969134 100644 --- a/setup.cfg +++ b/setup.cfg @@ -265,8 +265,6 @@ check_untyped_defs=False [mypy-pandas.io.html] check_untyped_defs=False -[mypy-pandas.io.json._json] -check_untyped_defs=False [mypy-pandas.io.parsers] check_untyped_defs=False From 3b1fba6459c436dbfa59994634129d6bf888c4fd Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 5 Oct 2020 16:21:36 -0700 Subject: [PATCH 3/6] whitespace fixup --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 1d74aba969134..80bf3ea0e2af0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -265,7 +265,6 @@ check_untyped_defs=False [mypy-pandas.io.html] check_untyped_defs=False - [mypy-pandas.io.parsers] check_untyped_defs=False From 44ebc7e2dbbbd2c12fd5076431a3a27827c08508 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 5 Oct 2020 17:32:31 -0700 Subject: [PATCH 4/6] fixup --- pandas/io/json/_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index f0bc9b7a8fe6e..591353f36ecee 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -937,7 +937,7 @@ def _convert_axes(self): """ obj = self.obj assert obj is not None # for mypy - for axis_name in obj: + for axis_name in obj._AXIS_ORDERS: new_axis, result = self._try_convert_data( name=axis_name, data=obj._get_axis(axis_name), From c5bbdfd84beb4fddd12d7a974701cce3d936b861 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 5 Oct 2020 19:52:15 -0700 Subject: [PATCH 5/6] lint fixup --- pandas/io/json/_json.py | 2 +- pandas/util/_decorators.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 591353f36ecee..3df3575b9748c 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -1098,7 +1098,7 @@ def _parse_numpy(self): # gets multiple values for keyword argument "dtype_if_empty self.obj = create_series_with_explicit_dtype( *data, dtype_if_empty=object - ) # type:ignore [misc] + ) # type:ignore[misc] else: self.obj = create_series_with_explicit_dtype(data, dtype_if_empty=object) diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index bd857a09d279d..37277aa50079a 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -279,7 +279,7 @@ def decorate(func): else: spec = inspect.getfullargspec(func) # mypy doesn't know that spec.defaults is Sized - allow_args = spec.args[: -len(spec.defaults)] # type:ignore [arg-type] + allow_args = spec.args[: -len(spec.defaults)] # type:ignore[arg-type] @wraps(func) def wrapper(*args, **kwargs): From a1fb8b6671ed7016d45f24a43dbdb72a04c40052 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 7 Oct 2020 07:53:02 -0700 Subject: [PATCH 6/6] update per comments --- pandas/io/json/_json.py | 5 +++-- pandas/util/_decorators.py | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 3df3575b9748c..3cf3c2e7fd91d 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -111,6 +111,8 @@ def to_json( class Writer: + _default_orient: str + def __init__( self, obj, @@ -126,8 +128,7 @@ def __init__( self.obj = obj if orient is None: - # error: "Writer" has no attribute "_default_orient" - orient = self._default_orient # type: ignore[attr-defined] + orient = self._default_orient self.orient = orient self.date_format = date_format diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index 37277aa50079a..d002e8a4ebd43 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -278,8 +278,10 @@ def decorate(func): allow_args = allowed_args else: spec = inspect.getfullargspec(func) - # mypy doesn't know that spec.defaults is Sized - allow_args = spec.args[: -len(spec.defaults)] # type:ignore[arg-type] + + # We must have some defaults if we are deprecating default-less + assert spec.defaults is not None # for mypy + allow_args = spec.args[: -len(spec.defaults)] @wraps(func) def wrapper(*args, **kwargs):