Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 42 additions & 36 deletions Doc/library/time.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,24 @@ An explanation of some terminology and conventions is in order.
Functions
---------

.. function:: asctime([t])
.. function:: asctime([time_tuple])

Convert a tuple or :class:`struct_time` representing a time as returned by
:func:`gmtime` or :func:`localtime` to a string of the following
form: ``'Sun Jun 20 23:21:05 1993'``. The day field is two characters long
and is space padded if the day is a single digit,
e.g.: ``'Wed Jun 9 04:26:40 1993'``.
for example: ``'Wed Jun 9 04:26:40 1993'``.

If *t* is not provided, the current time as returned by :func:`localtime`
is used. Locale information is not used by :func:`asctime`.
If *time_tuple* is not provided,
the current time as returned by :func:`localtime` is used.
Locale information is not used by :func:`asctime`.

.. note::

Unlike the C function of the same name, :func:`asctime` does not add a
trailing newline.

.. function:: pthread_getcpuclockid(thread_id)
.. function:: pthread_getcpuclockid(thread_id, /)

Return the *clk_id* of the thread-specific CPU-time clock for the specified *thread_id*.

Expand All @@ -157,7 +158,7 @@ Functions

.. versionadded:: 3.7

.. function:: clock_getres(clk_id)
.. function:: clock_getres(clk_id, /)

Return the resolution (precision) of the specified clock *clk_id*. Refer to
:ref:`time-clock-id-constants` for a list of accepted values for *clk_id*.
Expand All @@ -167,7 +168,7 @@ Functions
.. versionadded:: 3.3


.. function:: clock_gettime(clk_id) -> float
.. function:: clock_gettime(clk_id, /) -> float

Return the time of the specified clock *clk_id*. Refer to
:ref:`time-clock-id-constants` for a list of accepted values for *clk_id*.
Expand All @@ -180,7 +181,7 @@ Functions
.. versionadded:: 3.3


.. function:: clock_gettime_ns(clk_id) -> int
.. function:: clock_gettime_ns(clk_id, /) -> int

Similar to :func:`clock_gettime` but return time as nanoseconds.

Expand All @@ -189,7 +190,7 @@ Functions
.. versionadded:: 3.7


.. function:: clock_settime(clk_id, time)
.. function:: clock_settime(clk_id, time, /)

Set the time of the specified clock *clk_id*. Currently,
:data:`CLOCK_REALTIME` is the only accepted value for *clk_id*.
Expand All @@ -205,7 +206,7 @@ Functions
Accepts any real number as *time*, not only integer or float.


.. function:: clock_settime_ns(clk_id, time: int)
.. function:: clock_settime_ns(clk_id, time: int, /)

Similar to :func:`clock_settime` but set time with nanoseconds.

Expand All @@ -214,23 +215,23 @@ Functions
.. versionadded:: 3.7


.. function:: ctime([secs])
.. function:: ctime(seconds=None, /)

Convert a time expressed in seconds since the epoch_ to a string of a form:
``'Sun Jun 20 23:21:05 1993'`` representing local time. The day field
is two characters long and is space padded if the day is a single digit,
e.g.: ``'Wed Jun 9 04:26:40 1993'``.
for example: ``'Wed Jun 9 04:26:40 1993'``.

If *secs* is not provided or :const:`None`, the current time as
returned by :func:`.time` is used. ``ctime(secs)`` is equivalent to
``asctime(localtime(secs))``. Locale information is not used by
If *seconds* is not provided or :const:`None`, the current time as
returned by :func:`.time` is used. ``ctime(seconds)`` is equivalent to
``asctime(localtime(seconds))``. Locale information is not used by
:func:`ctime`.

.. versionchanged:: 3.15
Accepts any real number, not only integer or float.


.. function:: get_clock_info(name)
.. function:: get_clock_info(name, /)

Get information on the specified clock as a namespace object.
Supported clock names and the corresponding functions to read their value
Expand All @@ -255,10 +256,10 @@ Functions
.. versionadded:: 3.3


.. function:: gmtime([secs])
.. function:: gmtime(seconds=None, /)

Convert a time expressed in seconds since the epoch_ to a :class:`struct_time` in
UTC in which the dst flag is always zero. If *secs* is not provided or
UTC in which the dst flag is always zero. If *seconds* is not provided or
:const:`None`, the current time as returned by :func:`.time` is used. Fractions
of a second are ignored. See above for a description of the
:class:`struct_time` object. See :func:`calendar.timegm` for the inverse of this
Expand All @@ -268,11 +269,12 @@ Functions
Accepts any real number, not only integer or float.


.. function:: localtime([secs])
.. function:: localtime(seconds=None, /)

