<commit_before>/*
 * Functions that will convert a Python number to another number.
 *
 * Author: <NAME>
 *
 * January 2017
 */

#include "number_handling.h"

static bool
_PyFloat_is_Intlike(PyObject *obj) {
    PyObject *py_is_intlike = PyObject_CallMethod(obj, "is_integer", NULL);
    if (py_is_intlike == NULL)
        return PyErr_Clear(), false;
    else {
        const bool is_intlike = PyObject_IsTrue(py_is_intlike);
        Py_DECREF(py_is_intlike);
        return is_intlike;
    }
}


static PyObject*
PyNumber_to_PyInt_or_PyFloat(PyObject *pynum,
                             PyObject *inf_sub, PyObject *nan_sub,
                             PyObject *pycoerce)
{
    if (nan_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_NAN(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(nan_sub), nan_sub;
    else if (inf_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_INFINITY(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(inf_sub), inf_sub;
    else if (PyObject_IsTrue(pycoerce)) {
        if (PyNumber_IsInt(pynum) || PyFloat_is_Intlike(pynum))
            return PyNumber_ToInt(pynum);
        else
            return PyNumber_Float(pynum);
    }
    else
        return Py_INCREF(pynum), pynum;
}


static PyObject*
PyNumber_to_PyFloat(PyObject *pynum, PyObject *inf_sub, PyObject *nan_sub)
{
    if (nan_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_NAN(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(nan_sub), nan_sub;
    else if (inf_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_INFINITY(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(inf_sub), inf_sub;
    else
        return PyNumber_Float(pynum);
}


static PyObject*
PyNumber_to_PyInt(PyObject *pynum)
{
    if (PyFloat_Check(pynum)) { /* Watch out for un-intable numbers. */
        const double d = PyFloat_AS_DOUBLE(pynum);
        if (Py_IS_NAN(d) || Py_IS_INFINITY(d)) return NULL;
    }
    return PyNumber_ToInt(pynum);
}


PyObject*
PyFloat_to_PyInt(PyObject * fobj)
{
    PyObject *tmp = PyNumber_to_PyInt(fobj);
    Py_DECREF(fobj);
    return tmp;
}


bool
PyFloat_is_Intlike(PyObject *obj)
{
    const double dval = PyFloat_AS_DOUBLE(obj);
    if (dval < LONG_MAX && dval > LONG_MIN)
        return dval == (long) dval;
    return _PyFloat_is_Intlike(obj);
}


bool
double_is_intlike(const double val)
{
    if (val < LONG_MAX && val > LONG_MIN)
        return val == (long) val;
    else {
        PyObject *pyval = PyFloat_FromDouble(val);
        if (pyval == NULL)
            return PyErr_Clear(), false;
        return _PyFloat_is_Intlike(pyval);
    }
}


PyObject*
PyNumber_to_PyNumber(PyObject *pynum, const PyNumberType type,
                     PyObject *inf_sub, PyObject *nan_sub, PyObject *pycoerce)
{
    PyObject *pyresult = NULL;
    switch (type) {
    case REAL:
        pyresult = PyNumber_to_PyInt_or_PyFloat(pynum, inf_sub, nan_sub, pycoerce);
        break;
    case FLOAT:
        pyresult = PyNumber_to_PyFloat(pynum, inf_sub, nan_sub);
        break;
    case INT:
    case FORCEINT:
    case INTLIKE:
        pyresult = PyNumber_to_PyInt(pynum);
        break;
    }<commit_msg>Eliminated potential memory leak.<commit_after>/*
 * Functions that will convert a Python number to another number.
 *
 * Author: <NAME>
 *
 * January 2017
 */

#include "number_handling.h"

static bool
_PyFloat_is_Intlike(PyObject *obj) {
    PyObject *py_is_intlike = PyObject_CallMethod(obj, "is_integer", NULL);
    if (py_is_intlike == NULL)
        return PyErr_Clear(), false;
    else {
        const bool is_intlike = PyObject_IsTrue(py_is_intlike);
        Py_DECREF(py_is_intlike);
        return is_intlike;
    }
}


static PyObject*
PyNumber_to_PyInt_or_PyFloat(PyObject *pynum,
                             PyObject *inf_sub, PyObject *nan_sub,
                             PyObject *pycoerce)
{
    if (nan_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_NAN(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(nan_sub), nan_sub;
    else if (inf_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_INFINITY(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(inf_sub), inf_sub;
    else if (PyObject_IsTrue(pycoerce)) {
        if (PyNumber_IsInt(pynum) || PyFloat_is_Intlike(pynum))
            return PyNumber_ToInt(pynum);
        else
            return PyNumber_Float(pynum);
    }
    else
        return Py_INCREF(pynum), pynum;
}


static PyObject*
PyNumber_to_PyFloat(PyObject *pynum, PyObject *inf_sub, PyObject *nan_sub)
{
    if (nan_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_NAN(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(nan_sub), nan_sub;
    else if (inf_sub != NULL && PyFloat_Check(pynum) &&
            Py_IS_INFINITY(PyFloat_AS_DOUBLE(pynum)))
        return Py_INCREF(inf_sub), inf_sub;
    else
        return PyNumber_Float(pynum);
}


static PyObject*
PyNumber_to_PyInt(PyObject *pynum)
{
    if (PyFloat_Check(pynum)) { /* Watch out for un-intable numbers. */
        const double d = PyFloat_AS_DOUBLE(pynum);
        if (Py_IS_NAN(d) || Py_IS_INFINITY(d)) return NULL;
    }
    return PyNumber_ToInt(pynum);
}


PyObject*
PyFloat_to_PyInt(PyObject * fobj)
{
    PyObject *tmp = PyNumber_to_PyInt(fobj);
    Py_DECREF(fobj);
    return tmp;
}


bool
PyFloat_is_Intlike(PyObject *obj)
{
    const double dval = PyFloat_AS_DOUBLE(obj);
    if (dval < LONG_MAX && dval > LONG_MIN)
        return dval == (long) dval;
    return _PyFloat_is_Intlike(obj);
}


bool
double_is_intlike(const double val)
{
    if (val < LONG_MAX && val > LONG_MIN)
        return val == (long) val;
    else {
        PyObject *pyval = PyFloat_FromDouble(val);
        const bool result = pyval == NULL
                          ? (PyErr_Clear(), false)
                          : _PyFloat_is_Intlike(pyval);
        Py_XDECREF(pyval);
        return result;
    }
}


PyObject*
PyNumber_to_PyNumber(PyObject *pynum, const PyNumberType type,
                     PyObject *inf_sub, PyObject *nan_sub, PyObject *pycoerce)
{
    PyObject *pyresult = NULL;
    switch (type) {
    case REAL:
        pyresult = PyNumber_to_PyInt_or_PyFloat(pynum, inf_sub, nan_sub, pycoerce);
        break;
    case FLOAT:
        pyresult = PyNumber_to_PyFloat(pynum, inf_sub, nan_sub);
        break;
    case INT:
    case FORCEINT:
    case INTLIKE:
        pyresult = PyNumber_to_PyInt(pynum);
        break;
    }
{'fraction_non_alphanumeric': 0.10159176029962547, 'fraction_numerical': 0.0012484394506866417, 'mean_word_length': 2.803560830860534, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5300459', 'n_tokens_mistral': 2316, 'n_tokens_neox': 2351, 'n_words': 456}