Skip to content

CLN: generate_range #56416

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 1 commit into from
Dec 8, 2023
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
4 changes: 3 additions & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -2103,7 +2103,9 @@ def _validate_frequency(cls, index, freq: BaseOffset, **kwargs):
) from err

@classmethod
def _generate_range(cls, start, end, periods, freq, *args, **kwargs) -> Self:
def _generate_range(
cls, start, end, periods: int | None, freq, *args, **kwargs
) -> Self:
raise AbstractMethodError(cls)

# --------------------------------------------------------------
Expand Down
25 changes: 10 additions & 15 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ def _generate_range( # type: ignore[override]
cls,
start,
end,
periods,
periods: int | None,
freq,
tz=None,
normalize: bool = False,
Expand Down Expand Up @@ -441,9 +441,9 @@ def _generate_range( # type: ignore[override]
else:
unit = "ns"

if start is not None and unit is not None:
if start is not None:
start = start.as_unit(unit, round_ok=False)
if end is not None and unit is not None:
if end is not None:
end = end.as_unit(unit, round_ok=False)

left_inclusive, right_inclusive = validate_inclusive(inclusive)
Expand All @@ -452,14 +452,8 @@ def _generate_range( # type: ignore[override]

if tz is not None:
# Localize the start and end arguments
start_tz = None if start is None else start.tz
end_tz = None if end is None else end.tz
start = _maybe_localize_point(
start, start_tz, start, freq, tz, ambiguous, nonexistent
)
end = _maybe_localize_point(
end, end_tz, end, freq, tz, ambiguous, nonexistent
)
start = _maybe_localize_point(start, freq, tz, ambiguous, nonexistent)
end = _maybe_localize_point(end, freq, tz, ambiguous, nonexistent)

if freq is not None:
# We break Day arithmetic (fixed 24 hour) here and opt for
Expand Down Expand Up @@ -505,6 +499,7 @@ def _generate_range( # type: ignore[override]
# Nanosecond-granularity timestamps aren't always correctly
# representable with doubles, so we limit the range that we
# pass to np.linspace as much as possible
periods = cast(int, periods)
i8values = (
np.linspace(0, end._value - start._value, periods, dtype="int64")
+ start._value
Expand Down Expand Up @@ -2688,16 +2683,16 @@ def _maybe_normalize_endpoints(
return start, end


def _maybe_localize_point(ts, is_none, is_not_none, freq, tz, ambiguous, nonexistent):
def _maybe_localize_point(
ts: Timestamp | None, freq, tz, ambiguous, nonexistent
) -> Timestamp | None:
"""
Localize a start or end Timestamp to the timezone of the corresponding
start or end Timestamp

Parameters
----------
ts : start or end Timestamp to potentially localize
is_none : argument that should be None
is_not_none : argument that should not be None
freq : Tick, DateOffset, or None
tz : str, timezone object or None
ambiguous: str, localization behavior for ambiguous times
Expand All @@ -2710,7 +2705,7 @@ def _maybe_localize_point(ts, is_none, is_not_none, freq, tz, ambiguous, nonexis
# Make sure start and end are timezone localized if:
# 1) freq = a Timedelta-like frequency (Tick)
# 2) freq = None i.e. generating a linspaced range
if is_none is None and is_not_none is not None:
if ts is not None and ts.tzinfo is None:
# Note: We can't ambiguous='infer' a singular ambiguous time; however,
# we have historically defaulted ambiguous=False
ambiguous = ambiguous if ambiguous != "infer" else False
Expand Down