Skip to content

move is_null_datetimelike to nattype for self-containment #21692

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 4 commits into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 6 additions & 1 deletion pandas/_libs/missing.pxd
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# -*- coding: utf-8 -*-
# cython: profile=False

cdef bint is_null_datetimelike(object val)
from tslibs.nattype cimport is_null_datetimelike

cpdef bint checknull(object val)
cpdef bint checknull_old(object val)

cdef bint is_null_datetime64(v)
cdef bint is_null_timedelta64(v)
cdef bint is_null_period(v)
51 changes: 35 additions & 16 deletions pandas/_libs/missing.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,14 @@ cimport util

from tslibs.np_datetime cimport get_timedelta64_value, get_datetime64_value
from tslibs.nattype import NaT
from tslibs.nattype cimport is_null_datetimelike

cdef double INF = <double> np.inf
cdef double NEGINF = -INF

cdef int64_t NPY_NAT = util.get_nat()


cdef inline bint is_null_datetimelike(object val):
# determine if we have a null for a timedelta/datetime (or integer
# versions)
if util._checknull(val):
return True
elif val is NaT:
return True
elif util.is_timedelta64_object(val):
return val.view('int64') == NPY_NAT
elif util.is_datetime64_object(val):
return val.view('int64') == NPY_NAT
elif util.is_integer_object(val):
return val == NPY_NAT
return False


cdef inline bint _check_all_nulls(object val):
""" utility to check if a value is any type of null """
cdef bint res
Expand Down Expand Up @@ -308,3 +293,37 @@ cpdef bint isneginf_scalar(object val):
return True
else:
return False


cdef inline bint is_null_datetime64(v):
# determine if we have a null for a datetime (or integer versions),
# excluding np.timedelta64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
elif util.is_datetime64_object(v):
return v.view('int64') == NPY_NAT
return False


cdef inline bint is_null_timedelta64(v):
# determine if we have a null for a timedelta (or integer versions),
# excluding np.datetime64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
elif util.is_timedelta64_object(v):
return v.view('int64') == NPY_NAT
return False


cdef inline bint is_null_period(v):
# determine if we have a null for a Period (or integer versions),
# excluding np.datetime64('nat') and np.timedelta64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
return False
36 changes: 2 additions & 34 deletions pandas/_libs/src/inference.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ cdef extern from "numpy/arrayobject.h":
cdef object fields
cdef tuple names

from missing cimport is_null_datetime64, is_null_timedelta64, is_null_period

from util cimport UINT8_MAX, UINT64_MAX, INT64_MAX, INT64_MIN

# core.common import for fast inference checks
Expand Down Expand Up @@ -574,40 +576,6 @@ cpdef object infer_datetimelike_array(object arr):
return 'mixed'


cdef inline bint is_null_datetime64(v):
# determine if we have a null for a datetime (or integer versions),
# excluding np.timedelta64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
elif util.is_datetime64_object(v):
return v.view('int64') == iNaT
return False


cdef inline bint is_null_timedelta64(v):
# determine if we have a null for a timedelta (or integer versions),
# excluding np.datetime64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
elif util.is_timedelta64_object(v):
return v.view('int64') == iNaT
return False


cdef inline bint is_null_period(v):
# determine if we have a null for a Period (or integer versions),
# excluding np.datetime64('nat') and np.timedelta64('nat')
if util._checknull(v):
return True
elif v is NaT:
return True
return False


cdef inline bint is_datetime(object o):
return PyDateTime_Check(o)

Expand Down
1 change: 1 addition & 0 deletions pandas/_libs/tslibs/nattype.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ cdef int64_t NPY_NAT
cdef bint _nat_scalar_rules[6]

cdef bint checknull_with_nat(object val)
cdef bint is_null_datetimelike(object val)
26 changes: 26 additions & 0 deletions pandas/_libs/tslibs/nattype.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cimport numpy as cnp
from numpy cimport int64_t
cnp.import_array()

