Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into na-array-ufunc
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAugspurger committed Dec 13, 2019
2 parents bf8680f + 665e4b1 commit 0c69bd0
Show file tree
Hide file tree
Showing 49 changed files with 463 additions and 440 deletions.
16 changes: 7 additions & 9 deletions ci/azure/posix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,13 @@ jobs:
PATTERN: "not slow and not network"
LOCALE_OVERRIDE: "zh_CN.UTF-8"

# Disabled for NumPy object-dtype warning.
# https://github.com/pandas-dev/pandas/issues/30043
# py37_np_dev:
# ENV_FILE: ci/deps/azure-37-numpydev.yaml
# CONDA_PY: "37"
# PATTERN: "not slow and not network"
# TEST_ARGS: "-W error"
# PANDAS_TESTING_MODE: "deprecate"
# EXTRA_APT: "xsel"
py37_np_dev:
ENV_FILE: ci/deps/azure-37-numpydev.yaml
CONDA_PY: "37"
PATTERN: "not slow and not network"
TEST_ARGS: "-W error"
PANDAS_TESTING_MODE: "deprecate"
EXTRA_APT: "xsel"

steps:
- script: |
Expand Down
7 changes: 4 additions & 3 deletions pandas/_libs/parsers.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ cdef class TextReader:

if isinstance(source, str):
encoding = sys.getfilesystemencoding() or "utf-8"

usource = source
source = source.encode(encoding)

if self.memory_map:
Expand All @@ -677,10 +677,11 @@ cdef class TextReader:

if ptr == NULL:
if not os.path.exists(source):

raise FileNotFoundError(
ENOENT,
f'File {source} does not exist',
source)
f'File {usource} does not exist',
usource)
raise IOError('Initializing from file failed')

self.parser.source = ptr
Expand Down
7 changes: 6 additions & 1 deletion pandas/core/arrays/numpy_.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ def _is_boolean(self):

@classmethod
def construct_from_string(cls, string):
return cls(np.dtype(string))
try:
return cls(np.dtype(string))
except TypeError as err:
raise TypeError(
f"Cannot construct a 'PandasDtype' from '{string}'"
) from err

def construct_array_type(cls):
return PandasArray
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/arrays/sparse/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def construct_from_string(cls, string):
-------
SparseDtype
"""
msg = f"Could not construct SparseDtype from '{string}'"
msg = f"Cannot construct a 'SparseDtype' from '{string}'"
if string.startswith("Sparse"):
try:
sub_type, has_fill_value = cls._parse_subtype(string)
Expand All @@ -208,7 +208,7 @@ def construct_from_string(cls, string):
else:
result = SparseDtype(sub_type)
msg = (
f"Could not construct SparseDtype from '{string}'.\n\nIt "
f"Cannot construct a 'SparseDtype' from '{string}'.\n\nIt "
"looks like the fill_value in the string is not "
"the default for the dtype. Non-default fill_values "
"are not supported. Use the 'SparseDtype()' "
Expand Down
11 changes: 6 additions & 5 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ def construct_from_string(cls, string: str_type):
datetime64[ns, UTC]
"""
if isinstance(string, str):
msg = "Could not construct DatetimeTZDtype from '{string}'"
msg = f"Cannot construct a 'DatetimeTZDtype' from '{string}'"
match = cls._match.match(string)
if match:
d = match.groupdict()
Expand All @@ -743,10 +743,10 @@ def construct_from_string(cls, string: str_type):
# pytz timezone (actually pytz.UnknownTimeZoneError).
# TypeError if we pass a nonsense tz;
# ValueError if we pass a unit other than "ns"
raise TypeError(msg.format(string=string)) from err
raise TypeError(msg.format(string=string))
raise TypeError(msg) from err
raise TypeError(msg)

raise TypeError("Could not construct DatetimeTZDtype")
raise TypeError("Cannot construct a 'DatetimeTZDtype'")

def __str__(self) -> str_type:
return "datetime64[{unit}, {tz}]".format(unit=self.unit, tz=self.tz)
Expand Down Expand Up @@ -883,7 +883,7 @@ def construct_from_string(cls, string):
return cls(freq=string)
except ValueError:
pass
raise TypeError("could not construct PeriodDtype")
raise TypeError(f"Cannot construct a 'PeriodDtype' from '{string}'")

def __str__(self) -> str_type:
return self.name
Expand Down Expand Up @@ -1054,6 +1054,7 @@ def construct_from_string(cls, string):
return cls(string)

