PEP 418: Reorganize sections, move Alternatives after Python functions
This commit is contained in:
parent
e15486af9e
commit
e7dd82585b
252
pep-0418.txt
252
pep-0418.txt
|
@ -382,6 +382,132 @@ Pseudo-code [#pseudo]_::
|
|||
|
||||
|
||||
|
||||
Alternatives: API design
|
||||
========================
|
||||
|
||||
Other names for new functions
|
||||
-----------------------------
|
||||
|
||||
time.monotonic():
|
||||
|
||||
* time.counter()
|
||||
* time.seconds()
|
||||
* time.steady()
|
||||
* time.timeout_clock()
|
||||
* time.wallclock(): it is not the system time aka the "wall clock",
|
||||
but a monotonic clock with an unspecified starting point
|
||||
|
||||
The name "time.try_monotonic()" was also proposed when
|
||||
time.monotonic() was falling back to the system clock when no
|
||||
monotonic clock was available.
|
||||
|
||||
time.perf_counter():
|
||||
|
||||
* time.hires()
|
||||
* time.highres()
|
||||
* time.timer()
|
||||
|
||||
|
||||
Only expose operating system clocks
|
||||
-----------------------------------
|
||||
|
||||
To not have to define high-level clocks, which is a difficult task, a
|
||||
simpler approach is to only expose operating system clocks.
|
||||
time.clock_gettime() and related clock identifiers were already added
|
||||
to Python 3.3 for example.
|
||||
|
||||
|
||||
Fallback to system clock
|
||||
------------------------
|
||||
|
||||
If no monotonic clock is available, time.monotonic() falls back to the
|
||||
system clock.
|
||||
|
||||
Issues:
|
||||
|
||||
* It is hard to define correctly such function in the documentation:
|
||||
is it monotonic? is it steady? is it adjusted?
|
||||
* Some user want to decide what to do when no monotonic clock is
|
||||
available: use another clock, display an error, or do something
|
||||
else?
|
||||
|
||||
|
||||
One function choosing the clock from a list of constraints
|
||||
----------------------------------------------------------
|
||||
|
||||
``time.get_clock(*flags)`` with the following flags:
|
||||
|
||||
* time.MONOTONIC: clock cannot go backward
|
||||
* time.STEADY: clock rate is steady and the clock is not adjusted
|
||||
* time.HIGHRES: clock with the highest precision
|
||||
|
||||
time.get_clock() returns None if the clock is found and so calls can
|
||||
be chained using the or operator. Example::
|
||||
|
||||
get_time = time.get_clock(time.MONOTONIC) or time.get_clock(time.STEADY) or time.time()
|
||||
t = get_time()
|
||||
|
||||
Example of flags of system clocks:
|
||||
|
||||
* QueryPerformanceCounter: MONOTONIC | HIGHRES
|
||||
* GetTickCount: MONOTONIC | STEADY
|
||||
* CLOCK_MONOTONIC: MONOTONIC | STEADY (or only MONOTONIC on Linux)
|
||||
* CLOCK_MONOTONIC_RAW: MONOTONIC | STEADY
|
||||
* gettimeofday(): (no flag)
|
||||
|
||||
|
||||
One function with a flag: time.monotonic(fallback=True)
|
||||
-------------------------------------------------------
|
||||
|
||||
* time.monotonic(fallback=True) falls back to the system clock if no
|
||||
monotonic clock is available or if the monotonic clock failed.
|
||||
* time.monotonic(fallback=False) raises OSError if monotonic clock
|
||||
fails and NotImplementedError if the system does not provide a
|
||||
monotonic clock
|
||||
|
||||
"A keyword argument that gets passed as a constant in the caller is
|
||||
usually poor API."
|
||||
|
||||
Raising NotImplementedError for a function is something uncommon in
|
||||
Python and should be avoided.
|
||||
|
||||
|
||||
One function, no flag
|
||||
---------------------
|
||||
|
||||
time.monotonic() returns (time: float, is_monotonic: bool).
|
||||
|
||||
An alternative is to use a function attribute:
|
||||
time.monotonic.is_monotonic. The attribute value would be None before
|
||||
the first call to time.monotonic().
|
||||
|
||||
|
||||
Working around operating system bugs?
|
||||
-------------------------------------
|
||||
|
||||
Should Python ensure manually that a monotonic clock is truly
|
||||
monotonic by computing the maximum with the clock value and the
|
||||
previous value?
|
||||
|
||||
Since it's relatively straightforward to cache the last value returned
|
||||
using a static variable, it might be interesting to use this to make
|
||||
sure that the values returned are indeed monotonic.
|
||||
|
||||
* Virtual machines provide less reliable clocks.
|
||||
* QueryPerformanceCounter() has known bugs (only one is not fixed yet)
|
||||
|
||||
Python may only work around a specific known operating system bug:
|
||||
`KB274323`_ contains a code example to workaround the bug (use
|
||||
GetTickCount() to detect QueryPerformanceCounter() leap).
|
||||
|
||||
Issues of a hacked monotonic function:
|
||||
|
||||
* if the clock is accidentally set forward by an hour and then back
|
||||
again, you wouldn't have a useful clock for an hour
|
||||
* the cache is not shared between processes so different processes
|
||||
wouldn't see the same clock value
|
||||
|
||||
|
||||
Glossary
|
||||
========
|
||||
|
||||
|
@ -1250,132 +1376,6 @@ and wake notifications
|
|||
Q&A QA1340).
|
||||
|
||||
|
||||
Alternatives: API design
|
||||
========================
|
||||
|
||||
Other names for new functions
|
||||
-----------------------------
|
||||
|
||||
time.monotonic():
|
||||
|
||||
* time.counter()
|
||||
* time.seconds()
|
||||
* time.steady()
|
||||
* time.timeout_clock()
|
||||
* time.wallclock(): it is not the system time aka the "wall clock",
|
||||
but a monotonic clock with an unspecified starting point
|
||||
|
||||
The name "time.try_monotonic()" was also proposed when
|
||||
time.monotonic() was falling back to the system clock when no
|
||||
monotonic clock was available.
|
||||
|
||||
time.perf_counter():
|
||||
|
||||
* time.hires()
|
||||
* time.highres()
|
||||
* time.timer()
|
||||
|
||||
|
||||
Only expose operating system clocks
|
||||
-----------------------------------
|
||||
|
||||
To not have to define high-level clocks, which is a difficult task, a
|
||||
simpler approach is to only expose operating system clocks.
|
||||
time.clock_gettime() and related clock identifiers were already added
|
||||
to Python 3.3 for example.
|
||||
|
||||
|
||||
Fallback to system clock
|
||||
------------------------
|
||||
|
||||
If no monotonic clock is available, time.monotonic() falls back to the
|
||||
system clock.
|
||||
|
||||
Issues:
|
||||
|
||||
* It is hard to define correctly such function in the documentation:
|
||||
is it monotonic? is it steady? is it adjusted?
|
||||
* Some user want to decide what to do when no monotonic clock is
|
||||
available: use another clock, display an error, or do something
|
||||
else?
|
||||
|
||||
|
||||
One function choosing the clock from a list of constraints
|
||||
----------------------------------------------------------
|
||||
|
||||
``time.get_clock(*flags)`` with the following flags:
|
||||
|
||||
* time.MONOTONIC: clock cannot go backward
|
||||
* time.STEADY: clock rate is steady and the clock is not adjusted
|
||||
* time.HIGHRES: clock with the highest precision
|
||||
|
||||
time.get_clock() returns None if the clock is found and so calls can
|
||||
be chained using the or operator. Example::
|
||||
|
||||
get_time = time.get_clock(time.MONOTONIC) or time.get_clock(time.STEADY) or time.time()
|
||||
t = get_time()
|
||||
|
||||
Example of flags of system clocks:
|
||||
|
||||
* QueryPerformanceCounter: MONOTONIC | HIGHRES
|
||||
* GetTickCount: MONOTONIC | STEADY
|
||||
* CLOCK_MONOTONIC: MONOTONIC | STEADY (or only MONOTONIC on Linux)
|
||||
* CLOCK_MONOTONIC_RAW: MONOTONIC | STEADY
|
||||
* gettimeofday(): (no flag)
|
||||
|
||||
|
||||
One function with a flag: time.monotonic(fallback=True)
|
||||
-------------------------------------------------------
|
||||
|
||||
* time.monotonic(fallback=True) falls back to the system clock if no
|
||||
monotonic clock is available or if the monotonic clock failed.
|
||||
* time.monotonic(fallback=False) raises OSError if monotonic clock
|
||||
fails and NotImplementedError if the system does not provide a
|
||||
monotonic clock
|
||||
|
||||
"A keyword argument that gets passed as a constant in the caller is
|
||||
usually poor API."
|
||||
|
||||
Raising NotImplementedError for a function is something uncommon in
|
||||
Python and should be avoided.
|
||||
|
||||
|
||||
One function, no flag
|
||||
---------------------
|
||||
|
||||
time.monotonic() returns (time: float, is_monotonic: bool).
|
||||
|
||||
An alternative is to use a function attribute:
|
||||
time.monotonic.is_monotonic. The attribute value would be None before
|
||||
the first call to time.monotonic().
|
||||
|
||||
|
||||
Working around operating system bugs?
|
||||
=====================================
|
||||
|
||||
Should Python ensure manually that a monotonic clock is truly
|
||||
monotonic by computing the maximum with the clock value and the
|
||||
previous value?
|
||||
|
||||
Since it's relatively straightforward to cache the last value returned
|
||||
using a static variable, it might be interesting to use this to make
|
||||
sure that the values returned are indeed monotonic.
|
||||
|
||||
* Virtual machines provide less reliable clocks.
|
||||
* QueryPerformanceCounter() has known bugs (only one is not fixed yet)
|
||||
|
||||
Python may only work around a specific known operating system bug:
|
||||
`KB274323`_ contains a code example to workaround the bug (use
|
||||
GetTickCount() to detect QueryPerformanceCounter() leap).
|
||||
|
||||
Issues of a hacked monotonic function:
|
||||
|
||||
* if the clock is accidentally set forward by an hour and then back
|
||||
again, you wouldn't have a useful clock for an hour
|
||||
* the cache is not shared between processes so different processes
|
||||
wouldn't see the same clock value
|
||||
|
||||
|
||||
Footnotes
|
||||
=========
|
||||
|
||||
|
|
Loading…
Reference in New Issue