Skip to content

PyArray_CompareFunc of dtype datetime64 returns incorrect value for 'NaT' objects. #19574

@anmolschauhan

Description

@anmolschauhan

Sort order for NaT values got changed in numpy 1.18.0.

PyArray_CompareFunc of dtype datetime64 returns incorrect as per the updated sort order.

This is present with numpy 1.20.2 and 1.21 too.

This is reproducible via the following extension module.

compare_bug.c

#include <Python.h>
#include "numpy/arrayobject.h"
#include "numpy/ndarrayobject.h"
#include "numpy/ndarraytypes.h"
#include "numpy/arrayscalars.h"
#include "numpy/ufuncobject.h"


static PyObject*
reproduce_bug(PyObject* self, PyObject* args) {
    PyObject *arr = NULL;
    if (!PyArg_ParseTuple(args, "|O", &arr)) {
        return Py_None;
    }
    PyArrayObject *numpy_arr = (PyArrayObject*) arr;
    // We just compare 0th and 1st element and print out
    // the returned value.
    int x = numpy_arr->descr->f->compare(
        PyArray_GETPTR1(numpy_arr, 0),
        PyArray_GETPTR1(numpy_arr, 1),
        numpy_arr
    );
    printf("DEBUG %d\n", x);
    return Py_None;
}

static PyMethodDef bug_functions[] = {
    {"bug", (PyCFunction)reproduce_bug, METH_VARARGS, NULL},
    { NULL, NULL, 0, NULL }
};

static struct PyModuleDef numpybugmodule = {
    PyModuleDef_HEAD_INIT,
    "numpy_bug",
    NULL,
    -1,   
    bug_functions
};

PyMODINIT_FUNC
PyInit_numpy_bug(void)
{
    return PyModule_Create(&numpybugmodule);
}

setup.py

from distutils.core import setup, Extension, DEBUG
import numpy

extra_compile_args = ["-DNDEBUG", "-O3"]
sfc_module = Extension('numpy_bug', sources = ['compare_bug..c'],
                        include_dirs=[numpy.get_include()],
                       extra_compile_args=extra_compile_args)

setup(name = 'mtnumpy', version = '1.0',
    description = 'Python Package with superfastcode C++ extension',
    ext_modules = [sfc_module]
    )

Running this after installing above:

In [1]: import numpy, numpy_bug

In [2]: numpy_bug.bug(numpy.array(['NaT', '2020-01-01'], dtype='datetime64[s]')) # should print 1 as per new sort order.
DEBUG -1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions