Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ccd5715

Browse files
author
Victor Stinner
committed
PEP 410
1 parent 6f91ce7 commit ccd5715

9 files changed

Lines changed: 814 additions & 174 deletions

File tree

Doc/library/os.rst

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -808,13 +808,16 @@ as internal buffering of data.
808808
Availability: Unix.
809809

810810

811-
.. function:: fstat(fd)
811+
.. function:: fstat(fd, timestamp=None)
812812

813813
Return status for file descriptor *fd*, like :func:`~os.stat`.
814814

815815
Availability: Unix, Windows.
816816

817-
.. function:: fstatat(dirfd, path, flags=0)
817+
.. versionchanged:: 3.3
818+
Added the *timestamp* argument.
819+
820+
.. function:: fstatat(dirfd, path, flags=0, timestamp="float")
818821

819822
Like :func:`stat` but if *path* is relative, it is taken as relative to *dirfd*.
820823
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
@@ -1696,7 +1699,7 @@ Files and Directories
16961699
.. versionadded:: 3.3
16971700

16981701

1699-
.. function:: lstat(path)
1702+
.. function:: lstat(path, timestamp=None)
17001703

17011704
Perform the equivalent of an :c:func:`lstat` system call on the given path.
17021705
Similar to :func:`~os.stat`, but does not follow symbolic links. On
@@ -1706,6 +1709,9 @@ Files and Directories
17061709
.. versionchanged:: 3.2
17071710
Added support for Windows 6.0 (Vista) symbolic links.
17081711

1712+
.. versionchanged:: 3.3
1713+
The *timestamp* argument was added.
1714+
17091715

17101716
.. function:: lutimes(path[, times])
17111717

@@ -1969,7 +1975,7 @@ Files and Directories
19691975
.. versionadded:: 3.3
19701976

19711977

1972-
.. function:: stat(path)
1978+
.. function:: stat(path, timestamp=None)
19731979

19741980
Perform the equivalent of a :c:func:`stat` system call on the given path.
19751981
(This function follows symlinks; to stat a symlink use :func:`lstat`.)
@@ -1989,6 +1995,11 @@ Files and Directories
19891995
* :attr:`st_ctime` - platform dependent; time of most recent metadata change on
19901996
Unix, or the time of creation on Windows)
19911997

1998+
:attr:`st_atime`, :attr:`st_mtime` and :attr:`st_ctime` are :class:`float`
1999+
by default, or :class:`int` if :func:`os.stat_float_times` is ``False``. Set
2000+
the *timestamp* argument to get another :ref:`timestamp type
2001+
<timestamp-types>`.
2002+
19922003
On some Unix systems (such as Linux), the following attributes may also be
19932004
available:
19942005

@@ -2044,6 +2055,9 @@ Files and Directories
20442055

20452056
Availability: Unix, Windows.
20462057

2058+
.. versionchanged:: 3.3
2059+
Added the *timestamp* argument.
2060+
20472061

20482062
.. function:: stat_float_times([newvalue])
20492063

@@ -2069,6 +2083,9 @@ Files and Directories
20692083
are processed, this application should turn the feature off until the library
20702084
has been corrected.
20712085

2086+
.. deprecated:: 3.3
2087+
Use *timestamp* argument of stat functions instead.
2088+
20722089

20732090
.. function:: statvfs(path)
20742091

@@ -2859,27 +2876,39 @@ written in Python, such as a mail server's external command delivery program.
28592876
with :const:`P_NOWAIT` return suitable process handles.
28602877

28612878

2862-
.. function:: wait3([options])
2879+
.. function:: wait3(options[, timestamp=float])
28632880

28642881
Similar to :func:`waitpid`, except no process id argument is given and a
28652882
3-element tuple containing the child's process id, exit status indication, and
28662883
resource usage information is returned. Refer to :mod:`resource`.\
28672884
:func:`getrusage` for details on resource usage information. The option
28682885
argument is the same as that provided to :func:`waitpid` and :func:`wait4`.
2886+
:attr:`ru_utime` and :attr:`ru_stime` attributes of the resource usage are
2887+
:class:`float` by default, set the *timestamp* argument to get another
2888+
:ref:`timestamp type <timestamp-types>`.
28692889

28702890
Availability: Unix.
28712891

2892+
.. versionchanged:: 3.3
2893+
Added the *timestamp* argument.
2894+
28722895

2873-
.. function:: wait4(pid, options)
2896+
.. function:: wait4(pid, options[, timestamp=float])
28742897

28752898
Similar to :func:`waitpid`, except a 3-element tuple, containing the child's
28762899
process id, exit status indication, and resource usage information is returned.
28772900
Refer to :mod:`resource`.\ :func:`getrusage` for details on resource usage
28782901
information. The arguments to :func:`wait4` are the same as those provided to
28792902
:func:`waitpid`.
2903+
:attr:`ru_utime` and :attr:`ru_stime` attributes of the resource usage are
2904+
:class:`float` by default, set the *timestamp* argument to get another
2905+
:ref:`timestamp type <timestamp-types>`.
28802906

