Skip to content

Commit d824414

Browse files
committed
Merge remote-tracking branch 'repo_org/master' into check_np_pd_fromExamples
* repo_org/master: DOC: Validate that See Also section items do not contain the pandas. prefix (pandas-dev#23145) API/TST: make hasnans always return python booleans (pandas-dev#23349)
2 parents 881b011 + da9d851 commit d824414

File tree

13 files changed

+69
-50
lines changed

13 files changed

+69
-50
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ Other API Changes
910910
has an improved ``KeyError`` message, and will not fail on duplicate column names with ``drop=True``. (:issue:`22484`)
911911
- Slicing a single row of a DataFrame with multiple ExtensionArrays of the same type now preserves the dtype, rather than coercing to object (:issue:`22784`)
912912
- :class:`DateOffset` attribute `_cacheable` and method `_should_cache` have been removed (:issue:`23118`)
913+
- :meth:`Index.hasnans` and :meth:`Series.hasnans` now always return a python boolean. Previously, a python or a numpy boolean could be returned, depending on circumstances (:issue:`23294`).
913914

914915
.. _whatsnew_0240.deprecations:
915916

pandas/core/arrays/datetimelike.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def _isnan(self):
219219
@property # NB: override with cache_readonly in immutable subclasses
220220
def hasnans(self):
221221
""" return if I have any nans; enables various perf speedups """
222-
return self._isnan.any()
222+
return bool(self._isnan.any())
223223

224224
def _maybe_mask_results(self, result, fill_value=None, convert=None):
225225
"""

pandas/core/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ def __iter__(self):
889889
@cache_readonly
890890
def hasnans(self):
891891
""" return if I have any nans; enables various perf speedups """
892-
return isna(self).any()
892+
return bool(isna(self).any())
893893

894894
def _reduce(self, op, name, axis=0, skipna=True, numeric_only=None,
895895
filter_type=None, **kwds):

pandas/core/indexes/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2221,7 +2221,7 @@ def _nan_idxs(self):
22212221
def hasnans(self):
22222222
""" return if I have any nans; enables various perf speedups """
22232223
if self._can_hold_na:
2224-
return self._isnan.any()
2224+
return bool(self._isnan.any())
22252225
else:
22262226
return False
22272227

pandas/tests/indexes/common.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ def test_get_unique_index(self, indices):
417417
# and doesn't contain nans.
418418
assert idx_unique.is_unique is True
419419
try:
420-
assert not idx_unique.hasnans
420+
assert idx_unique.hasnans is False
421421
except NotImplementedError:
422422
pass
423423

@@ -916,7 +916,7 @@ def test_hasnans_isnans(self):
916916
# cases in indices doesn't include NaN
917917
expected = np.array([False] * len(idx), dtype=bool)
918918
tm.assert_numpy_array_equal(idx._isnan, expected)
919-
assert not idx.hasnans
919+
assert idx.hasnans is False
920920

921921
idx = index.copy()
922922
values = np.asarray(idx.values)
@@ -938,7 +938,7 @@ def test_hasnans_isnans(self):
938938
expected = np.array([False] * len(idx), dtype=bool)
939939
expected[1] = True
940940
tm.assert_numpy_array_equal(idx._isnan, expected)
941-
assert idx.hasnans
941+
assert idx.hasnans is True
942942

943943
def test_fillna(self):
944944
# GH 11343
@@ -978,7 +978,7 @@ def test_fillna(self):
978978
expected = np.array([False] * len(idx), dtype=bool)
979979
expected[1] = True
980980
tm.assert_numpy_array_equal(idx._isnan, expected)
981-
assert idx.hasnans
981+
assert idx.hasnans is True
982982

983983
def test_nulls(self):
984984
# this is really a smoke test for the methods

pandas/tests/indexes/datetimes/test_ops.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -356,15 +356,15 @@ def test_nat(self, tz_naive_fixture):
356356
assert idx._can_hold_na
357357

358358
tm.assert_numpy_array_equal(idx._isnan, np.array([False, False]))
359-
assert not idx.hasnans
359+
assert idx.hasnans is False
360360
tm.assert_numpy_array_equal(idx._nan_idxs,
361361
np.array([], dtype=np.intp))
362362

363363
idx = pd.DatetimeIndex(['2011-01-01', 'NaT'], tz=tz)
364364
assert idx._can_hold_na
365365

366366
tm.assert_numpy_array_equal(idx._isnan, np.array([False, True]))
367-
assert idx.hasnans
367+
assert idx.hasnans is True
368368
tm.assert_numpy_array_equal(idx._nan_idxs,
369369
np.array([1], dtype=np.intp))
370370

pandas/tests/indexes/interval/test_interval.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_length(self, closed, breaks):
9393

9494
def test_with_nans(self, closed):
9595
index = self.create_index(closed=closed)
96-
assert not index.hasnans
96+
assert index.hasnans is False
9797

9898
result = index.isna()
9999
expected = np.repeat(False, len(index))
@@ -104,7 +104,7 @@ def test_with_nans(self, closed):
104104
tm.assert_numpy_array_equal(result, expected)
105105

106106
index = self.create_index_with_nan(closed=closed)
107-
assert index.hasnans
107+
assert index.hasnans is True
108108

109109
result = index.isna()
110110
expected = np.array([False, True] + [False] * (len(index) - 2))

pandas/tests/indexes/multi/test_missing.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def test_fillna(idx):
4949
expected = np.array([False] * len(idx), dtype=bool)
5050
expected[1] = True
5151
tm.assert_numpy_array_equal(idx._isnan, expected)
52-
assert idx.hasnans
52+
assert idx.hasnans is True
5353

5454

5555
def test_dropna():
@@ -91,7 +91,7 @@ def test_hasnans_isnans(idx):
9191
# cases in indices doesn't include NaN
9292
expected = np.array([False] * len(index), dtype=bool)
9393
tm.assert_numpy_array_equal(index._isnan, expected)
94-
assert not index.hasnans
94+
assert index.hasnans is False
9595

9696
index = idx.copy()
9797
values = index.values
@@ -102,7 +102,7 @@ def test_hasnans_isnans(idx):
102102
expected = np.array([False] * len(index), dtype=bool)
103103
expected[1] = True
104104
tm.assert_numpy_array_equal(index._isnan, expected)
105-
assert index.hasnans
105+
assert index.hasnans is True
106106

107107

108108
def test_nan_stays_float():

pandas/tests/indexes/period/test_ops.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -356,15 +356,15 @@ def test_nat(self):
356356
assert idx._can_hold_na
357357

358358
tm.assert_numpy_array_equal(idx._isnan, np.array([False, False]))
359-
assert not idx.hasnans
359+
assert idx.hasnans is False
360360
tm.assert_numpy_array_equal(idx._nan_idxs,
361361
np.array([], dtype=np.intp))
362362

363363
idx = pd.PeriodIndex(['2011-01-01', 'NaT'], freq='D')
364364
assert idx._can_hold_na
365365

366366
tm.assert_numpy_array_equal(idx._isnan, np.array([False, True]))
367-
assert idx.hasnans
367+
assert idx.hasnans is True
368368
tm.assert_numpy_array_equal(idx._nan_idxs,
369369
np.array([1], dtype=np.intp))
370370

pandas/tests/indexes/timedeltas/test_ops.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -273,15 +273,15 @@ def test_nat(self):
273273
assert idx._can_hold_na
274274

275275
tm.assert_numpy_array_equal(idx._isnan, np.array([False, False]))
276-
assert not idx.hasnans
276+
assert idx.hasnans is False
277277
tm.assert_numpy_array_equal(idx._nan_idxs,
278278
np.array([], dtype=np.intp))
279279

280280
idx = pd.TimedeltaIndex(['1 days', 'NaT'])
281281
assert idx._can_hold_na
282282

283283
tm.assert_numpy_array_equal(idx._isnan, np.array([False, True]))
284-
assert idx.hasnans
284+
assert idx.hasnans is True
285285
tm.assert_numpy_array_equal(idx._nan_idxs,
286286
np.array([1], dtype=np.intp))
287287

pandas/tests/series/test_internals.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ def test_convert_preserve_all_bool(self):
315315
def test_hasnans_unchached_for_series():
316316
# GH#19700
317317
idx = pd.Index([0, 1])
318-
assert not idx.hasnans
318+
assert idx.hasnans is False
319319
assert 'hasnans' in idx._cache
320320
ser = idx.to_series()
321-
assert not ser.hasnans
321+
assert ser.hasnans is False
322322
assert not hasattr(ser, '_cache')
323323
ser.iloc[-1] = np.nan
324-
assert ser.hasnans
324+
assert ser.hasnans is True
325325
assert pd.Series.hasnans.__doc__ == pd.Index.hasnans.__doc__

scripts/tests/test_validate_docstrings.py

+43-28
Original file line numberDiff line numberDiff line change
@@ -346,33 +346,6 @@ def method(self, foo=None, bar=None):
346346
pass
347347

348348

349-
class BadSeeAlso(object):
350-
351-
def desc_no_period(self):
352-
"""
353-
Return the first 5 elements of the Series.
354-
355-
See Also
356-
--------
357-
Series.tail : Return the last 5 elements of the Series.
358-
Series.iloc : Return a slice of the elements in the Series,
359-
which can also be used to return the first or last n
360-
"""
361-
pass
362-
363-
def desc_first_letter_lowercase(self):
364-
"""
365-
Return the first 5 elements of the Series.
366-
367-
See Also
368-
--------
369-
Series.tail : return the last 5 elements of the Series.
370-
Series.iloc : Return a slice of the elements in the Series,
371-
which can also be used to return the first or last n.
372-
"""
373-
pass
374-
375-
376349
class BadSummaries(object):
377350

378351
def wrong_line(self):
@@ -585,6 +558,44 @@ def no_punctuation(self):
585558
return "Hello world!"
586559

587560

561+
class BadSeeAlso(object):
562+
563+
def desc_no_period(self):
564+
"""
565+
Return the first 5 elements of the Series.
566+
567+
See Also
568+
--------
569+
Series.tail : Return the last 5 elements of the Series.
570+
Series.iloc : Return a slice of the elements in the Series,
571+
which can also be used to return the first or last n
572+
"""
573+
pass
574+
575+
def desc_first_letter_lowercase(self):
576+
"""
577+
Return the first 5 elements of the Series.
578+
579+
See Also
580+
--------
581+
Series.tail : return the last 5 elements of the Series.
582+
Series.iloc : Return a slice of the elements in the Series,
583+
which can also be used to return the first or last n.
584+
"""
585+
pass
586+
587+
def prefix_pandas(self):
588+
"""
589+
Have `pandas` prefix in See Also section.
590+
591+
See Also
592+
--------
593+
pandas.Series.rename : Alter Series index labels or name.
594+
DataFrame.head : The first `n` rows of the caller object.
595+
"""
596+
pass
597+
598+
588599
class TestValidator(object):
589600

590601
def _import_path(self, klass=None, func=None):
@@ -705,7 +716,11 @@ def test_bad_generic_functions(self, func):
705716
('BadGenericDocStrings', 'method',
706717
('Examples should not have `import numpy` ',)),
707718
('BadGenericDocStrings', 'method',
708-
('Examples should not have `import pandas` ',))
719+
('Examples should not have `import pandas` ',)),
720+
# See Also tests
721+
('BadSeeAlso', 'prefix_pandas',
722+
('pandas.Series.rename in `See Also` section '
723+
'does not need `pandas` prefix',))
709724
])
710725
def test_bad_examples(self, capsys, klass, func, msgs):
711726
result = validate_one(self._import_path(klass=klass, func=func)) # noqa:F821

scripts/validate_docstrings.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,10 @@ def validate_one(func_name):
521521
else:
522522
errs.append('Missing description for '
523523
'See Also "{}" reference'.format(rel_name))
524-
524+
if rel_name.startswith('pandas.'):
525+
errs.append('{} in `See Also` section does not '
526+
'need `pandas` prefix, use {} instead.'
527+
.format(rel_name, rel_name[len('pandas.'):]))
525528
for line in doc.raw_doc.splitlines():
526529
if re.match("^ *\t", line):
527530
errs.append('Tabs found at the start of line "{}", '

0 commit comments

Comments
 (0)