From 98ff4d5fb6a9d01b0176b7786db61346952e5295 Mon Sep 17 00:00:00 2001 From: Edison A <20975616+SimiCode@users.noreply.github.com> Date: Fri, 17 May 2019 13:28:42 -0700 Subject: [PATCH] bpo-36782: Created C API wrappers and added missing tests for functions in the PyDateTimeAPI. (#13088) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * created a c API wrapper for pyDate_FromDate and added the test * 📜🤖 Added by blurb_it. * fixed auto-alignment by vscode * made changes as per PEP7 * Update 2019-05-04-21-25-19.bpo-36782.h3oPIb.rst * Refactored code as per requested changes * Remove Whitespace to Fix failed travis build * Update 2019-05-04-21-25-19.bpo-36782.h3oPIb.rst * Add a new line at end of ACKS * Added C API function for PyDateTime_FromDateAndTime * Added a test for the C API wrapper of PyDateTime_FromDateAndTime * Added C API function for PyDateTime_FromDateAndTime * Added a test for the C API wrapper of PyDateTime_FromDateAndTimeAndFold * Remove Whitespace using patchcheck * Added a C API function for PyTime_FromTime * Added a test for the C API wrapper of PyTime_FromTime * Added a C API function for PyTime_FromTimeAndFold * Added a test for the C API wrapper of PyTime_FromTimeAndFold * Added a C API function for PyDelta_FromDSU * Added a test for the C API wrapper of PyDelta_FromDSU * Refactor code, re-edit lines longer than 80 chars * Fix Whitespace issues in DatetimeTester * List all tests that were added in this PR * Update 2019-05-04-21-25-19.bpo-36782.h3oPIb.rst * Reformat code as per PEP7 guidelines * Remove unused varibles from another function * Added specific tests for the Fold Attribute * Update 2019-05-04-21-25-19.bpo-36782.h3oPIb.rst * Reformat code according to requested changes * Reformat code to PEP7 Guidelines * Reformat code to PEP7 Guidelines * Re-add name to blurb * Added a backtick to blurb file * Update 2019-05-04-21-25-19.bpo-36782.h3oPIb.rst * Remove the need to initialize mandatory parameters * Make the macro parameter mandatory * Re-arrange the order of unit-test args * Removed the need to initialize macro change all the int macro = 0 to int macro; now that macro is required Co-Authored-By: Paul Ganssle * Removed the need to initialize macro change all the `int macro = 0` to `int macro`; now that macro is required Co-Authored-By: Paul Ganssle * Removed the need to initialize macro change all the `int macro = 0` to `int macro`; now that macro is required Co-Authored-By: Paul Ganssle * Removed the need to initialize macro change all the `int macro = 0` to `int macro`; now that macro is required Co-Authored-By: Paul Ganssle * Removed the need to initialize macro change all the `int macro = 0` to `int macro`; now that macro is required Co-Authored-By: Paul Ganssle * Removed the need to initialize macro change all the `int macro = 0` to `int macro`; now that macro is required Co-Authored-By: Paul Ganssle --- Lib/test/datetimetester.py | 97 +++++++++- Misc/ACKS | 1 + .../2019-05-04-21-25-19.bpo-36782.h3oPIb.rst | 1 + Modules/_testcapimodule.c | 170 +++++++++++++++++- 4 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index af0047fafd8..239a0b5ac83 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -6018,6 +6018,100 @@ class CapiTest(unittest.TestCase): with self.subTest(arg=arg, exact=exact): self.assertFalse(is_tzinfo(arg, exact)) + def test_date_from_date(self): + exp_date = date(1993, 8, 26) + + for macro in [0, 1]: + with self.subTest(macro=macro): + c_api_date = _testcapi.get_date_fromdate( + macro, + exp_date.year, + exp_date.month, + exp_date.day) + + self.assertEqual(c_api_date, exp_date) + + def test_datetime_from_dateandtime(self): + exp_date = datetime(1993, 8, 26, 22, 12, 55, 99999) + + for macro in [0, 1]: + with self.subTest(macro=macro): + c_api_date = _testcapi.get_datetime_fromdateandtime( + macro, + exp_date.year, + exp_date.month, + exp_date.day, + exp_date.hour, + exp_date.minute, + exp_date.second, + exp_date.microsecond) + + self.assertEqual(c_api_date, exp_date) + + def test_datetime_from_dateandtimeandfold(self): + exp_date = datetime(1993, 8, 26, 22, 12, 55, 99999) + + for fold in [0, 1]: + for macro in [0, 1]: + with self.subTest(macro=macro, fold=fold): + c_api_date = _testcapi.get_datetime_fromdateandtimeandfold( + macro, + exp_date.year, + exp_date.month, + exp_date.day, + exp_date.hour, + exp_date.minute, + exp_date.second, + exp_date.microsecond, + exp_date.fold) + + self.assertEqual(c_api_date, exp_date) + self.assertEqual(c_api_date.fold, exp_date.fold) + + def test_time_from_time(self): + exp_time = time(22, 12, 55, 99999) + + for macro in [0, 1]: + with self.subTest(macro=macro): + c_api_time = _testcapi.get_time_fromtime( + macro, + exp_time.hour, + exp_time.minute, + exp_time.second, + exp_time.microsecond) + + self.assertEqual(c_api_time, exp_time) + + def test_time_from_timeandfold(self): + exp_time = time(22, 12, 55, 99999) + + for fold in [0, 1]: + for macro in [0, 1]: + with self.subTest(macro=macro, fold=fold): + c_api_time = _testcapi.get_time_fromtimeandfold( + macro, + exp_time.hour, + exp_time.minute, + exp_time.second, + exp_time.microsecond, + exp_time.fold) + + self.assertEqual(c_api_time, exp_time) + self.assertEqual(c_api_time.fold, exp_time.fold) + + def test_delta_from_dsu(self): + exp_delta = timedelta(26, 55, 99999) + + for macro in [0, 1]: + with self.subTest(macro=macro): + c_api_delta = _testcapi.get_delta_fromdsu( + macro, + exp_delta.days, + exp_delta.seconds, + exp_delta.microseconds) + + self.assertEqual(c_api_delta, exp_delta) + def test_date_from_timestamp(self): ts = datetime(1995, 4, 12).timestamp() @@ -6028,9 +6122,6 @@ class CapiTest(unittest.TestCase): self.assertEqual(d, date(1995, 4, 12)) def test_datetime_from_timestamp(self): - ts0 = datetime(1995, 4, 12).timestamp() - ts1 = datetime(1995, 4, 12, 12, 30).timestamp() - cases = [ ((1995, 4, 12), None, False), ((1995, 4, 12), None, True), diff --git a/Misc/ACKS b/Misc/ACKS index 06e288dfcb2..8b3232551e1 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1857,3 +1857,4 @@ Peter Ã…strand Zheao Li Carsten Klein Diego Rojas +Edison Abahurire diff --git a/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst b/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst new file mode 100644 index 00000000000..222fb386ca7 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst @@ -0,0 +1 @@ +Add tests for several C API functions in the :mod:`datetime` module. Patch by Edison Abahurire. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 59b42df279c..2af553960cc 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2340,6 +2340,168 @@ get_timezone_utc_capi(PyObject* self, PyObject *args) { } } +static PyObject * +get_date_fromdate(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + + if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { + return NULL; + } + + if (macro) { + rv = PyDate_FromDate(year, month, day); + } + else { + rv = PyDateTimeAPI->Date_FromDate( + year, month, day, + PyDateTimeAPI->DateType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + fold); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_time_fromtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiii", + ¯o, + &hour, &minute, &second, µsecond)) { + return NULL; + } + + if (macro) { + rv = PyTime_FromTime(hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->Time_FromTime( + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_time_fromtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiii", + ¯o, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); + } + else { + rv = PyDateTimeAPI->Time_FromTimeAndFold( + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_delta_fromdsu(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int days, seconds, microseconds; + + if (!PyArg_ParseTuple(args, "piii", + ¯o, + &days, &seconds, µseconds)) { + return NULL; + } + + if (macro) { + rv = PyDelta_FromDSU(days, seconds, microseconds); + } + else { + rv = PyDateTimeAPI->Delta_FromDelta( + days, seconds, microseconds, 1, + PyDateTimeAPI->DeltaType); + } + + return rv; +} + static PyObject * get_date_fromtimestamp(PyObject* self, PyObject *args) { @@ -4826,7 +4988,7 @@ static PyMethodDef TestMethods[] = { {"set_errno", set_errno, METH_VARARGS}, {"test_config", test_config, METH_NOARGS}, {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, - {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {"datetime_check_date", datetime_check_date, METH_VARARGS}, {"datetime_check_time", datetime_check_time, METH_VARARGS}, {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, @@ -4835,6 +4997,12 @@ static PyMethodDef TestMethods[] = { {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, + {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, + {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, + {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, + {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, + {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, + {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, {"test_list_api", test_list_api, METH_NOARGS},