cimport util
from util cimport (get_nat,
is_integer_object, is_float_object,
is_datetime64_object, is_timedelta64_object)
Expand Down Expand Up @@ -587,3 +588,28 @@ cdef inline bint checknull_with_nat(object val):
""" utility to check if a value is a nat or not """
return val is None or (
PyFloat_Check(val) and val != val) or val is NaT


cdef inline bint is_null_datetimelike(object val):
"""
Determine if we have a null for a timedelta/datetime (or integer versions)

Parameters
----------
val : object

Returns
-------
null_datetimelike : bool
"""
if util._checknull(val):
return True
elif val is NaT:
return True
elif util.is_timedelta64_object(val):
Copy link
Member

Choose a reason for hiding this comment

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

why import this from util? Didn't you move it to tslibs.missing ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I understand the question. This PR is moving this function from _libs.missing to tslibs.nattype because doing so simplifies the dependency structure.

Copy link
Member

Choose a reason for hiding this comment

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

and by moving the function should not change the import?

Copy link
Contributor

Choose a reason for hiding this comment

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

these util functions of basically c versions of isinstance checks, so this is ok.

return val.view('int64') == NPY_NAT
elif util.is_datetime64_object(val):
return val.view('int64') == NPY_NAT
elif util.is_integer_object(val):
return val == NPY_NAT
return False
4 changes: 1 addition & 3 deletions pandas/_libs/tslibs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ cdef extern from "../src/datetime/np_datetime.h":
cimport util
from util cimport is_period_object, is_string_object, INT32_MIN

from pandas._libs.missing cimport is_null_datetimelike

from timestamps import Timestamp
from timezones cimport is_utc, is_tzlocal, get_utcoffset, get_dst_info
from timedeltas cimport delta_to_nanoseconds
Expand All @@ -54,7 +52,7 @@ from frequencies cimport (get_freq_code, get_base_alias,
from parsing import parse_time_string, NAT_SENTINEL
from resolution import Resolution
from nattype import nat_strings, NaT, iNaT
from nattype cimport _nat_scalar_rules, NPY_NAT
from nattype cimport _nat_scalar_rules, NPY_NAT, is_null_datetimelike

from pandas.tseries import offsets
from pandas.tseries import frequencies
Expand Down
19 changes: 9 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,16 +531,6 @@ def pxd(name):
'pyxfile': '_libs/ops',
'pxdfiles': ['_libs/src/util',
'_libs/missing']},
'_libs.tslibs.period': {
'pyxfile': '_libs/tslibs/period',
'pxdfiles': ['_libs/src/util',
'_libs/missing',
'_libs/tslibs/ccalendar',
'_libs/tslibs/timedeltas',
'_libs/tslibs/timezones',
'_libs/tslibs/nattype'],
'depends': tseries_depends + ['pandas/_libs/src/period_helper.h'],
'sources': np_datetime_sources + ['pandas/_libs/src/period_helper.c']},
'_libs.properties': {
'pyxfile': '_libs/properties',
'include': []},
Expand Down Expand Up @@ -601,6 +591,15 @@ def pxd(name):
'_libs.tslibs.parsing': {
'pyxfile': '_libs/tslibs/parsing',
'pxdfiles': ['_libs/src/util']},
'_libs.tslibs.period': {
'pyxfile': '_libs/tslibs/period',
'pxdfiles': ['_libs/src/util',
'_libs/tslibs/ccalendar',
'_libs/tslibs/timedeltas',
'_libs/tslibs/timezones',
'_libs/tslibs/nattype'],
'depends': tseries_depends + ['pandas/_libs/src/period_helper.h'],
'sources': np_datetime_sources + ['pandas/_libs/src/period_helper.c']},
'_libs.tslibs.resolution': {
'pyxfile': '_libs/tslibs/resolution',
'pxdfiles': ['_libs/src/util',
Expand Down