summaryrefslogtreecommitdiffstats
path: root/Modules/_testcapimodule.c
diff options
context:
space:
mode:
authorPaul Ganssle <pganssle@users.noreply.github.com>2019-04-27 19:39:40 (GMT)
committerBerker Peksag <berker.peksag@gmail.com>2019-04-27 19:39:40 (GMT)
commit4d8c8c0ad6163c24136d3419eb04f310b31f7e64 (patch)
tree445d3de23677da75d5c1d3346a45d799b4874b48 /Modules/_testcapimodule.c
parent5c403b203510549a3f89d138d3265c5cc0cc12af (diff)
downloadcpython-4d8c8c0ad6163c24136d3419eb04f310b31f7e64.zip
cpython-4d8c8c0ad6163c24136d3419eb04f310b31f7e64.tar.gz
cpython-4d8c8c0ad6163c24136d3419eb04f310b31f7e64.tar.bz2
bpo-36025: Fix PyDate_FromTimestamp API (GH-11922)
In the process of converting the date.fromtimestamp function to use argument clinic in GH-8535, the C API for PyDate_FromTimestamp was inadvertently changed to expect a timestamp object rather than an argument tuple. This PR fixes this backwards-incompatible change by adding a new wrapper function for the C API function that unwraps the argument tuple and passes it to the underlying function. This PR also adds tests for both PyDate_FromTimestamp and PyDateTime_FromTimestamp to prevent any further regressions.
Diffstat (limited to 'Modules/_testcapimodule.c')
-rw-r--r--Modules/_testcapimodule.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 6f4eb53..c52e349 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2340,6 +2340,71 @@ get_timezone_utc_capi(PyObject* self, PyObject *args) {
}
}
+static PyObject *
+get_date_fromtimestamp(PyObject* self, PyObject *args)
+{
+ PyObject *tsargs = NULL, *ts = NULL, *rv = NULL;
+ int macro = 0;
+
+ if (!PyArg_ParseTuple(args, "O|p", &ts, &macro)) {
+ return NULL;
+ }
+
+ // Construct the argument tuple
+ if ((tsargs = PyTuple_Pack(1, ts)) == NULL) {
+ return NULL;
+ }
+
+ // Pass along to the API function
+ if (macro) {
+ rv = PyDate_FromTimestamp(tsargs);
+ }
+ else {
+ rv = PyDateTimeAPI->Date_FromTimestamp(
+ (PyObject *)PyDateTimeAPI->DateType, tsargs
+ );
+ }
+
+ Py_DECREF(tsargs);
+ return rv;
+}
+
+static PyObject *
+get_datetime_fromtimestamp(PyObject* self, PyObject *args)
+{
+ int macro = 0;
+ int usetz = 0;
+ PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL;
+ if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, &macro)) {
+ return NULL;
+ }
+
+ // Construct the argument tuple
+ if (usetz) {
+ tsargs = PyTuple_Pack(2, ts, tzinfo);
+ }
+ else {
+ tsargs = PyTuple_Pack(1, ts);
+ }
+
+ if (tsargs == NULL) {
+ return NULL;
+ }
+
+ // Pass along to the API function
+ if (macro) {
+ rv = PyDateTime_FromTimestamp(tsargs);
+ }
+ else {
+ rv = PyDateTimeAPI->DateTime_FromTimestamp(
+ (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL
+ );
+ }
+
+ Py_DECREF(tsargs);
+ return rv;
+}
+
/* test_thread_state spawns a thread of its own, and that thread releases
* `thread_done` when it's finished. The driver code has to know when the
@@ -4769,7 +4834,9 @@ static PyMethodDef TestMethods[] = {
{"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS},
{"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_timezone_utc_capi", get_timezone_utc_capi, 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},
{"test_dict_iteration", test_dict_iteration, METH_NOARGS},
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},