msg = (
f"Cannot construct a 'IntervalDtype' from '{string}'.\n\n"
"Incorrectly formatted string passed to constructor. "
"Valid formats include Interval or Interval[dtype] "
"where dtype is numeric, datetime, or timedelta"
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,8 @@ def wrapper(left, right):
res_name = get_op_result_name(left, right)

lvalues = extract_array(left, extract_numpy=True)
result = arithmetic_op(lvalues, right, op, str_rep)
rvalues = extract_array(right, extract_numpy=True)
result = arithmetic_op(lvalues, rvalues, op, str_rep)

return _construct_result(left, result, index=left.index, name=res_name)

Expand Down
23 changes: 4 additions & 19 deletions pandas/core/ops/array_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,14 @@
)
from pandas.core.dtypes.generic import (
ABCDatetimeArray,
ABCDatetimeIndex,
ABCExtensionArray,
ABCIndex,
ABCIndexClass,
ABCSeries,
ABCTimedeltaArray,
ABCTimedeltaIndex,
)
from pandas.core.dtypes.missing import isna, notna

from pandas.core.construction import extract_array
from pandas.core.ops import missing
from pandas.core.ops.dispatch import dispatch_to_extension_op, should_extension_dispatch
from pandas.core.ops.invalid import invalid_comparison
Expand Down Expand Up @@ -178,22 +175,10 @@ def arithmetic_op(

from pandas.core.ops import maybe_upcast_for_op

keep_null_freq = isinstance(
right,
(
ABCDatetimeIndex,
ABCDatetimeArray,
ABCTimedeltaIndex,
ABCTimedeltaArray,
Timestamp,
),
)

# NB: We assume that extract_array has already been called on `left`, but
# cannot make the same assumption about `right`. This is because we need
# to define `keep_null_freq` before calling extract_array on it.
# NB: We assume that extract_array has already been called
# on `left` and `right`.
lvalues = left
rvalues = extract_array(right, extract_numpy=True)
rvalues = right

rvalues = maybe_upcast_for_op(rvalues, lvalues.shape)

Expand All @@ -203,7 +188,7 @@ def arithmetic_op(
# TimedeltaArray, DatetimeArray, and Timestamp are included here
# because they have `freq` attribute which is handled correctly
# by dispatch_to_extension_op.
res_values = dispatch_to_extension_op(op, lvalues, rvalues, keep_null_freq)
res_values = dispatch_to_extension_op(op, lvalues, rvalues)

else:
with np.errstate(all="ignore"):
Expand Down
25 changes: 2 additions & 23 deletions pandas/core/ops/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

import numpy as np

from pandas.errors import NullFrequencyError

from pandas.core.dtypes.common import (
is_datetime64_dtype,
is_extension_array_dtype,
Expand Down Expand Up @@ -96,10 +94,7 @@ def should_series_dispatch(left, right, op):


def dispatch_to_extension_op(
op,
left: Union[ABCExtensionArray, np.ndarray],
right: Any,
keep_null_freq: bool = False,
op, left: Union[ABCExtensionArray, np.ndarray], right: Any,
):
"""
Assume that left or right is a Series backed by an ExtensionArray,
Expand All @@ -110,9 +105,6 @@ def dispatch_to_extension_op(
op : binary operator
left : ExtensionArray or np.ndarray
right : object
keep_null_freq : bool, default False
Whether to re-raise a NullFrequencyError unchanged, as opposed to
catching and raising TypeError.
Returns
-------
Expand All @@ -130,18 +122,5 @@ def dispatch_to_extension_op(

# The op calls will raise TypeError if the op is not defined
# on the ExtensionArray

try:
res_values = op(left, right)
except NullFrequencyError:
# DatetimeIndex and TimedeltaIndex with freq == None raise ValueError
# on add/sub of integers (or int-like). We re-raise as a TypeError.
if keep_null_freq:
# TODO: remove keep_null_freq after Timestamp+int deprecation
# GH#22535 is enforced
raise
raise TypeError(
"incompatible type for a datetime/timedelta "
"operation [{name}]".format(name=op.__name__)
)
res_values = op(left, right)
return res_values
5 changes: 2 additions & 3 deletions pandas/core/ops/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ def _create_methods(cls, arith_method, comp_method, bool_method, special):
have_divmod = issubclass(cls, ABCSeries)
# divmod is available for Series

# yapf: disable
new_methods = dict(
add=arith_method(cls, operator.add, special),
radd=arith_method(cls, radd, special),
Expand All @@ -181,8 +180,8 @@ def _create_methods(cls, arith_method, comp_method, bool_method, special):
rtruediv=arith_method(cls, rtruediv, special),
rfloordiv=arith_method(cls, rfloordiv, special),
rpow=arith_method(cls, rpow, special),
rmod=arith_method(cls, rmod, special))
# yapf: enable
rmod=arith_method(cls, rmod, special),
)
new_methods["div"] = new_methods["truediv"]
new_methods["rdiv"] = new_methods["rtruediv"]
if have_divmod:
Expand Down
13 changes: 6 additions & 7 deletions pandas/io/formats/css.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ def expand(self, prop, value):
mapping = self.SIDE_SHORTHANDS[len(tokens)]
except KeyError:
warnings.warn(
'Could not expand "{prop}: {val}"'.format(prop=prop, val=value),
CSSWarning,
f'Could not expand "{prop}: {value}"', CSSWarning,
)
return
for key, idx in zip(self.SIDES, mapping):
Expand Down Expand Up @@ -110,14 +109,14 @@ def __call__(self, declarations_str, inherited=None):

# 3. TODO: resolve other font-relative units
for side in self.SIDES:
prop = "border-{side}-width".format(side=side)
prop = f"border-{side}-width"
if prop in props:
props[prop] = self.size_to_pt(
props[prop], em_pt=font_size, conversions=self.BORDER_WIDTH_RATIOS
)
for prop in [
"margin-{side}".format(side=side),
"padding-{side}".format(side=side),
f"margin-{side}",
f"padding-{side}",
]:
if prop in props:
# TODO: support %
Expand Down Expand Up @@ -206,9 +205,9 @@ def _error():

val = round(val, 5)
if int(val) == val:
size_fmt = "{fmt:d}pt".format(fmt=int(val))
size_fmt = f"{int(val):d}pt"
else:
size_fmt = "{fmt:f}pt".format(fmt=val)
size_fmt = f"{val:f}pt"
return size_fmt

def atomize(self, declarations):
Expand Down
19 changes: 9 additions & 10 deletions pandas/io/formats/excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def build_xlstyle(self, props):
"font": self.build_font(props),
"number_format": self.build_number_format(props),
}

# TODO: handle cell width and height: needs support in pandas.io.excel

def remove_none(d):
Expand Down Expand Up @@ -132,12 +133,10 @@ def build_border(self, props):
return {
side: {
"style": self._border_style(
props.get("border-{side}-style".format(side=side)),
props.get("border-{side}-width".format(side=side)),
),
"color": self.color_to_excel(
props.get("border-{side}-color".format(side=side))
props.get(f"border-{side}-style"),
props.get(f"border-{side}-width"),
),
"color": self.color_to_excel(props.get(f"border-{side}-color")),
}
for side in ["top", "right", "bottom", "left"]
}
Expand Down Expand Up @@ -427,7 +426,7 @@ def _format_value(self, val):
if missing.isposinf_scalar(val):
val = self.inf_rep
elif missing.isneginf_scalar(val):
val = "-{inf}".format(inf=self.inf_rep)
val = f"-{self.inf_rep}"
elif self.float_format is not None:
val = float(self.float_format % val)
if getattr(val, "tzinfo", None) is not None:
Expand Down Expand Up @@ -509,8 +508,8 @@ def _format_header_regular(self):
if has_aliases:
if len(self.header) != len(self.columns):
raise ValueError(
"Writing {cols} cols but got {alias} "
"aliases".format(cols=len(self.columns), alias=len(self.header))
f"Writing {len(self.columns)} cols but got {len(self.header)} "
"aliases"
)
else:
colnames = self.header
Expand Down Expand Up @@ -718,8 +717,8 @@ def write(
if num_rows > self.max_rows or num_cols > self.max_cols:
raise ValueError(
"This sheet is too large! Your sheet size is: "
+ "{}, {} ".format(num_rows, num_cols)
+ "Max sheet size is: {}, {}".format(self.max_rows, self.max_cols)
f"{num_rows}, {num_cols} "
f"Max sheet size is: {self.max_rows}, {self.max_cols}"
)

if isinstance(writer, ExcelWriter):
Expand Down
Loading

0 comments on commit 0c69bd0

Please sign in to comment.