|
1 | 1 | # -*- coding: utf-8 -*-
|
2 | 2 | # cython: profile=False
|
| 3 | +# cython: linetrace=False |
| 4 | +# distutils: define_macros=CYTHON_TRACE=0 |
| 5 | +# distutils: define_macros=CYTHON_TRACE_NOGIL=0 |
3 | 6 |
|
4 | 7 | cimport numpy as np
|
5 | 8 | from numpy cimport (int8_t, int32_t, int64_t, import_array, ndarray,
|
@@ -79,7 +82,6 @@ PyDateTime_IMPORT
|
79 | 82 | cdef int64_t NPY_NAT = util.get_nat()
|
80 | 83 | iNaT = NPY_NAT
|
81 | 84 |
|
82 |
| - |
83 | 85 | from tslibs.timezones cimport (
|
84 | 86 | is_utc, is_tzlocal, is_fixed_offset,
|
85 | 87 | treat_tz_as_dateutil, treat_tz_as_pytz,
|
@@ -783,6 +785,32 @@ class Timestamp(_Timestamp):
|
783 | 785 | _nat_strings = set(['NaT', 'nat', 'NAT', 'nan', 'NaN', 'NAN'])
|
784 | 786 |
|
785 | 787 |
|
| 788 | +def _make_nat_func(func_name, cls): |
| 789 | + def f(*args, **kwargs): |
| 790 | + return NaT |
| 791 | + f.__name__ = func_name |
| 792 | + f.__doc__ = getattr(cls, func_name).__doc__ |
| 793 | + return f |
| 794 | + |
| 795 | + |
| 796 | +def _make_nan_func(func_name, cls): |
| 797 | + def f(*args, **kwargs): |
| 798 | + return np.nan |
| 799 | + f.__name__ = func_name |
| 800 | + f.__doc__ = getattr(cls, func_name).__doc__ |
| 801 | + return f |
| 802 | + |
| 803 | + |
| 804 | +def _make_error_func(func_name, cls): |
| 805 | + def f(*args, **kwargs): |
| 806 | + raise ValueError("NaTType does not support " + func_name) |
| 807 | + |
| 808 | + f.__name__ = func_name |
| 809 | + if cls is not None: |
| 810 | + f.__doc__ = getattr(cls, func_name).__doc__ |
| 811 | + return f |
| 812 | + |
| 813 | + |
786 | 814 | class NaTType(_NaT):
|
787 | 815 | """(N)ot-(A)-(T)ime, the time equivalent of NaN"""
|
788 | 816 |
|
@@ -865,6 +893,90 @@ class NaTType(_NaT):
|
865 | 893 | return NaT
|
866 | 894 | return NotImplemented
|
867 | 895 |
|
| 896 | + # ---------------------------------------------------------------------- |
| 897 | + # inject the Timestamp field properties |
| 898 | + # these by definition return np.nan |
| 899 | + |
| 900 | + year = property(fget=lambda self: np.nan) |
| 901 | + quarter = property(fget=lambda self: np.nan) |
| 902 | + month = property(fget=lambda self: np.nan) |
| 903 | + day = property(fget=lambda self: np.nan) |
| 904 | + hour = property(fget=lambda self: np.nan) |
| 905 | + minute = property(fget=lambda self: np.nan) |
| 906 | + second = property(fget=lambda self: np.nan) |
| 907 | + millisecond = property(fget=lambda self: np.nan) |
| 908 | + microsecond = property(fget=lambda self: np.nan) |
| 909 | + nanosecond = property(fget=lambda self: np.nan) |
| 910 | + |
| 911 | + week = property(fget=lambda self: np.nan) |
| 912 | + dayofyear = property(fget=lambda self: np.nan) |
| 913 | + weekofyear = property(fget=lambda self: np.nan) |
| 914 | + days_in_month = property(fget=lambda self: np.nan) |
| 915 | + daysinmonth = property(fget=lambda self: np.nan) |
| 916 | + dayofweek = property(fget=lambda self: np.nan) |
| 917 | + weekday_name = property(fget=lambda self: np.nan) |
| 918 | + |
| 919 | + # inject Timedelta properties |
| 920 | + days = property(fget=lambda self: np.nan) |
| 921 | + seconds = property(fget=lambda self: np.nan) |
| 922 | + microseconds = property(fget=lambda self: np.nan) |
| 923 | + nanoseconds = property(fget=lambda self: np.nan) |
| 924 | + |
| 925 | + # inject pd.Period properties |
| 926 | + qyear = property(fget=lambda self: np.nan) |
| 927 | + |
| 928 | + # ---------------------------------------------------------------------- |
| 929 | + # GH9513 NaT methods (except to_datetime64) to raise, return np.nan, or |
| 930 | + # return NaT create functions that raise, for binding to NaTType |
| 931 | + # These are the ones that can get their docstrings from datetime. |
| 932 | + |
| 933 | + # nan methods |
| 934 | + weekday = _make_nan_func('weekday', datetime) |
| 935 | + isoweekday = _make_nan_func('isoweekday', datetime) |
| 936 | + |
| 937 | + # _nat_methods |
| 938 | + date = _make_nat_func('date', datetime) |
| 939 | + |
| 940 | + utctimetuple = _make_error_func('utctimetuple', datetime) |
| 941 | + timetz = _make_error_func('timetz', datetime) |
| 942 | + timetuple = _make_error_func('timetuple', datetime) |
| 943 | + strptime = _make_error_func('strptime', datetime) |
| 944 | + strftime = _make_error_func('strftime', datetime) |
| 945 | + isocalendar = _make_error_func('isocalendar', datetime) |
| 946 | + dst = _make_error_func('dst', datetime) |
| 947 | + ctime = _make_error_func('ctime', datetime) |
| 948 | + time = _make_error_func('time', datetime) |
| 949 | + toordinal = _make_error_func('toordinal', datetime) |
| 950 | + tzname = _make_error_func('tzname', datetime) |
| 951 | + utcoffset = _make_error_func('utcoffset', datetime) |
| 952 | + |
| 953 | + # Timestamp has empty docstring for some methods. |
| 954 | + utcfromtimestamp = _make_error_func('utcfromtimestamp', None) |
| 955 | + fromtimestamp = _make_error_func('fromtimestamp', None) |
| 956 | + combine = _make_error_func('combine', None) |
| 957 | + utcnow = _make_error_func('utcnow', None) |
| 958 | + |
| 959 | + if PY3: |
| 960 | + timestamp = _make_error_func('timestamp', datetime) |
| 961 | + |
| 962 | + # GH9513 NaT methods (except to_datetime64) to raise, return np.nan, or |
| 963 | + # return NaT create functions that raise, for binding to NaTType |
| 964 | + astimezone = _make_error_func('astimezone', Timestamp) |
| 965 | + fromordinal = _make_error_func('fromordinal', Timestamp) |
| 966 | + |
| 967 | + # _nat_methods |
| 968 | + to_pydatetime = _make_nat_func('to_pydatetime', Timestamp) |
| 969 | + |
| 970 | + now = _make_nat_func('now', Timestamp) |
| 971 | + today = _make_nat_func('today', Timestamp) |
| 972 | + round = _make_nat_func('round', Timestamp) |
| 973 | + floor = _make_nat_func('floor', Timestamp) |
| 974 | + ceil = _make_nat_func('ceil', Timestamp) |
| 975 | + |
| 976 | + tz_convert = _make_nat_func('tz_convert', Timestamp) |
| 977 | + tz_localize = _make_nat_func('tz_localize', Timestamp) |
| 978 | + replace = _make_nat_func('replace', Timestamp) |
| 979 | + |
868 | 980 |
|
869 | 981 | def __nat_unpickle(*args):
|
870 | 982 | # return constant defined in the module
|
@@ -1323,6 +1435,7 @@ cdef _nat_rdivide_op(self, other):
|
1323 | 1435 | return np.nan
|
1324 | 1436 | return NotImplemented
|
1325 | 1437 |
|
| 1438 | + |
1326 | 1439 | cdef class _NaT(_Timestamp):
|
1327 | 1440 |
|
1328 | 1441 | def __hash__(_NaT self):
|
@@ -1540,7 +1653,7 @@ cdef _TSObject convert_datetime_to_tsobject(datetime ts, object tz,
|
1540 | 1653 | if is_timestamp(ts):
|
1541 | 1654 | obj.value += ts.nanosecond
|
1542 | 1655 | obj.dts.ps = ts.nanosecond * 1000
|
1543 |
| - |
| 1656 | + |
1544 | 1657 | if nanos:
|
1545 | 1658 | obj.value += nanos
|
1546 | 1659 | obj.dts.ps = nanos * 1000
|
@@ -3258,95 +3371,6 @@ cpdef convert_to_timedelta64(object ts, object unit):
|
3258 | 3371 | return ts.astype('timedelta64[ns]')
|
3259 | 3372 |
|
3260 | 3373 |
|
3261 |
| -#---------------------------------------------------------------------- |
3262 |
| -# NaT methods/property setups |
3263 |
| - |
3264 |
| - |
3265 |
| -# inject the Timestamp field properties |
3266 |
| -# these by definition return np.nan |
3267 |
| -fields = ['year', 'quarter', 'month', 'day', 'hour', |
3268 |
| - 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond', |
3269 |
| - 'week', 'dayofyear', 'weekofyear', 'days_in_month', 'daysinmonth', |
3270 |
| - 'dayofweek', 'weekday_name', 'days', 'seconds', 'microseconds', |
3271 |
| - 'nanoseconds', 'qyear'] |
3272 |
| -for field in fields: |
3273 |
| - prop = property(fget=lambda self: np.nan) |
3274 |
| - setattr(NaTType, field, prop) |
3275 |
| - |
3276 |
| - |
3277 |
| -# define how we are handling NaT methods & inject |
3278 |
| -# to the NaTType class; these can return NaT, np.nan |
3279 |
| -# or raise respectively |
3280 |
| -_nat_methods = ['date', 'now', 'replace', 'to_pydatetime', |
3281 |
| - 'today', 'round', 'floor', 'ceil', 'tz_convert', |
3282 |
| - 'tz_localize'] |
3283 |
| -_nan_methods = ['weekday', 'isoweekday'] |
3284 |
| -_implemented_methods = [ |
3285 |
| - 'to_datetime', 'to_datetime64', 'isoformat', 'total_seconds'] |
3286 |
| -_implemented_methods.extend(_nat_methods) |
3287 |
| -_implemented_methods.extend(_nan_methods) |
3288 |
| - |
3289 |
| - |
3290 |
| -def _get_docstring(_method_name): |
3291 |
| - # NaT serves double duty as Timestamp & Timedelta |
3292 |
| - # missing value, so need to acquire doc-strings for both |
3293 |
| - |
3294 |
| - try: |
3295 |
| - return getattr(Timestamp, _method_name).__doc__ |
3296 |
| - except AttributeError: |
3297 |
| - pass |
3298 |
| - |
3299 |
| - try: |
3300 |
| - return getattr(Timedelta, _method_name).__doc__ |
3301 |
| - except AttributeError: |
3302 |
| - pass |
3303 |
| - |
3304 |
| - return None |
3305 |
| - |
3306 |
| - |
3307 |
| -for _method_name in _nat_methods: |
3308 |
| - |
3309 |
| - def _make_nat_func(func_name): |
3310 |
| - def f(*args, **kwargs): |
3311 |
| - return NaT |
3312 |
| - f.__name__ = func_name |
3313 |
| - f.__doc__ = _get_docstring(func_name) |
3314 |
| - return f |
3315 |
| - |
3316 |
| - setattr(NaTType, _method_name, _make_nat_func(_method_name)) |
3317 |
| - |
3318 |
| - |
3319 |
| -for _method_name in _nan_methods: |
3320 |
| - |
3321 |
| - def _make_nan_func(func_name): |
3322 |
| - def f(*args, **kwargs): |
3323 |
| - return np.nan |
3324 |
| - f.__name__ = func_name |
3325 |
| - f.__doc__ = _get_docstring(func_name) |
3326 |
| - return f |
3327 |
| - |
3328 |
| - setattr(NaTType, _method_name, _make_nan_func(_method_name)) |
3329 |
| - |
3330 |
| - |
3331 |
| -# GH9513 NaT methods (except to_datetime64) to raise, return np.nan, or |
3332 |
| -# return NaT create functions that raise, for binding to NaTType |
3333 |
| -for _maybe_method_name in dir(NaTType): |
3334 |
| - _maybe_method = getattr(NaTType, _maybe_method_name) |
3335 |
| - if (callable(_maybe_method) |
3336 |
| - and not _maybe_method_name.startswith("_") |
3337 |
| - and _maybe_method_name not in _implemented_methods): |
3338 |
| - |
3339 |
| - def _make_error_func(func_name): |
3340 |
| - def f(*args, **kwargs): |
3341 |
| - raise ValueError("NaTType does not support " + func_name) |
3342 |
| - f.__name__ = func_name |
3343 |
| - f.__doc__ = _get_docstring(func_name) |
3344 |
| - return f |
3345 |
| - |
3346 |
| - setattr(NaTType, _maybe_method_name, |
3347 |
| - _make_error_func(_maybe_method_name)) |
3348 |
| - |
3349 |
| - |
3350 | 3374 | #----------------------------------------------------------------------
|
3351 | 3375 | # Conversion routines
|
3352 | 3376 |
|
|
0 commit comments