Skip to content

Commit 165f3fd

Browse files
committed
Merge remote-tracking branch 'upstream/master' into disown-tz-only-rebased
2 parents eae133d + 9f2c716 commit 165f3fd

File tree

19 files changed

+934
-788
lines changed

19 files changed

+934
-788
lines changed

asv_bench/benchmarks/period.py

+4
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,17 @@ class PeriodIndexConstructor(object):
4343
def setup(self, freq):
4444
self.rng = date_range('1985', periods=1000)
4545
self.rng2 = date_range('1985', periods=1000).to_pydatetime()
46+
self.ints = list(range(2000, 3000))
4647

4748
def time_from_date_range(self, freq):
4849
PeriodIndex(self.rng, freq=freq)
4950

5051
def time_from_pydatetime(self, freq):
5152
PeriodIndex(self.rng2, freq=freq)
5253

54+
def time_from_ints(self, freq):
55+
PeriodIndex(self.ints, freq=freq)
56+
5357

5458
class DataFramePeriodColumn(object):
5559

ci/code_checks.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ fi
153153
### CODE ###
154154
if [[ -z "$CHECK" || "$CHECK" == "code" ]]; then
155155

156-
MSG='Check for modules that pandas should not import' ; echo $MSG
157-
python -c "
156+
MSG='Check import. No warnings, and blacklist some optional dependencies' ; echo $MSG
157+
python -W error -c "
158158
import sys
159159
import pandas
160160

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@ Timedelta
13121312
- Bug in :class:`TimedeltaIndex` where adding ``np.timedelta64('NaT')`` incorrectly returned an all-`NaT` :class:`DatetimeIndex` instead of an all-`NaT` :class:`TimedeltaIndex` (:issue:`23215`)
13131313
- Bug in :class:`Timedelta` and :func:`to_timedelta()` have inconsistencies in supported unit string (:issue:`21762`)
13141314
- Bug in :class:`TimedeltaIndex` division where dividing by another :class:`TimedeltaIndex` raised ``TypeError`` instead of returning a :class:`Float64Index` (:issue:`23829`, :issue:`22631`)
1315+
- Bug in :class:`TimedeltaIndex` comparison operations where comparing against non-``Timedelta``-like objects would raise ``TypeError`` instead of returning all-``False`` for ``__eq__`` and all-``True`` for ``__ne__`` (:issue:`24056`)
13151316

13161317
Timezones
13171318
^^^^^^^^^

pandas/_libs/tslibs/parsing.pyx

+5-5
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ def parse_time_string(arg, freq=None, dayfirst=None, yearfirst=None):
118118
if getattr(freq, "_typ", None) == "dateoffset":
119119
freq = freq.rule_code
120120

121-
if dayfirst is None:
121+
if dayfirst is None or yearfirst is None:
122122
from pandas.core.config import get_option
123-
dayfirst = get_option("display.date_dayfirst")
124-
if yearfirst is None:
125-
from pandas.core.config import get_option
126-
yearfirst = get_option("display.date_yearfirst")
123+
if dayfirst is None:
124+
dayfirst = get_option("display.date_dayfirst")
125+
if yearfirst is None:
126+
yearfirst = get_option("display.date_yearfirst")
127127

