Skip to content

CLN: address TODOs #44305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions pandas/_libs/hashtable.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,6 @@ class StringHashTable(HashTable): ...
class PyObjectHashTable(HashTable): ...
class IntpHashTable(HashTable): ...

def duplicated_int64(
values: np.ndarray, # const int64_t[:] values
keep: Literal["last", "first", False] = ...,
) -> npt.NDArray[np.bool_]: ...

# TODO: Is it actually bool or is it uint8?

def mode_int64(
values: np.ndarray, # const int64_t[:] values
dropna: bool,
) -> npt.NDArray[np.int64]: ...
def value_count_int64(
values: np.ndarray, # const int64_t[:]
dropna: bool,
) -> tuple[npt.NDArray[np.int64], npt.NDArray[np.int64]]: ...
def duplicated(
values: np.ndarray,
keep: Literal["last", "first", False] = ...,
Expand Down
2 changes: 1 addition & 1 deletion pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ cdef class Tick(SingleConstructorOffset):
"Tick offset with `normalize=True` are not allowed."
)

# FIXME: Without making this cpdef, we get AttributeError when calling
# Note: Without making this cpdef, we get AttributeError when calling
# from __mul__
cpdef Tick _next_higher_resolution(Tick self):
if type(self) is Day:
Expand Down
7 changes: 5 additions & 2 deletions pandas/_libs/writers.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations

import numpy as np

# TODO: can make this more specific
from pandas._typing import ArrayLike

