https://github.com/python/cpython/commit/1596e58f45a26f2a694d26a2b856064640b06608
commit: 1596e58f45a26f2a694d26a2b856064640b06608
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-09-21T12:44:36+03:00
summary:

gh-155496: Use Argument Clinic for more functions in the time module (GH-155513)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

files:
M Lib/test/test_inspect/test_inspect.py
M Lib/test/test_unittest/testmock/testhelpers.py
M Modules/clinic/timemodule.c.h
M Modules/timemodule.c

diff --git a/Lib/test/test_inspect/test_inspect.py 
b/Lib/test/test_inspect/test_inspect.py
index 25276fc40cb0287..a4381f2c0233954 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -6378,15 +6378,10 @@ def test_thread_module_has_signatures(self):
         self._test_module_has_signatures(_thread, no_signature)
 
     def test_time_module_has_signatures(self):
-        no_signature = {
-            'asctime', 'ctime', 'get_clock_info', 'gmtime', 'localtime',
-            'strftime', 'strptime'
-        }
-        no_signature |= {name for name in
-            ['clock_getres', 'clock_settime', 'clock_settime_ns',
-             'pthread_getcpuclockid']
-            if hasattr(time, name)}
-        self._test_module_has_signatures(time, no_signature)
+        no_signature = {'strftime', 'strptime'}
+        unsupported_signature = {'asctime'}
+        self._test_module_has_signatures(time, no_signature,
+                                         unsupported_signature)
 
     def test_tokenize_module_has_signatures(self):
         import tokenize
diff --git a/Lib/test/test_unittest/testmock/testhelpers.py 
b/Lib/test/test_unittest/testmock/testhelpers.py
index 0e82c723ec3eaa2..476e9105063bf99 100644
--- a/Lib/test/test_unittest/testmock/testhelpers.py
+++ b/Lib/test/test_unittest/testmock/testhelpers.py
@@ -1,8 +1,9 @@
 import inspect
-import time
 import types
 import unittest
 