128128
res = parse_datetime_string_with_reso(arg, freq=freq,
129129
dayfirst=dayfirst,

pandas/compat/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ def lfilter(*args, **kwargs):
139139
Hashable = collections.abc.Hashable
140140
Iterable = collections.abc.Iterable
141141
Mapping = collections.abc.Mapping
142+
MutableMapping = collections.abc.MutableMapping
142143
Sequence = collections.abc.Sequence
143144
Sized = collections.abc.Sized
144145
Set = collections.abc.Set
@@ -200,6 +201,7 @@ def get_range_parameters(data):
200201
Hashable = collections.Hashable
201202
Iterable = collections.Iterable
202203
Mapping = collections.Mapping
204+
MutableMapping = collections.MutableMapping
203205
Sequence = collections.Sequence
204206
Sized = collections.Sized
205207
Set = collections.Set

pandas/core/arrays/categorical.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,12 @@ def __init__(self, values, categories=None, ordered=None, dtype=None,
380380
dtype = CategoricalDtype(values.categories, dtype.ordered)
381381

382382
elif not isinstance(values, (ABCIndexClass, ABCSeries)):
383-
# _sanitize_array coerces np.nan to a string under certain versions
383+
# sanitize_array coerces np.nan to a string under certain versions
384384
# of numpy
385385
values = maybe_infer_to_datetimelike(values, convert_dates=True)
386386
if not isinstance(values, np.ndarray):
387387
values = _convert_to_list_like(values)
388-
from pandas.core.series import _sanitize_array
388+
from pandas.core.internals.construction import sanitize_array
389389
# By convention, empty lists result in object dtype:
390390
if len(values) == 0:
391391
sanitize_dtype = 'object'
@@ -394,7 +394,7 @@ def __init__(self, values, categories=None, ordered=None, dtype=None,
394394
null_mask = isna(values)
395395
if null_mask.any():
396396
values = [values[idx] for idx in np.where(~null_mask)[0]]
397-
values = _sanitize_array(values, None, dtype=sanitize_dtype)
397+
values = sanitize_array(values, None, dtype=sanitize_dtype)
398398

399399
if dtype.categories is None:
400400
try:
@@ -2442,12 +2442,12 @@ def isin(self, values):
24422442
>>> s.isin(['lama'])
24432443
array([ True, False, True, False, True, False])
24442444
"""
2445-
from pandas.core.series import _sanitize_array
2445+
from pandas.core.internals.construction import sanitize_array
24462446
if not is_list_like(values):
24472447
raise TypeError("only list-like objects are allowed to be passed"
24482448
" to isin(), you passed a [{values_type}]"
24492449
.format(values_type=type(values).__name__))
2450-
values = _sanitize_array(values, None, None)
2450+
values = sanitize_array(values, None, None)
24512451
null_mask = np.asarray(isna(values))
24522452
code_values = self.categories.get_indexer(values)
24532453
code_values = code_values[null_mask | (code_values >= 0)]

pandas/core/arrays/datetimes.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def f(self):
8383
return result
8484

8585
f.__name__ = name
86-
f.__doc__ = docstring
86+
f.__doc__ = "\n{}\n".format(docstring)
8787
return property(f)
8888

8989

@@ -192,6 +192,9 @@ class DatetimeArrayMixin(dtl.DatetimeLikeArrayMixin,
192192
# by returning NotImplemented
193193
timetuple = None
194194

195+
# Needed so that Timestamp.__richcmp__(DateTimeArray) operates pointwise
196+
ndim = 1
197+
195198
# ensure that operations with numpy arrays defer to our implementation
196199
__array_priority__ = 1000
197200

@@ -246,6 +249,12 @@ def __new__(cls, values, freq=None, tz=None, dtype=None):
246249
# if dtype has an embedded tz, capture it
247250
tz = dtl.validate_tz_from_dtype(dtype, tz)
248251

252+
if not hasattr(values, "dtype"):
253+
if np.ndim(values) == 0:
254+
# i.e. iterator
255+
values = list(values)
256+
values = np.array(values)
257+
249258
if is_object_dtype(values):
250259
# kludge; dispatch until the DatetimeArray constructor is complete
251260
from pandas import DatetimeIndex
@@ -1227,12 +1236,12 @@ def date(self):
12271236
"The name of day in a week (ex: Friday)\n\n.. deprecated:: 0.23.0")
12281237

12291238
dayofyear = _field_accessor('dayofyear', 'doy',
1230-
"\nThe ordinal day of the year\n")
1231-
quarter = _field_accessor('quarter', 'q', "\nThe quarter of the date\n")
1239+
"The ordinal day of the year.")
1240+
quarter = _field_accessor('quarter', 'q', "The quarter of the date.")
12321241
days_in_month = _field_accessor(
12331242
'days_in_month',
12341243
'dim',
1235-
"\nThe number of days in the month\n")
1244+
"The number of days in the month.")
12361245
daysinmonth = days_in_month
12371246
_is_month_doc = """
12381247
Indicates whether the date is the {first_or_last} day of the month.

pandas/core/arrays/sparse.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,8 @@ def __init__(self, data, sparse_index=None, index=None, fill_value=None,
631631
if not is_array_like(data):
632632
try:
633633
# probably shared code in sanitize_series
634-
from pandas.core.series import _sanitize_array
635-
data = _sanitize_array(data, index=None)
634+
from pandas.core.internals.construction import sanitize_array
635+
data = sanitize_array(data, index=None)
636636
except ValueError:
637637
# NumPy may raise a ValueError on data like [1, []]
638638
# we retry with object dtype here.

pandas/core/arrays/timedeltas.py

+23-15
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
ABCDataFrame, ABCIndexClass, ABCSeries, ABCTimedeltaIndex)
2424
from pandas.core.dtypes.missing import isna
2525

26+
from pandas.core import ops
2627
from pandas.core.algorithms import checked_add_with_arr, unique1d
2728
import pandas.core.common as com
2829

@@ -60,7 +61,7 @@ def f(self):
6061
return result
6162

6263
f.__name__ = name
63-
f.__doc__ = docstring
64+
f.__doc__ = "\n{}\n".format(docstring)
6465
return property(f)
6566

6667

@@ -71,25 +72,29 @@ def _td_array_cmp(cls, op):
7172
opname = '__{name}__'.format(name=op.__name__)
7273
nat_result = True if opname == '__ne__' else False
7374

75+
meth = getattr(dtl.DatetimeLikeArrayMixin, opname)
76+
7477
def wrapper(self, other):
75-
msg = "cannot compare a {cls} with type {typ}"
76-
meth = getattr(dtl.DatetimeLikeArrayMixin, opname)
7778
if _is_convertible_to_td(other) or other is NaT:
7879
try:
7980
other = _to_m8(other)
8081
except ValueError:
8182
# failed to parse as timedelta
82-
raise TypeError(msg.format(cls=type(self).__name__,
83-
typ=type(other).__name__))
83+
return ops.invalid_comparison(self, other, op)
84+
8485
result = meth(self, other)
8586
if isna(other):
8687
result.fill(nat_result)
8788

8889
elif not is_list_like(other):
89-
raise TypeError(msg.format(cls=type(self).__name__,
90-
typ=type(other).__name__))
90+
return ops.invalid_comparison(self, other, op)
91+
9192
else:
92-
other = type(self)(other)._data
93+
try:
94+
other = type(self)(other)._data
95+
except (ValueError, TypeError):
96+
return ops.invalid_comparison(self, other, op)
97+
9398
result = meth(self, other)
9499
result = com.values_from_object(result)
95100

@@ -118,6 +123,9 @@ class TimedeltaArrayMixin(dtl.DatetimeLikeArrayMixin, dtl.TimelikeOps):
118123
_datetimelike_methods = ["to_pytimedelta", "total_seconds",
119124
"round", "floor", "ceil"]
120125

126+
# Needed so that NaT.__richcmp__(DateTimeArray) operates pointwise
127+
ndim = 1
128+
121129
@property
122130
def _box_func(self):
123131
return lambda x: Timedelta(x, unit='ns')
@@ -747,16 +755,16 @@ def _format_native_types(self):
747755
return self.astype(object)
748756

749757
days = _field_accessor("days", "days",
750-
"\nNumber of days for each element.\n")
758+
"Number of days for each element.")
751759
seconds = _field_accessor("seconds", "seconds",
752-
"\nNumber of seconds (>= 0 and less than 1 day) "
753-
"for each element.\n")
760+
"Number of seconds (>= 0 and less than 1 day) "
761+
"for each element.")
754762
microseconds = _field_accessor("microseconds", "microseconds",
755-
"\nNumber of microseconds (>= 0 and less "
756-
"than 1 second) for each element.\n")
763+
"Number of microseconds (>= 0 and less "
764+
"than 1 second) for each element.")
757765
nanoseconds = _field_accessor("nanoseconds", "nanoseconds",
758-
"\nNumber of nanoseconds (>= 0 and less "
759-
"than 1 microsecond) for each element.\n")
766+
"Number of nanoseconds (>= 0 and less "
767+
"than 1 microsecond) for each element.")
760768

761769
@property
762770
def components(self):

0 commit comments

Comments
 (0)