Skip to content

Commit 2c5fb17

Browse files
nanjekyejoannahvstinner
authored andcommitted
bpo-36833: Add tests for Datetime C API Macros (GH-14842)
Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of the datetime module.
1 parent 35f6301 commit 2c5fb17

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

Lib/test/datetimetester.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5941,6 +5941,65 @@ def test_timezones_capi(self):
59415941

59425942
self.assertEqual(dt1.astimezone(timezone.utc), dt_utc)
59435943

5944+
def test_PyDateTime_DELTA_GET(self):
5945+
class TimeDeltaSubclass(timedelta):
5946+
pass
5947+
5948+
for klass in [timedelta, TimeDeltaSubclass]:
5949+
for args in [(26, 55, 99999), (26, 55, 99999)]:
5950+
d = klass(*args)
5951+
with self.subTest(cls=klass, date=args):
5952+
days, seconds, microseconds = _testcapi.PyDateTime_DELTA_GET(d)
5953+
5954+
self.assertEqual(days, d.days)
5955+
self.assertEqual(seconds, d.seconds)
5956+
self.assertEqual(microseconds, d.microseconds)
5957+
5958+
def test_PyDateTime_GET(self):
5959+
class DateSubclass(date):
5960+
pass
5961+
5962+
for klass in [date, DateSubclass]:
5963+
for args in [(2000, 1, 2), (2012, 2, 29)]:
5964+
d = klass(*args)
5965+
with self.subTest(cls=klass, date=args):
5966+
year, month, day = _testcapi.PyDateTime_GET(d)
5967+
5968+
self.assertEqual(year, d.year)
5969+
self.assertEqual(month, d.month)
5970+
self.assertEqual(day, d.day)
5971+
5972+
def test_PyDateTime_DATE_GET(self):
5973+
class DateTimeSubclass(datetime):
5974+
pass
5975+
5976+
for klass in [datetime, DateTimeSubclass]:
5977+
for args in [(1993, 8, 26, 22, 12, 55, 99999),
5978+
(1993, 8, 26, 22, 12, 55, 99999)]:
5979+
d = klass(*args)
5980+
with self.subTest(cls=klass, date=args):
5981+
hour, minute, second, microsecond = _testcapi.PyDateTime_DATE_GET(d)
5982+
5983+
self.assertEqual(hour, d.hour)
5984+
self.assertEqual(minute, d.minute)
5985+
self.assertEqual(second, d.second)
5986+
self.assertEqual(microsecond, d.microsecond)
5987+
5988+
def test_PyDateTime_TIME_GET(self):
5989+
class TimeSubclass(time):
5990+
pass
5991+
5992+
for klass in [time, TimeSubclass]:
5993+
for args in [(12, 30, 20, 10), (12, 30, 20, 10)]:
5994+
d = klass(*args)
5995+
with self.subTest(cls=klass, date=args):
5996+
hour, minute, second, microsecond = _testcapi.PyDateTime_TIME_GET(d)
5997+
5998+
self.assertEqual(hour, d.hour)
5999+
self.assertEqual(minute, d.minute)
6000+
self.assertEqual(second, d.second)
6001+
self.assertEqual(microsecond, d.microsecond)
6002+
59446003
def test_timezones_offset_zero(self):
59456004
utc0, utc1, non_utc = _testcapi.get_timezones_offset_zero()
59466005

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of
2+
the :mod:`datetime` module. Patch by Joannah Nanjekye.

Modules/_testcapimodule.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,55 @@ get_datetime_fromtimestamp(PyObject* self, PyObject *args)
26292629
return rv;
26302630
}
26312631

2632+
static PyObject *
2633+
test_PyDateTime_GET(PyObject *self, PyObject *obj)
2634+
{
2635+
int year, month, day;
2636+
2637+
year = PyDateTime_GET_YEAR(obj);
2638+
month = PyDateTime_GET_MONTH(obj);
2639+
day = PyDateTime_GET_DAY(obj);
2640+
2641+
return Py_BuildValue("(lll)", year, month, day);
2642+
}
2643+
2644+
static PyObject *
2645+
test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj)
2646+
{
2647+
int hour, minute, second, microsecond;
2648+
2649+
hour = PyDateTime_DATE_GET_HOUR(obj);
2650+
minute = PyDateTime_DATE_GET_MINUTE(obj);
2651+
second = PyDateTime_DATE_GET_SECOND(obj);
2652+
microsecond = PyDateTime_DATE_GET_MICROSECOND(obj);
2653+
2654+
return Py_BuildValue("(llll)", hour, minute, second, microsecond);
2655+
}
2656+
2657+
static PyObject *
2658+
test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj)
2659+
{
2660+
int hour, minute, second, microsecond;
2661+
2662+
hour = PyDateTime_TIME_GET_HOUR(obj);
2663+
minute = PyDateTime_TIME_GET_MINUTE(obj);
2664+
second = PyDateTime_TIME_GET_SECOND(obj);
2665+
microsecond = PyDateTime_TIME_GET_MICROSECOND(obj);
2666+
2667+
return Py_BuildValue("(llll)", hour, minute, second, microsecond);
2668+
}
2669+
2670+
static PyObject *
2671+
test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj)
2672+
{
2673+
int days, seconds, microseconds;
2674+
2675+
days = PyDateTime_DELTA_GET_DAYS(obj);
2676+
seconds = PyDateTime_DELTA_GET_SECONDS(obj);
2677+
microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj);
2678+
2679+
return Py_BuildValue("(lll)", days, seconds, microseconds);
2680+
}
26322681

26332682
/* test_thread_state spawns a thread of its own, and that thread releases
26342683
* `thread_done` when it's finished. The driver code has to know when the
@@ -5138,6 +5187,10 @@ static PyMethodDef TestMethods[] = {
51385187
{"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS},
51395188
{"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS},
51405189
{"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS},
5190+
{"PyDateTime_GET", test_PyDateTime_GET, METH_O},
5191+
{"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O},
5192+
{"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O},
5193+
{"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O},
51415194
{"test_list_api", test_list_api, METH_NOARGS},
51425195
{"test_dict_iteration", test_dict_iteration, METH_NOARGS},
51435196
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},

0 commit comments

Comments
 (0)