Skip to content

REF: Simplify Datetimelike constructor dispatching #23140

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

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f13cc58
Avoid non-public constructors
jbrockmendel Oct 13, 2018
4188ec7
simplify and de-duplicate _generate_range
jbrockmendel Oct 13, 2018
7804f1b
Check for invalid axis kwarg
jbrockmendel Oct 13, 2018
a4775f4
Move some EA properties up to mixins
jbrockmendel Oct 13, 2018
8ee34fa
implement basic TimedeltaArray tests
jbrockmendel Oct 13, 2018
78943c1
clean up PeriodArray constructor, with tests
jbrockmendel Oct 13, 2018
aa71383
make PeriodArray.__new__ more grown-up
jbrockmendel Oct 13, 2018
eae8389
Remove unused kwargs from TimedeltaArray.__new__
jbrockmendel Oct 13, 2018
e871733
revert change that broke tests
jbrockmendel Oct 13, 2018
7840f91
Fixup whitespace
jbrockmendel Oct 14, 2018
ec50b0b
helper function for axis validation
jbrockmendel Oct 14, 2018
eb7a6b6
suggested clarifications
jbrockmendel Oct 14, 2018
32c6391
Merge branch 'dlike8' of https://github.com/jbrockmendel/pandas into …
jbrockmendel Oct 14, 2018
c903917
Merge branch 'master' of https://github.com/pandas-dev/pandas into dl…
jbrockmendel Oct 14, 2018
b97ec96
move axis validation to nv
jbrockmendel Oct 14, 2018
11db555
Merge branch 'master' of https://github.com/pandas-dev/pandas into dl…
jbrockmendel Oct 14, 2018
147de57
revert some removals
jbrockmendel Oct 14, 2018
7c4d281
Merge branch 'master' of https://github.com/pandas-dev/pandas into dl…
jbrockmendel Oct 15, 2018
b90f421
catch too-negative values
jbrockmendel Oct 15, 2018
dc4f474
Roll validate_minmax_axis into existing validate functions
jbrockmendel Oct 15, 2018
46d5e64
fixup typo
jbrockmendel Oct 15, 2018
b5827c7
Merge branch 'master' of https://github.com/pandas-dev/pandas into dl…
jbrockmendel Oct 17, 2018
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
Prev Previous commit
Next Next commit
simplify and de-duplicate _generate_range
  • Loading branch information
jbrockmendel committed Oct 13, 2018
commit 4188ec725aebc0140f6b8be34b66e5ab8e1a94f9
10 changes: 8 additions & 2 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ def _validate_frequency(cls, index, freq, **kwargs):
# Frequency validation is not meaningful for Period Array/Index
return None

# DatetimeArray may pass `ambiguous`, nothing else allowed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this? can you comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will clarify this comment. kwargs gets passed below to cls._generate_range, and the only kwarg that is valid there is "ambiguous", and that is only for DatetimeArray.

assert all(key == 'ambiguous' for key in kwargs)

inferred = index.inferred_freq
if index.size == 0 or inferred == freq.freqstr:
return None
Expand Down Expand Up @@ -590,9 +593,12 @@ def _time_shift(self, periods, freq=None):

start = self[0] + periods * self.freq
end = self[-1] + periods * self.freq
attribs = self._get_attributes_dict()

# Note: in the DatetimeTZ case, _generate_range will infer the
# appropriate timezone from `start` and `end`, so tz does not need
# to be passed explicitly.
return self._generate_range(start=start, end=end, periods=None,
**attribs)
freq=self.freq)

@classmethod
def _add_datetimelike_methods(cls):
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def _generate_range(cls, start, end, periods, freq, fields):
freq = Period._maybe_convert_freq(freq)