28812907
Availability: Unix.
28822908

2909+
.. versionchanged:: 3.3
2910+
Added the *timestamp* argument.
2911+
28832912

28842913
.. data:: WNOHANG
28852914

Doc/library/time.rst

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ An explanation of some terminology and conventions is in order.
9595
| local time | | |
9696
+-------------------------+-------------------------+-------------------------+
9797

98+
.. _timestamp-types:
99+
100+
* Python supports the following timestamp types:
101+
102+
* :class:`int`
103+
* :class:`float`
104+
* :class:`decimal.Decimal`
105+
98106

99107
The module defines the following functions and data items:
100108

@@ -119,7 +127,7 @@ The module defines the following functions and data items:
119127
trailing newline.
120128

121129

122-
.. function:: clock()
130+
.. function:: clock(timestamp=float)
123131

124132
.. index::
125133
single: CPU time
@@ -136,16 +144,27 @@ The module defines the following functions and data items:
136144
:c:func:`QueryPerformanceCounter`. The resolution is typically better than one
137145
microsecond.
138146

147+
Return as a floating point number by default, set the *timestamp* argument
148+
to get another :ref:`timestamp type <timestamp-types>`.
149+
150+
.. versionchanged:: 3.3
151+
Added the *timestamp* argument.
152+
139153

140-
.. function:: clock_getres(clk_id)
154+
.. function:: clock_getres(clk_id, timestamp=float)
141155

142156
Return the resolution (precision) of the specified clock *clk_id*.
157+
Return a floating point number by default, set the *timestamp* argument to
158+
get another :ref:`timestamp type <timestamp-types>`.
159+
143160

144161
.. versionadded:: 3.3
145162

146-
.. function:: clock_gettime(clk_id)
163+
.. function:: clock_gettime(clk_id, timestamp=float)
147164

148165
Return the time of the specified clock *clk_id*.
166+
Return a floating point number by default, set the *timestamp* argument to
167+
get another :ref:`timestamp type <timestamp-types>`.
149168

150169
.. versionadded:: 3.3
151170

@@ -214,19 +233,22 @@ The module defines the following functions and data items:
214233
flag is set to ``1`` when DST applies to the given time.
215234

216235

217-
.. function:: mktime(t)
236+
.. function:: mktime(t, timestamp=float)
218237

219238
This is the inverse function of :func:`localtime`. Its argument is the
220239
:class:`struct_time` or full 9-tuple (since the dst flag is needed; use ``-1``
221240
as the dst flag if it is unknown) which expresses the time in *local* time, not
222-
UTC. It returns a floating point number, for compatibility with :func:`time`.
241+
It returns a floating point number by default, for compatibility with
242+
:func:`time`, set the *timestamp* argument to get another :ref:`timestamp
243+
type <timestamp-types>`.
244+
223245
If the input value cannot be represented as a valid time, either
224246
:exc:`OverflowError` or :exc:`ValueError` will be raised (which depends on
225247
whether the invalid value is caught by Python or the underlying C libraries).
226248
The earliest date for which it can generate a time is platform-dependent.
227249

228250

229-
.. function:: monotonic()
251+
.. function:: monotonic(timestamp=float)
230252

231253
Monotonic clock. The reference point of the returned value is undefined so
232254
only the difference of consecutive calls is valid.
@@ -440,15 +462,20 @@ The module defines the following functions and data items:
440462
:exc:`TypeError` is raised.
441463

442464

443-
.. function:: time()
465+
.. function:: time(timestamp=float)
444466

445-
Return the time as a floating point number expressed in seconds since the epoch,
446-
in UTC. Note that even though the time is always returned as a floating point
467+
Return the time expressed in seconds since the epoch in UTC. Return a
468+
floating point number by default, set the *timestamp* argument to get
469+
another :ref:`timestamp type <timestamp-types>`.
470+
Note that even though the time is always returned as a floating point
447471
number, not all systems provide time with a better precision than 1 second.
448472
While this function normally returns non-decreasing values, it can return a
449473
lower value than a previous call if the system clock has been set back between
450474
the two calls.
451475

476+
.. versionchanged:: 3.3
477+
Added the *timestamp* argument.
478+
452479

453480
.. data:: timezone
454481

@@ -546,13 +573,16 @@ The module defines the following functions and data items:
546573
('EET', 'EEST')
547574

548575

549-
.. function:: wallclock()
576+
.. function:: wallclock(timestamp=float)
550577

551578
.. index::
552579
single: Wallclock
553580
single: benchmarking
554581

555582
Return the current time in fractions of a second to the system's best ability.
583+
Return a floating point number by default, set the *timestamp* argument to
584+
get another :ref:`timestamp type <timestamp-types>`.
585+
556586
Use this when the most accurate representation of wall-clock is required, i.e.
557587
when "processor time" is inappropriate. The reference point of the returned
558588
value is undefined so only the difference of consecutive calls is valid.

Doc/whatsnew/3.3.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,42 @@ new, more precise information::
270270
'<function C.D.meth at 0x7f46b9fe31e0>'
271271

272272

273+
PEP 410: Use decimal.Decimal type for timestamps
274+
================================================
275+
276+
:pep:`410` - Use decimal.Decimal type for timestamps
277+
PEP written and implemented by Victor Stinner.
278+
279+
The following functions have a new optional *timestamp* argument to get a
280+
timestamp as a :class:`decimal.Decimal` instead of :class:`int` or
281+
:class:`float`:
282+
283+
* :mod:`time` module: :func:`~time.clock`, :func:`~time.clock_gettime`,
284+
:func:`~time.clock_getres`, :func:`~time.monotonic`, :func:`~time.time` and
285+
:func:`~time.wallclock`
286+
* :mod:`os` module: :func:`~os.fstat`, :func:`~os.fstatat`, :func:`~os.lstat`
287+
and :func:`~os.stat` (``st_atime``, ``st_ctime`` and ``st_mtime`` fields of
288+
the stat structure)
289+
290+
:class:`decimal.Decimal` supports a resolution of a nanosecond (10^-9)
291+
resolution, whereas :class:`float` has only a resolution of a microsecond
292+
(10^-6) in common cases. See the list of available :ref:`timestamp types
293+
<timestamp-types>`.
294+
295+
Example::
296+
297+
>>> import decimal, time
298+
>>> time.time()
299+
1328006975.681211
300+
>>> time.time(timestamp=int)
301+
1328006979
302+
>>> time.time(timestamp=decimal.Decimal)
303+
Decimal('1328006983.761119')
304+
305+
:func:`os.stat_float_times` has been deprecated, use *timestamp* argument of
306+
`os.stat` instead.
307+
308+
273309
Other Language Changes
274310
======================
275311

Include/pytime.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
#ifndef Py_PYTIME_H
33
#define Py_PYTIME_H
44

5-
#include "pyconfig.h" /* include for defines */
5+
#include "pyport.h"
6+
#include "object.h"
67

78
/**************************************************************************
89
Symbols and macros to supply platform-independent interfaces to time related
@@ -37,6 +38,31 @@ do { \
3738
((tv_end.tv_sec - tv_start.tv_sec) + \
3839
(tv_end.tv_usec - tv_start.tv_usec) * 0.000001)
3940

41+
#if defined(HAVE_LONG_LONG)
42+
typedef unsigned PY_LONG_LONG _PyTime_fraction_t;
43+
#else
44+
typedef size_t _PyTime_fraction_t;
45+
#endif
46+
47+
typedef struct
48+
{
49+
/* timestamp = seconds + numerator / denominator */
50+
time_t seconds;
51+
_PyTime_fraction_t numerator;
52+
/* denominator cannot be zero */
53+
_PyTime_fraction_t denominator;
54+
/* the timestamp resolution is 1/divisor */
55+
} _PyTime_t;
56+
57+
/* Similar to POSIX gettimeofday. If system gettimeofday
58+
fails or is not available, fall back to lower resolution clocks. */
59+
PyAPI_FUNC(void) _PyTime_get(_PyTime_t *tp);
60+
61+
/* Convert a timestamp structure to the specified timestamp type.
62+
63+
Raise a ValueError if the timestamp type is unknown. */
64+
PyAPI_FUNC(PyObject*) _PyTime_Convert(_PyTime_t *ts, PyObject *timestamp);
65+
4066
/* Dummy to force linking. */
4167
PyAPI_FUNC(void) _PyTime_Init(void);
4268

Lib/test/test_os.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# does add tests for a few functions which have been determined to be more
33
# portable than they had been thought to be.
44

5+
import decimal
56
import os
67
import errno
78
import unittest
@@ -238,6 +239,36 @@ def test_stat_attributes_bytes(self):
238239
warnings.simplefilter("ignore", DeprecationWarning)
239240
self.check_stat_attributes(fname)
240241

242+
def test_stat_timestamp(self):
243+
# test deprecation
244+
with warnings.catch_warnings():
245+
warnings.simplefilter("error", DeprecationWarning)
246+
self.assertRaises(DeprecationWarning, os.stat_float_times, False)
247+
248+
with warnings.catch_warnings():
249+
warnings.simplefilter("ignore", DeprecationWarning)
250+
old_value = os.stat_float_times()
251+
try:
252+
# test invalid timestamp types
253+
self.assertRaises(ValueError, os.stat, self.fname,
254+
timestamp="abc")
255+
self.assertRaises(ValueError, os.stat, self.fname,
256+
timestamp=decimal.Context)
257+
258+
for float_times in (False, True):
259+
os.stat_float_times(float_times)
260+
t = os.stat(self.fname).st_mtime
261+
if float_times:
262+
self.assertIsInstance(t, float)
263+
else:
264+
self.assertIsInstance(t, int)
265+
266+
for type in (int, float, decimal.Decimal):
267+
t = os.stat(self.fname, timestamp=type).st_mtime
268+
self.assertIsInstance(t, type)
269+
finally:
270+
os.stat_float_times(old_value)
271+
241272
def test_statvfs_attributes(self):
242273
if not hasattr(os, "statvfs"):
243274
return

0 commit comments

Comments
 (0)