+from test.support import import_helper
+
 from unittest.mock import (
     call, _Call, create_autospec, MagicMock,
     Mock, ANY, _CallList, patch, PropertyMock, _callable
@@ -929,8 +930,10 @@ def check_data_descriptor(mock_attr):
 
 
     def test_autospec_on_bound_builtin_function(self):
-        meth = types.MethodType(time.ctime, time.time())
-        self.assertIsInstance(meth(), str)
+        _testcapi = import_helper.import_module('_testcapi')
+        # This function is defined without a signature.
+        meth = types.MethodType(_testcapi.docstring_no_signature, object())
+        self.assertIsNone(meth())
         mocked = create_autospec(meth)
 
         # no signature, so no spec to check against
diff --git a/Modules/clinic/timemodule.c.h b/Modules/clinic/timemodule.c.h
index bbc0748f9a9c0dd..3b0a8d44129d381 100644
--- a/Modules/clinic/timemodule.c.h
+++ b/Modules/clinic/timemodule.c.h
@@ -2,6 +2,57 @@
 preserve
 [clinic start generated code]*/
 
+#include "pycore_modsupport.h"    // _PyArg_CheckPositional()
+
+PyDoc_STRVAR(time_time__doc__,
+"time($module, /)\n"
+"--\n"
+"\n"
+"Return the current time in seconds since the Epoch.\n"
+"\n"
+"Fractions of a second may be present if the system clock provides\n"
+"them.");
+
+#define TIME_TIME_METHODDEF    \
+    {"time", (PyCFunction)time_time, METH_NOARGS, time_time__doc__},
+
+static double
+time_time_impl(PyObject *module);
+
+static PyObject *
+time_time(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *return_value = NULL;
+    double _return_value;
+
+    _return_value = time_time_impl(module);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_time_ns__doc__,
+"time_ns($module, /)\n"
+"--\n"
+"\n"
+"Return the current time in nanoseconds since the Epoch.");
+
+#define TIME_TIME_NS_METHODDEF    \
+    {"time_ns", (PyCFunction)time_time_ns, METH_NOARGS, time_time_ns__doc__},
+
+static PyObject *
+time_time_ns_impl(PyObject *module);
+
+static PyObject *
+time_time_ns(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_time_ns_impl(module);
+}
+
 #if defined(HAVE_CLOCK_GETTIME)
 
 PyDoc_STRVAR(time_clock_gettime__doc__,
@@ -64,6 +115,603 @@ time_clock_gettime_ns(PyObject *module, PyObject *arg)
 
 #endif /* defined(HAVE_CLOCK_GETTIME) */
 
+#if defined(HAVE_CLOCK_SETTIME)
+
+PyDoc_STRVAR(time_clock_settime__doc__,
+"clock_settime($module, clk_id, time, /)\n"
+"--\n"
+"\n"
+"Set the time of the specified clock clk_id.");
+
+#define TIME_CLOCK_SETTIME_METHODDEF    \
+    {"clock_settime", _PyCFunction_CAST(time_clock_settime), METH_FASTCALL, 
time_clock_settime__doc__},
+
+static PyObject *
+time_clock_settime_impl(PyObject *module, int clk_id, PyObject *obj);
+
+static PyObject *
+time_clock_settime(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    int clk_id;
+    PyObject *obj;
+
+    if (!_PyArg_CheckPositional("clock_settime", nargs, 2, 2)) {
+        goto exit;
+    }
+    clk_id = PyLong_AsInt(args[0]);
+    if (clk_id == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    obj = args[1];
+    return_value = time_clock_settime_impl(module, clk_id, obj);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_CLOCK_SETTIME) */
+
+#if defined(HAVE_CLOCK_SETTIME)
+
+PyDoc_STRVAR(time_clock_settime_ns__doc__,
+"clock_settime_ns($module, clk_id, time, /)\n"
+"--\n"
+"\n"
+"Set the time of the specified clock clk_id with nanoseconds.");
+
+#define TIME_CLOCK_SETTIME_NS_METHODDEF    \
+    {"clock_settime_ns", _PyCFunction_CAST(time_clock_settime_ns), 
METH_FASTCALL, time_clock_settime_ns__doc__},
+
+static PyObject *
+time_clock_settime_ns_impl(PyObject *module, int clk_id, PyObject *obj);
+
+static PyObject *
+time_clock_settime_ns(PyObject *module, PyObject *const *args, Py_ssize_t 
nargs)
+{
+    PyObject *return_value = NULL;
+    int clk_id;
+    PyObject *obj;
+
+    if (!_PyArg_CheckPositional("clock_settime_ns", nargs, 2, 2)) {
+        goto exit;
+    }
+    clk_id = PyLong_AsInt(args[0]);
+    if (clk_id == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    obj = args[1];
+    return_value = time_clock_settime_ns_impl(module, clk_id, obj);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_CLOCK_SETTIME) */
+
+#if defined(HAVE_CLOCK_GETRES)
+
+PyDoc_STRVAR(time_clock_getres__doc__,
+"clock_getres($module, clk_id, /)\n"
+"--\n"
+"\n"
+"Return the resolution (precision) of the specified clock clk_id.");
+
+#define TIME_CLOCK_GETRES_METHODDEF    \
+    {"clock_getres", (PyCFunction)time_clock_getres, METH_O, 
time_clock_getres__doc__},
+
+static double
+time_clock_getres_impl(PyObject *module, int clk_id);
+
+static PyObject *
+time_clock_getres(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    int clk_id;
+    double _return_value;
+
+    clk_id = PyLong_AsInt(arg);
+    if (clk_id == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+    _return_value = time_clock_getres_impl(module, clk_id);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_CLOCK_GETRES) */
+
+#if defined(HAVE_PTHREAD_GETCPUCLOCKID)
+
+PyDoc_STRVAR(time_pthread_getcpuclockid__doc__,
+"pthread_getcpuclockid($module, thread_id, /)\n"
+"--\n"
+"\n"
+"Return the clk_id of a thread\'s CPU time clock.");
+
+#define TIME_PTHREAD_GETCPUCLOCKID_METHODDEF    \
+    {"pthread_getcpuclockid", (PyCFunction)time_pthread_getcpuclockid, METH_O, 
time_pthread_getcpuclockid__doc__},
+
+static PyObject *
+time_pthread_getcpuclockid_impl(PyObject *module, unsigned long thread_id);
+
+static PyObject *
+time_pthread_getcpuclockid(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    unsigned long thread_id;
+
+    if (!PyIndex_Check(arg)) {
+        _PyArg_BadArgument("pthread_getcpuclockid", "argument", "int", arg);
+        goto exit;
+    }
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &thread_id, 
sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
+    return_value = time_pthread_getcpuclockid_impl(module, thread_id);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_PTHREAD_GETCPUCLOCKID) */
+
+PyDoc_STRVAR(time_sleep__doc__,
+"sleep($module, seconds, /)\n"
+"--\n"
+"\n"
+"Delay execution for a given number of seconds.\n"
+"\n"
+"The argument may be a floating-point number for subsecond precision.");
+
+#define TIME_SLEEP_METHODDEF    \
+    {"sleep", (PyCFunction)time_sleep, METH_O, time_sleep__doc__},
+
+PyDoc_STRVAR(time_gmtime__doc__,
+"gmtime($module, seconds=None, /)\n"
+"--\n"
+"\n"
+"Convert seconds since the Epoch to a time tuple expressing UTC.\n"
+"\n"
+"That is, Greenwich Mean Time.  When \'seconds\' is not passed in, convert\n"
+"the current time instead.\n"
+"\n"
+"If the platform supports the tm_gmtoff and tm_zone, they are available\n"
+"as attributes only.");
+
+#define TIME_GMTIME_METHODDEF    \
+    {"gmtime", _PyCFunction_CAST(time_gmtime), METH_FASTCALL, 
time_gmtime__doc__},
+
+static PyObject *
+time_gmtime_impl(PyObject *module, PyObject *ot);
+
+static PyObject *
+time_gmtime(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *ot = Py_None;
+
+    if (!_PyArg_CheckPositional("gmtime", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    ot = args[0];
+skip_optional:
+    return_value = time_gmtime_impl(module, ot);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_localtime__doc__,
+"localtime($module, seconds=None, /)\n"
+"--\n"
+"\n"
+"Convert seconds since the Epoch to a time tuple expressing local time.\n"
+"\n"
+"When \'seconds\' is not passed in, convert the current time instead.");
+
+#define TIME_LOCALTIME_METHODDEF    \
+    {"localtime", _PyCFunction_CAST(time_localtime), METH_FASTCALL, 
time_localtime__doc__},
+
+static PyObject *
+time_localtime_impl(PyObject *module, PyObject *ot);
+
+static PyObject *
+time_localtime(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *ot = Py_None;
+
+    if (!_PyArg_CheckPositional("localtime", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    ot = args[0];
+skip_optional:
+    return_value = time_localtime_impl(module, ot);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_asctime__doc__,
+"asctime($module, time_tuple=<unrepresentable>, /)\n"
+"--\n"
+"\n"
+"Convert a time tuple to a string, e.g. \'Sat Jun 06 16:26:11 1998\'.\n"
+"\n"
+"When the time tuple is not present, current time as returned by\n"
+"localtime() is used.");
+
+#define TIME_ASCTIME_METHODDEF    \
+    {"asctime", _PyCFunction_CAST(time_asctime), METH_FASTCALL, 
time_asctime__doc__},
+
+static PyObject *
+time_asctime_impl(PyObject *module, PyObject *tup);
+
+static PyObject *
+time_asctime(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *tup = NULL;
+
+    if (!_PyArg_CheckPositional("asctime", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    tup = args[0];
+skip_optional:
+    return_value = time_asctime_impl(module, tup);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_ctime__doc__,
+"ctime($module, seconds=None, /)\n"
+"--\n"
+"\n"
+"Convert a time in seconds since the Epoch to a string in local time.\n"
+"\n"
+"This is equivalent to asctime(localtime(seconds)).  When \'seconds\' is\n"
+"not passed in, convert the current time instead.");
+
+#define TIME_CTIME_METHODDEF    \
+    {"ctime", _PyCFunction_CAST(time_ctime), METH_FASTCALL, time_ctime__doc__},
+
+static PyObject *
+time_ctime_impl(PyObject *module, PyObject *ot);
+
+static PyObject *
+time_ctime(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *ot = Py_None;
+
+    if (!_PyArg_CheckPositional("ctime", nargs, 0, 1)) {
+        goto exit;
+    }
+    if (nargs < 1) {
+        goto skip_optional;
+    }
+    ot = args[0];
+skip_optional:
+    return_value = time_ctime_impl(module, ot);
+
+exit:
+    return return_value;
+}
+
+#if defined(HAVE_MKTIME)
+
+PyDoc_STRVAR(time_mktime__doc__,
+"mktime($module, time_tuple, /)\n"
+"--\n"
+"\n"
+"Convert a time tuple in local time to seconds since the Epoch.\n"
+"\n"
+"Note that mktime(gmtime(0)) will not generally return zero for most\n"
+"time zones; instead the returned value will either be equal to that of\n"
+"the timezone or altzone attributes on the time module.");
+
+#define TIME_MKTIME_METHODDEF    \
+    {"mktime", (PyCFunction)time_mktime, METH_O, time_mktime__doc__},
+
+#endif /* defined(HAVE_MKTIME) */
+
+#if defined(HAVE_WORKING_TZSET)
+
+PyDoc_STRVAR(time_tzset__doc__,
+"tzset($module, /)\n"
+"--\n"
+"\n"
+"Initialize, or reinitialize, the local timezone.\n"
+"\n"
+"The local timezone is set to the value stored in os.environ[\'TZ\'].  The\n"
+"TZ environment variable should be specified in standard Unix timezone\n"
+"format as documented in the tzset man page (eg. \'US/Eastern\',\n"
+"\'Europe/Amsterdam\').  Unknown timezones will silently fall back to UTC.\n"
+"If the TZ environment variable is not set, the local timezone is set to\n"
+"the systems best guess of wallclock time.  Changing the TZ environment\n"
+"variable without calling tzset *may* change the local timezone used by\n"
+"methods such as localtime, but this behaviour should not be relied on.");
+
+#define TIME_TZSET_METHODDEF    \
+    {"tzset", (PyCFunction)time_tzset, METH_NOARGS, time_tzset__doc__},
+
+static PyObject *
+time_tzset_impl(PyObject *module);
+
+static PyObject *
+time_tzset(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_tzset_impl(module);
+}
+
+#endif /* defined(HAVE_WORKING_TZSET) */
+
+PyDoc_STRVAR(time_monotonic__doc__,
+"monotonic($module, /)\n"
+"--\n"
+"\n"
+"Monotonic clock, cannot go backward.");
+
+#define TIME_MONOTONIC_METHODDEF    \
+    {"monotonic", (PyCFunction)time_monotonic, METH_NOARGS, 
time_monotonic__doc__},
+
+static double
+time_monotonic_impl(PyObject *module);
+
+static PyObject *
+time_monotonic(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *return_value = NULL;
+    double _return_value;
+
+    _return_value = time_monotonic_impl(module);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_monotonic_ns__doc__,
+"monotonic_ns($module, /)\n"
+"--\n"
+"\n"
+"Monotonic clock, cannot go backward, as nanoseconds.");
+
+#define TIME_MONOTONIC_NS_METHODDEF    \
+    {"monotonic_ns", (PyCFunction)time_monotonic_ns, METH_NOARGS, 
time_monotonic_ns__doc__},
+
+static PyObject *
+time_monotonic_ns_impl(PyObject *module);
+
+static PyObject *
+time_monotonic_ns(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_monotonic_ns_impl(module);
+}
+
+PyDoc_STRVAR(time_perf_counter__doc__,
+"perf_counter($module, /)\n"
+"--\n"
+"\n"
+"Performance counter for benchmarking.");
+
+#define TIME_PERF_COUNTER_METHODDEF    \
+    {"perf_counter", (PyCFunction)time_perf_counter, METH_NOARGS, 
time_perf_counter__doc__},
+
+static double
+time_perf_counter_impl(PyObject *module);
+
+static PyObject *
+time_perf_counter(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *return_value = NULL;
+    double _return_value;
+
+    _return_value = time_perf_counter_impl(module);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_perf_counter_ns__doc__,
+"perf_counter_ns($module, /)\n"
+"--\n"
+"\n"
+"Performance counter for benchmarking as nanoseconds.");
+
+#define TIME_PERF_COUNTER_NS_METHODDEF    \
+    {"perf_counter_ns", (PyCFunction)time_perf_counter_ns, METH_NOARGS, 
time_perf_counter_ns__doc__},
+
+static PyObject *
+time_perf_counter_ns_impl(PyObject *module);
+
+static PyObject *
+time_perf_counter_ns(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_perf_counter_ns_impl(module);
+}
+
+PyDoc_STRVAR(time_process_time__doc__,
+"process_time($module, /)\n"
+"--\n"
+"\n"
+"Process time for profiling.\n"
+"\n"
+"That is the sum of the kernel and user-space CPU time.");
+
+#define TIME_PROCESS_TIME_METHODDEF    \
+    {"process_time", (PyCFunction)time_process_time, METH_NOARGS, 
time_process_time__doc__},
+
+static double
+time_process_time_impl(PyObject *module);
+
+static PyObject *
+time_process_time(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *return_value = NULL;
+    double _return_value;
+
+    _return_value = time_process_time_impl(module);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(time_process_time_ns__doc__,
+"process_time_ns($module, /)\n"
+"--\n"
+"\n"
+"Process time for profiling as nanoseconds.\n"
+"\n"
+"That is the sum of the kernel and user-space CPU time.");
+
+#define TIME_PROCESS_TIME_NS_METHODDEF    \
+    {"process_time_ns", (PyCFunction)time_process_time_ns, METH_NOARGS, 
time_process_time_ns__doc__},
+
+static PyObject *
+time_process_time_ns_impl(PyObject *module);
+
+static PyObject *
+time_process_time_ns(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_process_time_ns_impl(module);
+}
+
+#if defined(HAVE_THREAD_TIME)
+
+PyDoc_STRVAR(time_thread_time__doc__,
+"thread_time($module, /)\n"
+"--\n"
+"\n"
+"Thread time for profiling.\n"
+"\n"
+"That is the sum of the kernel and user-space CPU time.");
+
+#define TIME_THREAD_TIME_METHODDEF    \
+    {"thread_time", (PyCFunction)time_thread_time, METH_NOARGS, 
time_thread_time__doc__},
+
+static double
+time_thread_time_impl(PyObject *module);
+
+static PyObject *
+time_thread_time(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *return_value = NULL;
+    double _return_value;
+
+    _return_value = time_thread_time_impl(module);
+    if ((_return_value == -1.0) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyFloat_FromDouble(_return_value);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(HAVE_THREAD_TIME) */
+
+#if defined(HAVE_THREAD_TIME)
+
+PyDoc_STRVAR(time_thread_time_ns__doc__,
+"thread_time_ns($module, /)\n"
+"--\n"
+"\n"
+"Thread time for profiling as nanoseconds.\n"
+"\n"
+"That is the sum of the kernel and user-space CPU time.");
+
+#define TIME_THREAD_TIME_NS_METHODDEF    \
+    {"thread_time_ns", (PyCFunction)time_thread_time_ns, METH_NOARGS, 
time_thread_time_ns__doc__},
+
+static PyObject *
+time_thread_time_ns_impl(PyObject *module);
+
+static PyObject *
+time_thread_time_ns(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+    return time_thread_time_ns_impl(module);
+}
+
+#endif /* defined(HAVE_THREAD_TIME) */
+
+PyDoc_STRVAR(time_get_clock_info__doc__,
+"get_clock_info($module, name, /)\n"
+"--\n"
+"\n"
+"Get information of the specified clock.");
+
+#define TIME_GET_CLOCK_INFO_METHODDEF    \
+    {"get_clock_info", (PyCFunction)time_get_clock_info, METH_O, 
time_get_clock_info__doc__},
+
+static PyObject *
+time_get_clock_info_impl(PyObject *module, const char *name);
+
+static PyObject *
+time_get_clock_info(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    const char *name;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("get_clock_info", "argument", "str", arg);
+        goto exit;
+    }
+    Py_ssize_t name_length;
+    name = PyUnicode_AsUTF8AndSize(arg, &name_length);
+    if (name == NULL) {
+        goto exit;
+    }
+    if (strlen(name) != (size_t)name_length) {
+        PyErr_SetString(PyExc_ValueError, "embedded null character");
+        goto exit;
+    }
+    return_value = time_get_clock_info_impl(module, name);
+
+exit:
+    return return_value;
+}
+
 #ifndef TIME_CLOCK_GETTIME_METHODDEF
     #define TIME_CLOCK_GETTIME_METHODDEF
 #endif /* !defined(TIME_CLOCK_GETTIME_METHODDEF) */
@@ -71,4 +719,36 @@ time_clock_gettime_ns(PyObject *module, PyObject *arg)
 #ifndef TIME_CLOCK_GETTIME_NS_METHODDEF
     #define TIME_CLOCK_GETTIME_NS_METHODDEF
 #endif /* !defined(TIME_CLOCK_GETTIME_NS_METHODDEF) */
-/*[clinic end generated code: output=b589a2132aa9df47 input=a9049054013a1b77]*/
+
+#ifndef TIME_CLOCK_SETTIME_METHODDEF
+    #define TIME_CLOCK_SETTIME_METHODDEF
+#endif /* !defined(TIME_CLOCK_SETTIME_METHODDEF) */
+
+#ifndef TIME_CLOCK_SETTIME_NS_METHODDEF
+    #define TIME_CLOCK_SETTIME_NS_METHODDEF
+#endif /* !defined(TIME_CLOCK_SETTIME_NS_METHODDEF) */
+
+#ifndef TIME_CLOCK_GETRES_METHODDEF
+    #define TIME_CLOCK_GETRES_METHODDEF
+#endif /* !defined(TIME_CLOCK_GETRES_METHODDEF) */
+
+#ifndef TIME_PTHREAD_GETCPUCLOCKID_METHODDEF
+    #define TIME_PTHREAD_GETCPUCLOCKID_METHODDEF
+#endif /* !defined(TIME_PTHREAD_GETCPUCLOCKID_METHODDEF) */
+
+#ifndef TIME_MKTIME_METHODDEF
+    #define TIME_MKTIME_METHODDEF
+#endif /* !defined(TIME_MKTIME_METHODDEF) */
+
+#ifndef TIME_TZSET_METHODDEF
+    #define TIME_TZSET_METHODDEF
+#endif /* !defined(TIME_TZSET_METHODDEF) */
+
+#ifndef TIME_THREAD_TIME_METHODDEF
+    #define TIME_THREAD_TIME_METHODDEF
+#endif /* !defined(TIME_THREAD_TIME_METHODDEF) */
+
+#ifndef TIME_THREAD_TIME_NS_METHODDEF
+    #define TIME_THREAD_TIME_NS_METHODDEF
+#endif /* !defined(TIME_THREAD_TIME_NS_METHODDEF) */
+/*[clinic end generated code: output=540a094cac69e0d4 input=a9049054013a1b77]*/
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 0005974b52499ce..98db74c2222f204 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -96,33 +96,36 @@ get_time_state(PyObject *module)
 }
 
 
-static PyObject*
-_PyFloat_FromPyTime(PyTime_t t)
-{
-    double d = PyTime_AsSecondsDouble(t);
-    return PyFloat_FromDouble(d);
-}
+/*[clinic input]
+time.time -> double
 
+Return the current time in seconds since the Epoch.
 
-static PyObject *
-time_time(PyObject *self, PyObject *unused)
+Fractions of a second may be present if the system clock provides
+them.
+[clinic start generated code]*/
+
+static double
+time_time_impl(PyObject *module)
+/*[clinic end generated code: output=4adfc457b48923ca input=eea2e80c63bbcaad]*/
 {
     PyTime_t t;
     if (PyTime_Time(&t) < 0) {
-        return NULL;
+        return -1.0;
     }
-    return _PyFloat_FromPyTime(t);
+    return PyTime_AsSecondsDouble(t);
 }
 
 
-PyDoc_STRVAR(time_doc,
-"time() -> floating-point number\n\
-\n\
-Return the current time in seconds since the Epoch.\n\
-Fractions of a second may be present if the system clock provides them.");
+/*[clinic input]
+time.time_ns
+
+Return the current time in nanoseconds since the Epoch.
+[clinic start generated code]*/
 
 static PyObject *
-time_time_ns(PyObject *self, PyObject *unused)
+time_time_ns_impl(PyObject *module)
+/*[clinic end generated code: output=f5f1924ebdcf1cf3 input=3acccd9786731be4]*/
 {
     PyTime_t t;
     if (PyTime_Time(&t) < 0) {
@@ -131,11 +134,6 @@ time_time_ns(PyObject *self, PyObject *unused)
     return PyLong_FromInt64(t);
 }
 
-PyDoc_STRVAR(time_ns_doc,
-"time_ns() -> int\n\
-\n\
-Return the current time in nanoseconds since the Epoch.");
-
 #ifdef HAVE_CLOCK
 
 #ifndef CLOCKS_PER_SEC
@@ -266,18 +264,24 @@ time_clock_gettime_ns_impl(PyObject *module, clockid_t 
clk_id)
 #endif   /* HAVE_CLOCK_GETTIME */
 
 #ifdef HAVE_CLOCK_SETTIME
+/*[clinic input]
+time.clock_settime
+
+    clk_id: int
+    time as obj: object
+    /
+
+Set the time of the specified clock clk_id.
+[clinic start generated code]*/
+
 static PyObject *
-time_clock_settime(PyObject *self, PyObject *args)
+time_clock_settime_impl(PyObject *module, int clk_id, PyObject *obj)
+/*[clinic end generated code: output=ff2fc2e129f5fdea input=0e71daa237ff6edc]*/
 {
-    int clk_id;
-    PyObject *obj;
     PyTime_t t;
     struct timespec tp;
     int ret;
 
-    if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj))
-        return NULL;
-
     if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0)
         return NULL;
 
@@ -292,24 +296,24 @@ time_clock_settime(PyObject *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(clock_settime_doc,
-"clock_settime(clk_id, time)\n\
-\n\
-Set the time of the specified clock clk_id.");
+/*[clinic input]
+time.clock_settime_ns
+
+    clk_id: int
+    time as obj: object
+    /
+
+Set the time of the specified clock clk_id with nanoseconds.
+[clinic start generated code]*/
 
 static PyObject *
-time_clock_settime_ns(PyObject *self, PyObject *args)
+time_clock_settime_ns_impl(PyObject *module, int clk_id, PyObject *obj)
+/*[clinic end generated code: output=5d40ca0217bfe058 input=f2333aae32a7f441]*/
 {
-    int clk_id;
-    PyObject *obj;
     PyTime_t t;
     struct timespec ts;
     int ret;
 
-    if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) {
-        return NULL;
-    }
-
     if (PyLong_AsInt64(obj, &t) < 0) {
         return NULL;
     }
@@ -325,37 +329,34 @@ time_clock_settime_ns(PyObject *self, PyObject *args)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(clock_settime_ns_doc,
-"clock_settime_ns(clk_id, time)\n\
-\n\
-Set the time of the specified clock clk_id with nanoseconds.");
 #endif   /* HAVE_CLOCK_SETTIME */
 
 #ifdef HAVE_CLOCK_GETRES
-static PyObject *
-time_clock_getres(PyObject *self, PyObject *args)
+/*[clinic input]
+time.clock_getres -> double
+
+    clk_id: int
+    /
+
+Return the resolution (precision) of the specified clock clk_id.
+[clinic start generated code]*/
+
+static double
+time_clock_getres_impl(PyObject *module, int clk_id)
+/*[clinic end generated code: output=94c4fb7df9f0c2f2 input=d1409a8b5b3be180]*/
 {
     int ret;
-    int clk_id;
     struct timespec tp;
 
-    if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id))
-        return NULL;
-
     ret = clock_getres((clockid_t)clk_id, &tp);
     if (ret != 0) {
         PyErr_SetFromErrno(PyExc_OSError);
-        return NULL;
+        return -1.0;
     }
 
-    return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
+    return tp.tv_sec + tp.tv_nsec * 1e-9;
 }
 
-PyDoc_STRVAR(clock_getres_doc,
-"clock_getres(clk_id) -> floating-point number\n\
-\n\
-Return the resolution (precision) of the specified clock clk_id.");
-
 #ifdef __APPLE__
 #pragma clang diagnostic pop
 #endif
@@ -363,15 +364,21 @@ Return the resolution (precision) of the specified clock 
clk_id.");
 #endif   /* HAVE_CLOCK_GETRES */
 
 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
+/*[clinic input]
+time.pthread_getcpuclockid
+
+    thread_id: unsigned_long(bitwise=True)
+    /
+
+Return the clk_id of a thread's CPU time clock.
+[clinic start generated code]*/
+
 static PyObject *
-time_pthread_getcpuclockid(PyObject *self, PyObject *args)
+time_pthread_getcpuclockid_impl(PyObject *module, unsigned long thread_id)
+/*[clinic end generated code: output=4fc7d4cb73d2e894 input=eb8af7bbcf189270]*/
 {
-    unsigned long thread_id;
     int err;
     clockid_t clk_id;
-    if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) {
-        return NULL;
-    }
     err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id);
     if (err) {
         errno = err;
@@ -384,14 +391,22 @@ time_pthread_getcpuclockid(PyObject *self, PyObject *args)
     return PyLong_FromLong(clk_id);
 }
 
-PyDoc_STRVAR(pthread_getcpuclockid_doc,
-"pthread_getcpuclockid(thread_id) -> int\n\
-\n\
-Return the clk_id of a thread's CPU time clock.");
 #endif /* HAVE_PTHREAD_GETCPUCLOCKID */
 
+/*[clinic input]
+time.sleep
+
+    seconds as timeout_obj: object
+    /
+
+Delay execution for a given number of seconds.
+
+The argument may be a floating-point number for subsecond precision.
+[clinic start generated code]*/
+
 static PyObject *
-time_sleep(PyObject *self, PyObject *timeout_obj)
+time_sleep(PyObject *module, PyObject *timeout_obj)
+/*[clinic end generated code: output=f46e88f5f5756f65 input=3928b1704a2faa12]*/
 {
     if (PySys_Audit("time.sleep", "O", timeout_obj) < 0) {
         return NULL;
@@ -411,12 +426,6 @@ time_sleep(PyObject *self, PyObject *timeout_obj)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(sleep_doc,
-"sleep(seconds)\n\
-\n\
-Delay execution for a given number of seconds.  The argument may be\n\
-a floating-point number for subsecond precision.");
-
 static PyStructSequence_Field struct_time_type_fields[] = {
     {"tm_year", "year, for example, 1993"},
     {"tm_mon", "month of year, range [1, 12]"},
@@ -500,19 +509,16 @@ tmtotuple(time_module_state *state, struct tm *p
     return v;
 }
 
-/* Parse arg tuple that can contain an optional float-or-None value;
-   format needs to be "|O:name".
+/* Convert a number of seconds since the Epoch, or None which means the
+   current time, to time_t.
    Returns non-zero on success (parallels PyArg_ParseTuple).
 */
 static int
-parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
+parse_time_t_arg(PyObject *ot, time_t *pwhen)
 {
-    PyObject *ot = NULL;
     time_t whent;
 
-    if (!PyArg_ParseTuple(args, format, &ot))
-        return 0;
-    if (ot == NULL || ot == Py_None) {
+    if (ot == Py_None) {
         whent = time(NULL);
     }
     else {
@@ -523,13 +529,29 @@ parse_time_t_args(PyObject *args, const char *format, 
time_t *pwhen)
     return 1;
 }
 
+/*[clinic input]
+time.gmtime
+
+    seconds as ot: object = None
+    /
+
+Convert seconds since the Epoch to a time tuple expressing UTC.
+
+That is, Greenwich Mean Time.  When 'seconds' is not passed in, convert
+the current time instead.
+
+If the platform supports the tm_gmtoff and tm_zone, they are available
+as attributes only.
+[clinic start generated code]*/
+
 static PyObject *
-time_gmtime(PyObject *module, PyObject *args)
+time_gmtime_impl(PyObject *module, PyObject *ot)
+/*[clinic end generated code: output=375372dd236a6ed6 input=784de5b57649d4d7]*/
 {
     time_t when;
     struct tm buf;
 
-    if (!parse_time_t_args(args, "|O:gmtime", &when))
+    if (!parse_time_t_arg(ot, &when))
         return NULL;
 
     errno = 0;
@@ -557,23 +579,25 @@ timegm(struct tm *p)
 }
 #endif
 
-PyDoc_STRVAR(gmtime_doc,
-"gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\
-                       tm_sec, tm_wday, tm_yday, tm_isdst)\n\
-\n\
-Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
-GMT).  When 'seconds' is not passed in, convert the current time instead.\n\
-\n\
-If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
-attributes only.");
+/*[clinic input]
+time.localtime
+
+    seconds as ot: object = None
+    /
+
+Convert seconds since the Epoch to a time tuple expressing local time.
+
+When 'seconds' is not passed in, convert the current time instead.
+[clinic start generated code]*/
 
 static PyObject *
-time_localtime(PyObject *module, PyObject *args)
+time_localtime_impl(PyObject *module, PyObject *ot)
+/*[clinic end generated code: output=d3c1c6818abd34a1 input=43b4e8bf4914300e]*/
 {
     time_t when;
     struct tm buf;
 
-    if (!parse_time_t_args(args, "|O:localtime", &when))
+    if (!parse_time_t_arg(ot, &when))
         return NULL;
     if (_PyTime_localtime(when, &buf) != 0)
         return NULL;
@@ -597,13 +621,6 @@ time_localtime(PyObject *module, PyObject *args)
 static const char *utc_string = NULL;
 #endif
 
-PyDoc_STRVAR(localtime_doc,
-"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\
-                          tm_sec,tm_wday,tm_yday,tm_isdst)\n\
-\n\
-Convert seconds since the Epoch to a time tuple expressing local time.\n\
-When 'seconds' is not passed in, convert the current time instead.");
-
 /* Convert 9-item tuple to tm structure.  Return 1 on success, set
  * an exception and return 0 on error.
  */
@@ -1031,15 +1048,24 @@ _asctime(struct tm *timeptr)
         1900 + timeptr->tm_year);
 }
 
+/*[clinic input]
+time.asctime
+
+    time_tuple as tup: object = NULL
+    /
+
+Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.
+
+When the time tuple is not present, current time as returned by
+localtime() is used.
+[clinic start generated code]*/
+
 static PyObject *
-time_asctime(PyObject *module, PyObject *args)
+time_asctime_impl(PyObject *module, PyObject *tup)
+/*[clinic end generated code: output=a1bc45f84a00fb55 input=083c132f3cb23f1e]*/
 {
-    PyObject *tup = NULL;
     struct tm buf;
 
-    if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup))
-        return NULL;
-
     time_module_state *state = get_time_state(module);
     if (tup == NULL) {
         time_t tt = time(NULL);
@@ -1055,35 +1081,48 @@ time_asctime(PyObject *module, PyObject *args)
     return _asctime(&buf);
 }
 
-PyDoc_STRVAR(asctime_doc,
-"asctime([time_tuple]) -> string\n\
-\n\
-Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\
-When the time tuple is not present, current time as returned by localtime()\n\
-is used.");
+/*[clinic input]
+time.ctime
+
+    seconds as ot: object = None
+    /
+
+Convert a time in seconds since the Epoch to a string in local time.
+
+This is equivalent to asctime(localtime(seconds)).  When 'seconds' is
+not passed in, convert the current time instead.
+[clinic start generated code]*/
 
 static PyObject *
-time_ctime(PyObject *self, PyObject *args)
+time_ctime_impl(PyObject *module, PyObject *ot)
+/*[clinic end generated code: output=c3a028f5c6931cbc input=ee744f25ce87d1ae]*/
 {
     time_t tt;
     struct tm buf;
-    if (!parse_time_t_args(args, "|O:ctime", &tt))
+    if (!parse_time_t_arg(ot, &tt))
         return NULL;
     if (_PyTime_localtime(tt, &buf) != 0)
         return NULL;
     return _asctime(&buf);
 }
 
-PyDoc_STRVAR(ctime_doc,
-"ctime([seconds]) -> string\n\
-\n\
-Convert a time in seconds since the Epoch to a string in local time.\n\
-This is equivalent to asctime(localtime(seconds)). When 'seconds' is not\n\
-passed in, convert the current time instead.");
-
 #ifdef HAVE_MKTIME
+/*[clinic input]
+time.mktime
+
+    time_tuple as tm_tuple: object
+    /
+
+Convert a time tuple in local time to seconds since the Epoch.
+
+Note that mktime(gmtime(0)) will not generally return zero for most
+time zones; instead the returned value will either be equal to that of
+the timezone or altzone attributes on the time module.
+[clinic start generated code]*/
+
 static PyObject *
 time_mktime(PyObject *module, PyObject *tm_tuple)
+/*[clinic end generated code: output=1b2a224cd309deb7 input=70b93e1c2e57e14e]*/
 {
     struct tm tm;
     time_t tt;
@@ -1152,20 +1191,29 @@ time_mktime(PyObject *module, PyObject *tm_tuple)
     return PyFloat_FromDouble((double)tt);
 }
 
-PyDoc_STRVAR(mktime_doc,
-"mktime(time_tuple) -> floating-point number\n\
-\n\
-Convert a time tuple in local time to seconds since the Epoch.\n\
-Note that mktime(gmtime(0)) will not generally return zero for most\n\
-time zones; instead the returned value will either be equal to that\n\
-of the timezone or altzone attributes on the time module.");
 #endif /* HAVE_MKTIME */
 
 #ifdef HAVE_WORKING_TZSET
 static int init_timezone(PyObject *module);
 
+/*[clinic input]
+time.tzset
+
+Initialize, or reinitialize, the local timezone.
+
+The local timezone is set to the value stored in os.environ['TZ'].  The
+TZ environment variable should be specified in standard Unix timezone
+format as documented in the tzset man page (eg. 'US/Eastern',
+'Europe/Amsterdam').  Unknown timezones will silently fall back to UTC.
+If the TZ environment variable is not set, the local timezone is set to
+the systems best guess of wallclock time.  Changing the TZ environment
+variable without calling tzset *may* change the local timezone used by
+methods such as localtime, but this behaviour should not be relied on.
+[clinic start generated code]*/
+
 static PyObject *
-time_tzset(PyObject *self, PyObject *unused)
+time_tzset_impl(PyObject *module)
+/*[clinic end generated code: output=d1564ac4d48d320b input=a4d11aab49badf88]*/
 {
     PyObject* m;
 
@@ -1190,38 +1238,35 @@ time_tzset(PyObject *self, PyObject *unused)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(tzset_doc,
-"tzset()\n\
-\n\
-Initialize, or reinitialize, the local timezone to the value stored in\n\
-os.environ['TZ']. The TZ environment variable should be specified in\n\
-standard Unix timezone format as documented in the tzset man page\n\
-(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\
-fall back to UTC. If the TZ environment variable is not set, the local\n\
-timezone is set to the systems best guess of wallclock time.\n\
-Changing the TZ environment variable without calling tzset *may* change\n\
-the local timezone used by methods such as localtime, but this behaviour\n\
-should not be relied on.");
 #endif /* HAVE_WORKING_TZSET */
 
 
-static PyObject *
-time_monotonic(PyObject *self, PyObject *unused)
+/*[clinic input]
+time.monotonic -> double
+
+Monotonic clock, cannot go backward.
+[clinic start generated code]*/
+
+static double
+time_monotonic_impl(PyObject *module)
+/*[clinic end generated code: output=ab51899a17e16542 input=059cb42b2bad6df0]*/
 {
     PyTime_t t;
     if (PyTime_Monotonic(&t) < 0) {
-        return NULL;
+        return -1.0;
     }
-    return _PyFloat_FromPyTime(t);
+    return PyTime_AsSecondsDouble(t);
 }
 
-PyDoc_STRVAR(monotonic_doc,
-"monotonic() -> float\n\
-\n\
-Monotonic clock, cannot go backward.");
+/*[clinic input]
+time.monotonic_ns
+
+Monotonic clock, cannot go backward, as nanoseconds.
+[clinic start generated code]*/
 
 static PyObject *
-time_monotonic_ns(PyObject *self, PyObject *unused)
+time_monotonic_ns_impl(PyObject *module)
+/*[clinic end generated code: output=57a9261f91740349 input=14032d6b1601a300]*/
 {
     PyTime_t t;
     if (PyTime_Monotonic(&t) < 0) {
@@ -1230,30 +1275,32 @@ time_monotonic_ns(PyObject *self, PyObject *unused)
     return PyLong_FromInt64(t);
 }
 
-PyDoc_STRVAR(monotonic_ns_doc,
-"monotonic_ns() -> int\n\
-\n\
-Monotonic clock, cannot go backward, as nanoseconds.");
+/*[clinic input]
+time.perf_counter -> double
 
+Performance counter for benchmarking.
+[clinic start generated code]*/
 
-static PyObject *
-time_perf_counter(PyObject *self, PyObject *unused)
+static double
+time_perf_counter_impl(PyObject *module)
+/*[clinic end generated code: output=6eee280ca7b73cb1 input=f786239c5015893b]*/
 {
     PyTime_t t;
     if (PyTime_PerfCounter(&t) < 0) {
-        return NULL;
+        return -1.0;
     }
-    return _PyFloat_FromPyTime(t);
+    return PyTime_AsSecondsDouble(t);
 }
 
-PyDoc_STRVAR(perf_counter_doc,
-"perf_counter() -> float\n\
-\n\
-Performance counter for benchmarking.");
+/*[clinic input]
+time.perf_counter_ns
 
+Performance counter for benchmarking as nanoseconds.
+[clinic start generated code]*/
 
 static PyObject *
-time_perf_counter_ns(PyObject *self, PyObject *unused)
+time_perf_counter_ns_impl(PyObject *module)
+/*[clinic end generated code: output=e11a728338108d42 input=178bf260d7d48a02]*/
 {
     PyTime_t t;
     if (PyTime_PerfCounter(&t) < 0) {
@@ -1262,12 +1309,6 @@ time_perf_counter_ns(PyObject *self, PyObject *unused)
     return PyLong_FromInt64(t);
 }
 
-PyDoc_STRVAR(perf_counter_ns_doc,
-"perf_counter_ns() -> int\n\
-\n\
-Performance counter for benchmarking as nanoseconds.");
-
-
 // gh-115714: Don't use times() on WASI.
 #if defined(HAVE_TIMES) && !defined(__wasi__)
 static int
@@ -1424,24 +1465,37 @@ py_process_time(time_module_state *state, PyTime_t *tp,
 #endif
 }
 
-static PyObject *
-time_process_time(PyObject *module, PyObject *unused)
+/*[clinic input]
+time.process_time -> double
+
+Process time for profiling.
+
+That is the sum of the kernel and user-space CPU time.
+[clinic start generated code]*/
+
+static double
+time_process_time_impl(PyObject *module)
+/*[clinic end generated code: output=13b593cb16d415a8 input=6d539ae686c37c06]*/
 {
     time_module_state *state = get_time_state(module);
     PyTime_t t;
     if (py_process_time(state, &t, NULL) < 0) {
-        return NULL;
+        return -1.0;
     }
-    return _PyFloat_FromPyTime(t);
+    return PyTime_AsSecondsDouble(t);
 }
 
-PyDoc_STRVAR(process_time_doc,
-"process_time() -> float\n\
-\n\
-Process time for profiling: sum of the kernel and user-space CPU time.");
+/*[clinic input]
+time.process_time_ns
+
+Process time for profiling as nanoseconds.
+
+That is the sum of the kernel and user-space CPU time.
+[clinic start generated code]*/
 
 static PyObject *
-time_process_time_ns(PyObject *module, PyObject *unused)
+time_process_time_ns_impl(PyObject *module)
+/*[clinic end generated code: output=857f0c20105c4d1a input=6d998fd7a213c0cd]*/
 {
     time_module_state *state = get_time_state(module);
     PyTime_t t;
@@ -1451,13 +1505,6 @@ time_process_time_ns(PyObject *module, PyObject *unused)
     return PyLong_FromInt64(t);
 }
 
-PyDoc_STRVAR(process_time_ns_doc,
-"process_time() -> int\n\
-\n\
-Process time for profiling as nanoseconds:\n\
-sum of the kernel and user-space CPU time.");
-
-
 #if defined(MS_WINDOWS)
 #define HAVE_THREAD_TIME
 static int
@@ -1599,23 +1646,36 @@ _PyTime_GetThreadTimeWithInfo(PyTime_t *tp, 
_Py_clock_info_t *info)
 #pragma clang diagnostic ignored "-Wunguarded-availability"
 #endif
 
-static PyObject *
-time_thread_time(PyObject *self, PyObject *unused)
+/*[clinic input]
+time.thread_time -> double
+
+Thread time for profiling.
+
+That is the sum of the kernel and user-space CPU time.
+[clinic start generated code]*/
+
+static double
+time_thread_time_impl(PyObject *module)
+/*[clinic end generated code: output=33f6639edb42e8f5 input=cdf4621822b8ed60]*/
 {
     PyTime_t t;
     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
-        return NULL;
+        return -1.0;
     }
-    return _PyFloat_FromPyTime(t);
+    return PyTime_AsSecondsDouble(t);
 }
 
-PyDoc_STRVAR(thread_time_doc,
-"thread_time() -> float\n\
-\n\
-Thread time for profiling: sum of the kernel and user-space CPU time.");
+/*[clinic input]
+time.thread_time_ns
+
+Thread time for profiling as nanoseconds.
+
+That is the sum of the kernel and user-space CPU time.
+[clinic start generated code]*/
 
 static PyObject *
-time_thread_time_ns(PyObject *self, PyObject *unused)
+time_thread_time_ns_impl(PyObject *module)
+/*[clinic end generated code: output=2a1ac9cc3e1d4c37 input=a79b2b91f308277d]*/
 {
     PyTime_t t;
     if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) {
@@ -1624,12 +1684,6 @@ time_thread_time_ns(PyObject *self, PyObject *unused)
     return PyLong_FromInt64(t);
 }
 
-PyDoc_STRVAR(thread_time_ns_doc,
-"thread_time() -> int\n\
-\n\
-Thread time for profiling as nanoseconds:\n\
-sum of the kernel and user-space CPU time.");
-
 #ifdef __APPLE__
 #pragma clang diagnostic pop
 #endif
@@ -1637,18 +1691,23 @@ sum of the kernel and user-space CPU time.");
 #endif
 
 
+/*[clinic input]
+time.get_clock_info
+
+    name: str
+    /
+
+Get information of the specified clock.
+[clinic start generated code]*/
+
 static PyObject *
-time_get_clock_info(PyObject *module, PyObject *args)
+time_get_clock_info_impl(PyObject *module, const char *name)
+/*[clinic end generated code: output=a77a07bdf3554bd6 input=6812ae049f1b1031]*/
 {
-    char *name;
     _Py_clock_info_t info;
     PyObject *obj = NULL, *dict, *ns;
     PyTime_t t;
 
-    if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) {
-        return NULL;
-    }
-
 #ifdef Py_DEBUG
     info.implementation = NULL;
     info.monotonic = -1;
@@ -1760,11 +1819,6 @@ time_get_clock_info(PyObject *module, PyObject *args)
     return NULL;
 }
 
-PyDoc_STRVAR(get_clock_info_doc,
-"get_clock_info(name: str) -> dict\n\
-\n\
-Get information of the specified clock.");
-
 #ifndef HAVE_DECL_TZNAME
 static void
 get_zone(char *zone, int n, struct tm *p)
@@ -1913,48 +1967,48 @@ init_timezone(PyObject *m)
 #include "clinic/timemodule.c.h"
 
 static PyMethodDef time_methods[] = {
-    {"time",            time_time, METH_NOARGS, time_doc},
-    {"time_ns",         time_time_ns, METH_NOARGS, time_ns_doc},
+    TIME_TIME_METHODDEF
+    TIME_TIME_NS_METHODDEF
 #ifdef HAVE_CLOCK_GETTIME
     TIME_CLOCK_GETTIME_METHODDEF
     TIME_CLOCK_GETTIME_NS_METHODDEF
 #endif
 #ifdef HAVE_CLOCK_SETTIME
-    {"clock_settime",   time_clock_settime, METH_VARARGS, clock_settime_doc},
-    {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, 
clock_settime_ns_doc},
+    TIME_CLOCK_SETTIME_METHODDEF
+    TIME_CLOCK_SETTIME_NS_METHODDEF
 #endif
 #ifdef HAVE_CLOCK_GETRES
-    {"clock_getres",    time_clock_getres, METH_VARARGS, clock_getres_doc},
+    TIME_CLOCK_GETRES_METHODDEF
 #endif
 #ifdef HAVE_PTHREAD_GETCPUCLOCKID
-    {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, 
pthread_getcpuclockid_doc},
+    TIME_PTHREAD_GETCPUCLOCKID_METHODDEF
 #endif
-    {"sleep",           time_sleep, METH_O, sleep_doc},
-    {"gmtime",          time_gmtime, METH_VARARGS, gmtime_doc},
-    {"localtime",       time_localtime, METH_VARARGS, localtime_doc},
-    {"asctime",         time_asctime, METH_VARARGS, asctime_doc},
-    {"ctime",           time_ctime, METH_VARARGS, ctime_doc},
+    TIME_SLEEP_METHODDEF
+    TIME_GMTIME_METHODDEF
+    TIME_LOCALTIME_METHODDEF
+    TIME_ASCTIME_METHODDEF
+    TIME_CTIME_METHODDEF
 #ifdef HAVE_MKTIME
-    {"mktime",          time_mktime, METH_O, mktime_doc},
+    TIME_MKTIME_METHODDEF
 #endif
 #ifdef HAVE_STRFTIME
     {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
 #endif
     {"strptime",        time_strptime, METH_VARARGS, strptime_doc},
 #ifdef HAVE_WORKING_TZSET
-    {"tzset",           time_tzset, METH_NOARGS, tzset_doc},
+    TIME_TZSET_METHODDEF
 #endif
-    {"monotonic",       time_monotonic, METH_NOARGS, monotonic_doc},
-    {"monotonic_ns",    time_monotonic_ns, METH_NOARGS, monotonic_ns_doc},
-    {"process_time",    time_process_time, METH_NOARGS, process_time_doc},
-    {"process_time_ns", time_process_time_ns, METH_NOARGS, 
process_time_ns_doc},
+    TIME_MONOTONIC_METHODDEF
+    TIME_MONOTONIC_NS_METHODDEF
+    TIME_PROCESS_TIME_METHODDEF
+    TIME_PROCESS_TIME_NS_METHODDEF
 #ifdef HAVE_THREAD_TIME
-    {"thread_time",     time_thread_time, METH_NOARGS, thread_time_doc},
-    {"thread_time_ns",  time_thread_time_ns, METH_NOARGS, thread_time_ns_doc},
+    TIME_THREAD_TIME_METHODDEF
+    TIME_THREAD_TIME_NS_METHODDEF
 #endif
-    {"perf_counter",    time_perf_counter, METH_NOARGS, perf_counter_doc},
-    {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, 
perf_counter_ns_doc},
-    {"get_clock_info",  time_get_clock_info, METH_VARARGS, get_clock_info_doc},
+    TIME_PERF_COUNTER_METHODDEF
+    TIME_PERF_COUNTER_NS_METHODDEF
+    TIME_GET_CLOCK_INFO_METHODDEF
     {NULL,              NULL}           /* sentinel */
 };
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to