Skip to content
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

Refactor timezones functions out of tslib #17274

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 3 additions & 4 deletions pandas/_libs/index.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ from datetime import datetime, timedelta
from datetime cimport (get_datetime64_value, _pydatetime_to_dts,
pandas_datetimestruct)

from tslibs.timezones cimport _get_utcoffset, _is_utc

from cpython cimport PyTuple_Check, PyList_Check

cdef extern from "datetime.h":
Expand Down Expand Up @@ -554,14 +556,11 @@ cdef inline _to_i8(object val):
# Save the original date value so we can get the utcoffset from it.
ival = _pydatetime_to_dts(val, &dts)
if tzinfo is not None and not _is_utc(tzinfo):
offset = tslib._get_utcoffset(tzinfo, val)
offset = _get_utcoffset(tzinfo, val)
ival -= tslib._delta_to_nanoseconds(offset)
return ival
return val

cdef inline bint _is_utc(object tz):
return tz is UTC or isinstance(tz, _du_utc)


cdef class MultiIndexObjectEngine(ObjectEngine):
"""
Expand Down
48 changes: 26 additions & 22 deletions pandas/_libs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ from numpy cimport (int8_t, int32_t, int64_t, import_array, ndarray,
NPY_INT64, NPY_DATETIME, NPY_TIMEDELTA)
import numpy as np

cdef extern from "datetime_helper.h":
double total_seconds(object)

from libc.stdlib cimport free

from pandas import compat
from pandas.compat import PY2
from pandas.core.dtypes.generic import ABCDateOffset
Copy link
Member Author

Choose a reason for hiding this comment

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

An upcoming PR will make a cython version of dtypes.generic. The isinstance checks are about 2x faster that way. It's a small difference, but nice to avoid calling into python for these things.

Copy link
Contributor

Choose a reason for hiding this comment

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

let's keep perf changes separate. I would much prefer PR's that don't mix multiple changes all at once.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK. I just pushed a commit that reverted from ABCDateOffset back to offsets.DateOffset.


cimport cython

cdef extern from "datetime.h":
void PyDateTime_IMPORT()

from datetime cimport (
is_leapyear,
PyDateTime_IMPORT,
pandas_datetimestruct,
pandas_datetimestruct_to_datetime,
pandas_datetime_to_datetimestruct,
Expand All @@ -32,16 +32,17 @@ from datetime cimport (
cimport util, lib
from lib cimport is_null_datetimelike, is_period
from pandas._libs import tslib, lib
from pandas._libs.tslib import (Timedelta, Timestamp, iNaT,
NaT, _get_utcoffset)
from tslib cimport (
maybe_get_tz,
_is_utc,
_is_tzlocal,
from pandas._libs.tslib import Timestamp, iNaT, NaT
from tslib cimport _nat_scalar_rules

from tslibs.timezones cimport (
total_seconds,
_get_utcoffset,
_get_dst_info,
_nat_scalar_rules)
_is_tzlocal,
_is_utc,
maybe_get_tz)

from pandas.tseries import offsets
from pandas.core.tools.datetimes import parse_time_string
from pandas.tseries import frequencies

Expand Down Expand Up @@ -117,9 +118,16 @@ cdef extern from "period_helper.h":

initialize_daytime_conversion_factor_matrix()


cpdef _is_tick(item):
# offsets.Tick subclasses offsets.DateOffset and has a "_inc" attribute
return isinstance(item, ABCDateOffset) and hasattr(item, "_inc")


# Period logic
#----------------------------------------------------------------------

# TODO: never used?
cdef inline int64_t apply_mult(int64_t period_ord, int64_t mult):
"""
Get freq+multiple ordinal value from corresponding freq-only ordinal value.
Expand All @@ -131,6 +139,7 @@ cdef inline int64_t apply_mult(int64_t period_ord, int64_t mult):

return (period_ord - 1) // mult

# TODO: never used?
cdef inline int64_t remove_mult(int64_t period_ord_w_mult, int64_t mult):
"""
Get freq-only ordinal value from corresponding freq+multiple ordinal.
Expand Down Expand Up @@ -746,10 +755,9 @@ cdef class _Period(object):
return hash((self.ordinal, self.freqstr))

def _add_delta(self, other):
if isinstance(other, (timedelta, np.timedelta64,
offsets.Tick, Timedelta)):
if isinstance(other, (timedelta, np.timedelta64)) or _is_tick(other):
offset = frequencies.to_offset(self.freq.rule_code)
if isinstance(offset, offsets.Tick):
if _is_tick(offset):
nanos = tslib._delta_to_nanoseconds(other)
offset_nanos = tslib._delta_to_nanoseconds(offset)

Expand All @@ -758,7 +766,7 @@ cdef class _Period(object):
return Period(ordinal=ordinal, freq=self.freq)
msg = 'Input cannot be converted to Period(freq={0})'
raise IncompatibleFrequency(msg.format(self.freqstr))
elif isinstance(other, offsets.DateOffset):
elif isinstance(other, ABCDateOffset):
freqstr = other.rule_code
base = frequencies.get_base_alias(freqstr)
if base == self.freq.rule_code:
Expand All @@ -771,9 +779,7 @@ cdef class _Period(object):

def __add__(self, other):
if isinstance(self, Period):
if isinstance(other, (timedelta, np.timedelta64,
offsets.Tick, offsets.DateOffset,
Timedelta)):
if isinstance(other, (timedelta, np.timedelta64, ABCDateOffset)):
Copy link
Member Author

Choose a reason for hiding this comment

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

Timedelta subclasses timedelta and Tick subclasses DateOffset, so we can remove them from these checks.

return self._add_delta(other)
elif other is NaT:
return NaT
Expand All @@ -789,9 +795,7 @@ cdef class _Period(object):

def __sub__(self, other):
if isinstance(self, Period):
if isinstance(other, (timedelta, np.timedelta64,
offsets.Tick, offsets.DateOffset,
Timedelta)):
if isinstance(other, (timedelta, np.timedelta64, ABCDateOffset)):
neg_other = -other
return self + neg_other
elif lib.is_integer(other):
Expand Down
4 changes: 0 additions & 4 deletions pandas/_libs/tslib.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@ from numpy cimport ndarray, int64_t

cdef convert_to_tsobject(object, object, object, bint, bint)
cpdef convert_to_timedelta64(object, object)
cpdef object maybe_get_tz(object)
cdef bint _is_utc(object)
cdef bint _is_tzlocal(object)
cdef object _get_dst_info(object)
cdef bint _nat_scalar_rules[6]
cdef bint _check_all_nulls(obj)
Loading