field_count = len(fields)
if com.count_not_none(start, end) > 0:
if start is not None or end is not None:
if field_count > 0:
raise ValueError('Can either instantiate from fields '
'or endpoints, but not both')
Expand Down
6 changes: 2 additions & 4 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ def __new__(cls, values, freq=None, start=None, end=None, periods=None,
return result

@classmethod
def _generate_range(cls, start, end, periods, freq, closed=None, **kwargs):
# **kwargs are for compat with TimedeltaIndex, which includes `name`
def _generate_range(cls, start, end, periods, freq, closed=None):

periods = dtl.validate_periods(periods)
if freq is None and any(x is None for x in [periods, start, end]):
Expand All @@ -167,10 +166,9 @@ def _generate_range(cls, start, end, periods, freq, closed=None, **kwargs):

if freq is not None:
index = _generate_regular_range(start, end, periods, freq)
index = cls._simple_new(index, freq=freq, **kwargs)
index = cls._simple_new(index, freq=freq)
else:
index = np.linspace(start.value, end.value, periods).astype('i8')
# TODO: shouldn't we pass `name` here? (via **kwargs)
index = cls._simple_new(index, freq=freq)

if not left_closed:
Expand Down
6 changes: 6 additions & 0 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ def astype(self, dtype, copy=True):
raise TypeError(msg.format(name=type(self).__name__, dtype=dtype))
return super(DatetimeIndexOpsMixin, self).astype(dtype, copy=copy)

@Appender(DatetimeLikeArrayMixin._time_shift.__doc__)
def _time_shift(self, periods, freq=None):
result = DatetimeLikeArrayMixin._time_shift(self, periods, freq=freq)
result.name = self.name
return result


def _ensure_datetimelike_to_i8(other, to_utc=False):
"""
Expand Down
19 changes: 5 additions & 14 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ def __new__(cls, data=None,

if data is None:
# TODO: Remove this block and associated kwargs; GH#20535
return cls._generate_range(start, end, periods, name, freq,
tz=tz, normalize=normalize,
closed=closed, ambiguous=ambiguous)
out = cls._generate_range(start, end, periods,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out -> result

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update.

freq=freq, tz=tz, normalize=normalize,
closed=closed, ambiguous=ambiguous)
out.name = name
return out

if not isinstance(data, (np.ndarray, Index, ABCSeries,
DatetimeArrayMixin)):
Expand Down Expand Up @@ -315,17 +317,6 @@ def __new__(cls, data=None,

return subarr._deepcopy_if_needed(ref_to_data, copy)

@classmethod
@Appender(DatetimeArrayMixin._generate_range.__doc__)
def _generate_range(cls, start, end, periods, name=None, freq=None,
tz=None, normalize=False, ambiguous='raise',
closed=None):
out = super(DatetimeIndex, cls)._generate_range(
start, end, periods, freq,
tz=tz, normalize=normalize, ambiguous=ambiguous, closed=closed)
out.name = name
return out

@classmethod
def _use_cached_range(cls, freq, _normalized, start, end):
# Note: This always returns False
Expand Down
20 changes: 4 additions & 16 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,10 @@ def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,

if data is None:
# TODO: Remove this block and associated kwargs; GH#20535
if freq is None and com._any_none(periods, start, end):
raise ValueError('Must provide freq argument if no data is '
'supplied')
periods = dtl.validate_periods(periods)
return cls._generate_range(start, end, periods, name, freq,
closed=closed)
out = cls._generate_range(start, end, periods,
freq=freq, closed=closed)
out.name = name
return out

if unit is not None:
data = to_timedelta(data, unit=unit, box=False)
Expand Down Expand Up @@ -181,16 +179,6 @@ def __new__(cls, data=None, unit=None, freq=None, start=None, end=None,

return subarr

@classmethod
def _generate_range(cls, start, end, periods,
name=None, freq=None, closed=None):
# TimedeltaArray gets `name` via **kwargs, so we need to explicitly
# override it if name is passed as a positional argument
return super(TimedeltaIndex, cls)._generate_range(start, end,
periods, freq,
name=name,
closed=closed)

@classmethod
def _simple_new(cls, values, name=None, freq=None, **kwargs):
result = super(TimedeltaIndex, cls)._simple_new(values, freq, **kwargs)
Expand Down