Like :func:`gmtime` but converts to local time. If *secs* is not provided or
:const:`None`, the current time as returned by :func:`.time` is used. The dst
flag is set to ``1`` when DST applies to the given time.
Like :func:`gmtime` but converts to local time.
If *seconds* is not provided or :const:`None`,
the current time as returned by :func:`.time` is used.
The dst flag is set to ``1`` when DST applies to the given time.

:func:`localtime` may raise :exc:`OverflowError`, if the timestamp is
outside the range of values supported by the platform C :c:func:`localtime`
Expand All @@ -284,7 +286,7 @@ Functions
Accepts any real number, not only integer or float.


.. function:: mktime(t)
.. function:: mktime(time_tuple, /)

This is the inverse function of :func:`localtime`. Its argument is the
:class:`struct_time` or full 9-tuple (since the dst flag is needed; use ``-1``
Expand Down Expand Up @@ -391,7 +393,7 @@ Functions

.. versionadded:: 3.7

.. function:: sleep(secs)
.. function:: sleep(seconds, /)

Suspend execution of the calling thread for the given number of seconds.
The argument may be a non-integer to indicate a more precise sleep time.
Expand All @@ -404,13 +406,16 @@ Functions

.. rubric:: Windows implementation

On Windows, if *secs* is zero, the thread relinquishes the remainder of its
time slice to any other thread that is ready to run. If there are no other
threads ready to run, the function returns immediately, and the thread
continues execution. On Windows 10 and newer the implementation uses
On Windows, if *seconds* is zero,
the thread relinquishes the remainder of its time slice
to any other thread that is ready to run.
If there are no other threads ready to run,
the function returns immediately, and the thread continues execution.
On Windows 10 and newer the implementation uses
a `high-resolution timer
<https://learn.microsoft.com/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerexw>`_
which provides resolution of 100 nanoseconds. If *secs* is zero, ``Sleep(0)`` is used.
which provides resolution of 100 nanoseconds.
If *seconds* is zero, ``Sleep(0)`` is used.

.. rubric:: Unix implementation

Expand All @@ -425,12 +430,13 @@ Functions
To voluntarily relinquish the CPU, specify a real-time :ref:`scheduling
policy <os-scheduling-policy>` and use :func:`os.sched_yield` instead.

.. audit-event:: time.sleep secs
.. audit-event:: time.sleep seconds

.. versionchanged:: 3.5
The function now sleeps at least *secs* even if the sleep is interrupted
by a signal, except if the signal handler raises an exception (see
:pep:`475` for the rationale).
The function now sleeps at least *seconds*
even if the sleep is interrupted by a signal,
except if the signal handler raises an exception
(see :pep:`475` for the rationale).

.. versionchanged:: 3.11
On Unix, the ``clock_nanosleep()`` and ``nanosleep()`` functions are now
Expand All @@ -445,13 +451,13 @@ Functions
.. index::
single: % (percent); datetime format

.. function:: strftime(format[, t])
.. function:: strftime(format[, time_tuple])

Convert a tuple or :class:`struct_time` representing a time as returned by
:func:`gmtime` or :func:`localtime` to a string as specified by the *format*
argument. If *t* is not provided, the current time as returned by
argument. If *time_tuple* is not provided, the current time as returned by
:func:`localtime` is used. *format* must be a string. :exc:`ValueError` is
raised if any field in *t* is outside of the allowed range.
raised if any field in *time_tuple* is outside of the allowed range.

0 is a legal argument for any position in the time tuple; if it is normally
illegal the value is forced to a correct one.
Expand Down
44 changes: 40 additions & 4 deletions Lib/test/test_lazy_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,17 +678,53 @@ def test_lazy_modules_tracks_lazy_imports(self):
class ErrorHandlingTests(LazyImportTestCase):
"""Tests for error handling during lazy import reification."""

def test_missing_lazy_submodule_raises_attribute_error(self):
"""Accessing a nonexistent lazy submodule via parent attr raises AttributeError."""
def test_missing_lazy_submodule_raises_module_not_found_error(self):
"""Accessing a nonexistent lazy submodule via parent attr raises ModuleNotFoundError."""
code = textwrap.dedent("""
lazy import test.test_lazy_import.data.nonexistent_module

try:
_ = test.test_lazy_import.data.nonexistent_module
except AttributeError:
except ModuleNotFoundError:
pass
else:
raise AssertionError("AttributeError was not raised")
raise AssertionError("ModuleNotFoundError was not raised")
""")
assert_python_ok("-c", code)

def test_non_package_lazily_imported(self):
"""Accessing a nonexistent lazy name via parent attr raises ModuleNotFoundError."""
code = textwrap.dedent("""
lazy import math.pi

try:
_ = math.pi
except ModuleNotFoundError:
pass
else:
raise AssertionError("ModuleNotFoundError was not raised")
""")
assert_python_ok("-c", code)

def test_non_package_lazily_imported_as(self):
"""Doing a dotted lazy import as still works"""
code = textwrap.dedent("""
lazy import math.pi as pi
pi
""")
assert_python_ok("-c", code)

def test_missing_attribute_raises_import_error(self):
"""Accessing a nonexistent lazy name via from import raises ImportError."""
code = textwrap.dedent("""
lazy from sys import doesnotexist

try:
_ = doesnotexist
except ImportError:
pass
else:
raise AssertionError("ImportError was not raised")
""")
assert_python_ok("-c", code)

Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_lazy_import/data/lazypkg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lazy from . import bar
2 changes: 2 additions & 0 deletions Lib/test/test_lazy_import/data/lazypkg/bar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
print("BAR_MODULE_LOADED")
def f(): pass
14 changes: 7 additions & 7 deletions Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -5611,11 +5611,11 @@ class TestLazyImportSuggestions(unittest.TestCase):

def test_attribute_error_does_not_reify_lazy_imports(self):
"""Printing an AttributeError should not trigger lazy import reification."""
# pkg.bar prints "BAR_MODULE_LOADED" when imported.
# lazypkg.bar prints "BAR_MODULE_LOADED" when imported.
# If lazy import is reified during suggestion computation, we'll see it.
code = textwrap.dedent("""
lazy import test.test_lazy_import.data.pkg.bar
test.test_lazy_import.data.pkg.nonexistent
lazy import test.test_lazy_import.data.lazypkg
test.test_lazy_import.data.lazypkg.nonexistent
""")
rc, stdout, stderr = assert_python_failure('-c', code)
self.assertNotIn(b"BAR_MODULE_LOADED", stdout)
Expand All @@ -5624,9 +5624,9 @@ def test_traceback_formatting_does_not_reify_lazy_imports(self):
"""Formatting a traceback should not trigger lazy import reification."""
code = textwrap.dedent("""
import traceback
lazy import test.test_lazy_import.data.pkg.bar
lazy import test.test_lazy_import.data.lazypkg
try:
test.test_lazy_import.data.pkg.nonexistent
test.test_lazy_import.data.lazypkg.nonexistent
except AttributeError:
traceback.format_exc()
print("OK")
Expand All @@ -5638,9 +5638,9 @@ def test_traceback_formatting_does_not_reify_lazy_imports(self):
def test_suggestion_still_works_for_non_lazy_attributes(self):
"""Suggestions should still work for non-lazy module attributes."""
code = textwrap.dedent("""
lazy import test.test_lazy_import.data.pkg.bar
lazy import test.test_lazy_import.data.lazypkg
# Typo for __name__
test.test_lazy_import.data.pkg.__nme__
test.test_lazy_import.data.lazypkg.__nme__
""")
rc, stdout, stderr = assert_python_failure('-c', code)
self.assertIn(b"__name__", stderr)
Expand Down
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -2690,6 +2690,7 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_lazy_import/data/pkg \
test/test_lazy_import/data/badsyntax \
test/test_lazy_import/data/circular_import_pkg \
test/test_lazy_import/data/lazypkg \
test/test_lazy_import/data/metasyntactic \
test/test_lazy_import/data/metasyntactic/foo \
test/test_lazy_import/data/metasyntactic/foo/ack \
Expand Down
14 changes: 7 additions & 7 deletions Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ time_strftime(PyObject *module, PyObject *args)
#undef time_char
#undef format_time
PyDoc_STRVAR(strftime_doc,
"strftime(format[, tuple]) -> string\n\
"strftime(format[, time_tuple]) -> string\n\
\n\
Convert a time tuple to a string according to a format specification.\n\
See the library reference manual for formatting codes. When the time tuple\n\
Expand All @@ -1003,7 +1003,7 @@ time_strptime(PyObject *self, PyObject *args)


PyDoc_STRVAR(strptime_doc,
"strptime(string, format) -> struct_time\n\
"strptime(string[, format]) -> struct_time\n\
\n\
Parse a string to a time tuple according to a format specification.\n\
See the library reference manual for formatting codes (same as\n\
Expand Down Expand Up @@ -1056,7 +1056,7 @@ time_asctime(PyObject *module, PyObject *args)
}

PyDoc_STRVAR(asctime_doc,
"asctime([tuple]) -> string\n\
"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\
Expand All @@ -1075,11 +1075,11 @@ time_ctime(PyObject *self, PyObject *args)
}

PyDoc_STRVAR(ctime_doc,
"ctime(seconds) -> string\n\
"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 the time tuple is\n\
not present, current time as returned by localtime() is used.");
This is equivalent to asctime(localtime(seconds)). When 'seconds' is not\n\
passed in, convert the current time instead.");

#ifdef HAVE_MKTIME
static PyObject *
Expand Down Expand Up @@ -1153,7 +1153,7 @@ time_mktime(PyObject *module, PyObject *tm_tuple)
}

PyDoc_STRVAR(mktime_doc,
"mktime(tuple) -> floating-point number\n\
"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\
Expand Down
Loading
Loading