def write_csv_rows(
data: list,
data: list[ArrayLike],
data_index: np.ndarray,
nlevels: int,
cols: np.ndarray,
Expand Down
2 changes: 1 addition & 1 deletion pandas/_libs/writers.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def write_csv_rows(

Parameters
----------
data : list
data : list[ArrayLike]
data_index : ndarray
nlevels : int
cols : ndarray
Expand Down
17 changes: 10 additions & 7 deletions pandas/core/array_algos/putmask.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def putmask_inplace(values: ArrayLike, mask: npt.NDArray[np.bool_], value: Any)
np.putmask(values, mask, value)


def putmask_smart(values: np.ndarray, mask: np.ndarray, new) -> np.ndarray:
def putmask_smart(values: np.ndarray, mask: npt.NDArray[np.bool_], new) -> np.ndarray:
"""
Return a new ndarray, try to preserve dtype if possible.

Expand All @@ -84,12 +84,11 @@ def putmask_smart(values: np.ndarray, mask: np.ndarray, new) -> np.ndarray:

See Also
--------
ndarray.putmask
np.putmask
"""
# we cannot use np.asarray() here as we cannot have conversions
# that numpy does when numeric are mixed with strings

# n should be the length of the mask or a scalar here
if not is_list_like(new):
new = np.broadcast_to(new, mask.shape)

Expand Down Expand Up @@ -139,15 +138,17 @@ def putmask_smart(values: np.ndarray, mask: np.ndarray, new) -> np.ndarray:
return _putmask_preserve(values, new, mask)


def _putmask_preserve(new_values: np.ndarray, new, mask: np.ndarray):
def _putmask_preserve(new_values: np.ndarray, new, mask: npt.NDArray[np.bool_]):
try:
new_values[mask] = new[mask]
except (IndexError, ValueError):
new_values[mask] = new
return new_values


def putmask_without_repeat(values: np.ndarray, mask: np.ndarray, new: Any) -> None:
def putmask_without_repeat(
values: np.ndarray, mask: npt.NDArray[np.bool_], new: Any
) -> None:
"""
np.putmask will truncate or repeat if `new` is a listlike with
len(new) != len(values). We require an exact match.
Expand Down Expand Up @@ -181,7 +182,9 @@ def putmask_without_repeat(values: np.ndarray, mask: np.ndarray, new: Any) -> No
np.putmask(values, mask, new)


def validate_putmask(values: ArrayLike, mask: np.ndarray) -> tuple[np.ndarray, bool]:
def validate_putmask(
values: ArrayLike, mask: np.ndarray
) -> tuple[npt.NDArray[np.bool_], bool]:
"""
Validate mask and check if this putmask operation is a no-op.
"""
Expand All @@ -193,7 +196,7 @@ def validate_putmask(values: ArrayLike, mask: np.ndarray) -> tuple[np.ndarray, b
return mask, noop


def extract_bool_array(mask: ArrayLike) -> np.ndarray:
def extract_bool_array(mask: ArrayLike) -> npt.NDArray[np.bool_]:
"""
If we have a SparseArray or BooleanArray, convert it to ndarray[bool].
"""
Expand Down
1 change: 1 addition & 0 deletions pandas/core/indexes/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ def fillna(self, value, downcast=None):

return type(self)._simple_new(cat, name=self.name)

# TODO(2.0): remove reindex once non-unique deprecation is enforced
def reindex(
self, target, method=None, level=None, limit=None, tolerance=None
) -> tuple[Index, npt.NDArray[np.intp] | None]:
Expand Down
1 change: 0 additions & 1 deletion pandas/tests/arithmetic/test_timedelta64.py
Original file line number Diff line number Diff line change
Expand Up @@ -2132,7 +2132,6 @@ def test_float_series_rdiv_td64arr(self, box_with_array, names):

result = ser.__rtruediv__(tdi)
if box is DataFrame:
# TODO: Should we skip this case sooner or test something else?
assert result is NotImplemented
else:
tm.assert_equal(result, expected)
Expand Down
13 changes: 6 additions & 7 deletions pandas/tests/arrays/categorical/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
([1, 2, "3"], "5", ["5", "5", 3], True),
],
)
def test_replace(to_replace, value, expected, flip_categories):
def test_replace_categorical_series(to_replace, value, expected, flip_categories):
# GH 31720
stays_categorical = not isinstance(value, list) or len(pd.unique(value)) == 1

s = pd.Series([1, 2, 3], dtype="category")
result = s.replace(to_replace, value)
ser = pd.Series([1, 2, 3], dtype="category")
result = ser.replace(to_replace, value)
expected = pd.Series(expected, dtype="category")
s.replace(to_replace, value, inplace=True)
ser.replace(to_replace, value, inplace=True)

if flip_categories:
expected = expected.cat.set_categories(expected.cat.categories[::-1])
Expand All @@ -46,7 +46,7 @@ def test_replace(to_replace, value, expected, flip_categories):
expected = pd.Series(np.asarray(expected))

tm.assert_series_equal(expected, result, check_category_order=False)
tm.assert_series_equal(expected, s, check_category_order=False)
tm.assert_series_equal(expected, ser, check_category_order=False)


@pytest.mark.parametrize(
Expand All @@ -59,8 +59,7 @@ def test_replace(to_replace, value, expected, flip_categories):
("b", None, ["a", None], "Categorical.categories length are different"),
],
)
def test_replace2(to_replace, value, result, expected_error_msg):
# TODO: better name
def test_replace_categorical(to_replace, value, result, expected_error_msg):
# GH#26988
cat = Categorical(["a", "b"])
expected = Categorical(result)
Expand Down
13 changes: 1 addition & 12 deletions pandas/tests/arrays/timedeltas/test_reductions.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,8 @@ def test_sum(self):
assert isinstance(result, Timedelta)
assert result == expected

# TODO: de-duplicate with test_npsum below
def test_np_sum(self):
# GH#25282
vals = np.arange(5, dtype=np.int64).view("m8[h]").astype("m8[ns]")
arr = TimedeltaArray(vals)
result = np.sum(arr)
assert result == vals.sum()

result = np.sum(pd.TimedeltaIndex(arr))
assert result == vals.sum()

def test_npsum(self):
# GH#25335 np.sum should return a Timedelta, not timedelta64
# GH#25282, GH#25335 np.sum should return a Timedelta, not timedelta64
tdi = pd.TimedeltaIndex(["3H", "3H", "2H", "5H", "4H"])
arr = tdi.array

Expand Down
7 changes: 4 additions & 3 deletions pandas/tests/extension/decimal/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,12 @@ def test_series_repr(self, data):
assert "Decimal: " in repr(ser)


# TODO(extension)
@pytest.mark.xfail(
reason=(
"raising AssertionError as this is not implemented, though easy enough to do"
)
"DecimalArray constructor raises bc _from_sequence wants Decimals, not ints."
"Easy to fix, just need to do it."
),
raises=TypeError,
)
def test_series_constructor_coerce_data_to_extension_dtype_raises():
xpr = (
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/categorical/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ def test_get_indexer_same_categories_different_order(self):


class TestWhere:
def test_where(self, listlike_box_with_tuple):
klass = listlike_box_with_tuple
def test_where(self, listlike_box):
klass = listlike_box

i = CategoricalIndex(list("aabbca"), categories=list("cab"), ordered=False)
cond = [True] * len(i)
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ def test_numpy_repeat(self, simple_index):
with pytest.raises(ValueError, match=msg):
np.repeat(idx, rep, axis=0)

def test_where(self, listlike_box_with_tuple, simple_index):
klass = listlike_box_with_tuple
def test_where(self, listlike_box, simple_index):
klass = listlike_box

idx = simple_index
if isinstance(idx, (DatetimeIndex, TimedeltaIndex)):
Expand Down
12 changes: 1 addition & 11 deletions pandas/tests/indexes/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,9 @@ def freq_sample(request):
return request.param


@pytest.fixture(params=[list, np.array, array, Series])
@pytest.fixture(params=[list, tuple, np.array, array, Series])
def listlike_box(request):
"""
Types that may be passed as the indexer to searchsorted.
"""
return request.param


# TODO: not clear if this _needs_ to be different from listlike_box or
# if that is just a historical artifact
@pytest.fixture(params=[list, tuple, np.array, Series])
def listlike_box_with_tuple(request):
"""
Types that may be passed as the indexer to searchsorted.
"""
return request.param
4 changes: 2 additions & 2 deletions pandas/tests/indexes/interval/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def test_take(self, closed):
expected = IntervalIndex.from_arrays([0, 0, 1], [1, 1, 2], closed=closed)
tm.assert_index_equal(result, expected)

def test_where(self, simple_index, listlike_box_with_tuple):
klass = listlike_box_with_tuple
def test_where(self, simple_index, listlike_box):
klass = listlike_box

idx = simple_index
cond = [True] * len(idx)
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/multi/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,12 +720,12 @@ def test_where(self):
with pytest.raises(NotImplementedError, match=msg):
i.where(True)

def test_where_array_like(self, listlike_box_with_tuple):
def test_where_array_like(self, listlike_box):
mi = MultiIndex.from_tuples([("A", 1), ("A", 2)])
cond = [False, True]
msg = r"\.where is not supported for MultiIndex operations"
with pytest.raises(NotImplementedError, match=msg):
mi.where(listlike_box_with_tuple(cond))
mi.where(listlike_box(cond))


class TestContains:
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/numeric/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,14 @@ class TestWhere:
UInt64Index(np.arange(5, dtype="uint64")),
],
)
def test_where(self, listlike_box_with_tuple, index):
def test_where(self, listlike_box, index):
cond = [True] * len(index)
expected = index
result = index.where(listlike_box_with_tuple(cond))
result = index.where(listlike_box(cond))

cond = [False] + [True] * (len(index) - 1)
expected = Float64Index([index._na_value] + index[1:].tolist())
result = index.where(listlike_box_with_tuple(cond))
result = index.where(listlike_box(cond))
tm.assert_index_equal(result, expected)

def test_where_uint64(self):
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/period/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,16 +602,16 @@ def test_get_indexer2(self):


class TestWhere:
def test_where(self, listlike_box_with_tuple):
def test_where(self, listlike_box):
i = period_range("20130101", periods=5, freq="D")
cond = [True] * len(i)
expected = i
result = i.where(listlike_box_with_tuple(cond))
result = i.where(listlike_box(cond))
tm.assert_index_equal(result, expected)

cond = [False] + [True] * (len(i) - 1)
expected = PeriodIndex([NaT] + i[1:].tolist(), freq="D")
result = i.where(listlike_box_with_tuple(cond))
result = i.where(listlike_box(cond))
tm.assert_index_equal(result, expected)

def test_where_other(self):
Expand Down
10 changes: 5 additions & 5 deletions pandas/tests/io/formats/style/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ def test_replaced_css_class_names(styler_mi):
uuid_len=0,
).set_table_styles(css_class_names=css)
styler_mi.index.names = ["n1", "n2"]
styler_mi.hide_index(styler_mi.index[1:])
styler_mi.hide_columns(styler_mi.columns[1:])
styler_mi.hide(styler_mi.index[1:], axis=0)
styler_mi.hide(styler_mi.columns[1:], axis=1)
styler_mi.applymap_index(lambda v: "color: red;", axis=0)
styler_mi.applymap_index(lambda v: "color: green;", axis=1)
styler_mi.applymap(lambda v: "color: blue;")
Expand Down Expand Up @@ -611,9 +611,9 @@ def test_hiding_index_columns_multiindex_alignment():
)
df = DataFrame(np.arange(16).reshape(4, 4), index=midx, columns=cidx)
styler = Styler(df, uuid_len=0)
styler.hide_index(level=1).hide_columns(level=0)
styler.hide_index([("j0", "i1", "j2")])
styler.hide_columns([("c0", "d1", "d2")])
styler.hide(level=1, axis=0).hide(level=0, axis=1)
styler.hide([("j0", "i1", "j2")], axis=0)
styler.hide([("c0", "d1", "d2")], axis=1)
result = styler.to_html()
expected = dedent(
"""\
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/io/formats/style/test_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,7 @@ def test_hiding_headers_over_index_no_sparsify():
df = DataFrame(9, index=midx, columns=[0])
ctx = df.style._translate(False, False)
assert len(ctx["body"]) == 6
ctx = df.style.hide_index((1, "a"))._translate(False, False)
ctx = df.style.hide((1, "a"), axis=0)._translate(False, False)
assert len(ctx["body"]) == 4
assert "row2" in ctx["body"][0][0]["class"]

Expand Down
8 changes: 4 additions & 4 deletions pandas/tests/io/formats/style/test_to_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ def test_css_convert_apply_index(styler, axis):

def test_hide_index_latex(styler):
# GH 43637
styler.hide_index([0])
styler.hide([0], axis=0)
result = styler.to_latex()
expected = dedent(
"""\
Expand All @@ -826,9 +826,9 @@ def test_latex_hiding_index_columns_multiindex_alignment():
)
df = DataFrame(np.arange(16).reshape(4, 4), index=midx, columns=cidx)
styler = Styler(df, uuid_len=0)
styler.hide_index(level=1).hide_columns(level=0)
styler.hide_index([("i0", "i1", "i2")])
styler.hide_columns([("c0", "c1", "c2")])
styler.hide(level=1, axis=0).hide(level=0, axis=1)
styler.hide([("i0", "i1", "i2")], axis=0)
styler.hide([("c0", "c1", "c2")], axis=1)
styler.applymap(lambda x: "color:{red};" if x == 5 else "")
styler.applymap_index(lambda x: "color:{blue};" if "j" in x else "")
result = styler.to_latex()
Expand Down