Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
6fe20b3a
Commit
6fe20b3a
authored
Apr 19, 2012
by
Larry Hastings
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #14127: Add st_{cma}time_ns fields to os.stat() result object.
parent
dd5aa36f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
33 deletions
+96
-33
Doc/library/os.rst
Doc/library/os.rst
+26
-6
Include/pytime.h
Include/pytime.h
+4
-0
Lib/test/test_os.py
Lib/test/test_os.py
+7
-0
Modules/_testcapimodule.c
Modules/_testcapimodule.c
+0
-11
Modules/posixmodule.c
Modules/posixmodule.c
+48
-16
Python/pytime.c
Python/pytime.c
+11
-0
No files found.
Doc/library/os.rst
View file @
6fe20b3a
...
...
@@ -2011,8 +2011,8 @@ Files and Directories
Perform the equivalent of a :c:func:`stat` system call on the given path.
(This function follows symlinks; to stat a symlink use :func:`lstat`.)
The return value is an object whose attributes correspond
to the members
of the :c:type:`stat` structure, namely:
The return value is an object whose attributes correspond
roughly
to the members
of the :c:type:`stat` structure, namely:
* :attr:`st_mode` - protection bits,
* :attr:`st_ino` - inode number,
...
...
@@ -2021,10 +2021,18 @@ Files and Directories
* :attr:`st_uid` - user id of owner,
* :attr:`st_gid` - group id of owner,
* :attr:`st_size` - size of file, in bytes,
* :attr:`st_atime` - time of most recent access,
* :attr:`st_mtime` - time of most recent content modification,
* :attr:`st_ctime` - platform dependent; time of most recent metadata change on
Unix, or the time of creation on Windows)
* :attr:`st_atime` - time of most recent access expressed in seconds,
* :attr:`st_mtime` - time of most recent content modification
expressed in seconds,
* :attr:`st_ctime` - platform dependent; time of most recent metadata
change on Unix, or the time of creation on Windows, expressed in seconds
* :attr:`st_atime_ns` - time of most recent access
expressed in nanoseconds as an integer,
* :attr:`st_mtime_ns` - time of most recent content modification
expressed in nanoseconds as an integer,
* :attr:`st_ctime_ns` - platform dependent; time of most recent metadata
change on Unix, or the time of creation on Windows,
expressed in nanoseconds as an integer
On some Unix systems (such as Linux), the following attributes may also be
available:
...
...
@@ -2054,6 +2062,14 @@ Files and Directories
or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and
:attr:`st_atime` has only 1-day resolution. See your operating system
documentation for details.
Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`,
and :attr:`st_ctime_ns` are always expressed in nanoseconds, many
systems do not provide nanosecond precision. On systems that do
provide nanosecond precision, the floating-point object used to
store :attr:`st_atime`, :attr:`st_mtime`, and :attr:`st_ctime`
cannot preserve all of it, and as such will be slightly inexact.
If you need the exact timestamps you should always use
:attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`.
For backward compatibility, the return value of :func:`~os.stat` is also accessible
as a tuple of at least 10 integers giving the most important (and portable)
...
...
@@ -2081,6 +2097,10 @@ Files and Directories
Availability: Unix, Windows.
.. versionadded:: 3.3
The :attr:`st_atime_ns`, :attr:`st_mtime_ns`,
and :attr:`st_ctime_ns` members.
.. function:: stat_float_times([newvalue])
...
...
Include/pytime.h
View file @
6fe20b3a
...
...
@@ -44,6 +44,10 @@ PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
PyObject
*
obj
,
time_t
*
sec
);
/* Convert a time_t to a PyLong. */
PyAPI_FUNC
(
PyObject
*
)
_PyLong_FromTime_t
(
time_t
sec
);
/* Convert a number of seconds, int or float, to a timeval structure.
usec is in the range [0; 999999] and rounded towards zero.
For example, -1.2 is converted to (-2, 800000). */
...
...
Lib/test/test_os.py
View file @
6fe20b3a
...
...
@@ -191,6 +191,13 @@ class StatAttributeTests(unittest.TestCase):
result
[
getattr
(
stat
,
name
)])
self
.
assertIn
(
attr
,
members
)
# Make sure that the st_?time and st_?time_ns fields roughly agree
# (they should always agree up to the tens-of-microseconds magnitude)
for
name
in
'st_atime st_mtime st_ctime'
.
split
():
floaty
=
int
(
getattr
(
result
,
name
)
*
100000
)
nanosecondy
=
getattr
(
result
,
name
+
"_ns"
)
//
10000
self
.
assertEqual
(
floaty
,
nanosecondy
)
try
:
result
[
200
]
self
.
fail
(
"No exception thrown"
)
...
...
Modules/_testcapimodule.c
View file @
6fe20b3a
...
...
@@ -2362,17 +2362,6 @@ run_in_subinterp(PyObject *self, PyObject *args)
return
PyLong_FromLong
(
r
);
}
static
PyObject
*
_PyLong_FromTime_t
(
time_t
value
)
{
#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
return
PyLong_FromLongLong
(
value
);
#else
assert
(
sizeof
(
time_t
)
<=
sizeof
(
long
));
return
PyLong_FromLong
(
value
);
#endif
}
static
PyObject
*
test_pytime_object_to_time_t
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
Modules/posixmodule.c
View file @
6fe20b3a
...
...
@@ -1550,6 +1550,9 @@ static PyStructSequence_Field stat_result_fields[] = {
{
"st_atime"
,
"time of last access"
},
{
"st_mtime"
,
"time of last modification"
},
{
"st_ctime"
,
"time of last change"
},
{
"st_atime_ns"
,
"time of last access in nanoseconds"
},
{
"st_mtime_ns"
,
"time of last modification in nanoseconds"
},
{
"st_ctime_ns"
,
"time of last change in nanoseconds"
},
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
{
"st_blksize"
,
"blocksize for filesystem I/O"
},
#endif
...
...
@@ -1572,9 +1575,9 @@ static PyStructSequence_Field stat_result_fields[] = {
};
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
#define ST_BLKSIZE_IDX 1
3
#define ST_BLKSIZE_IDX 1
6
#else
#define ST_BLKSIZE_IDX 1
2
#define ST_BLKSIZE_IDX 1
5
#endif
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
...
...
@@ -1726,25 +1729,50 @@ stat_float_times(PyObject* self, PyObject *args)
return
Py_None
;
}
static
PyObject
*
billion
=
NULL
;
static
void
fill_time
(
PyObject
*
v
,
int
index
,
time_t
sec
,
unsigned
long
nsec
)
{
PyObject
*
fval
,
*
ival
;
#if SIZEOF_TIME_T > SIZEOF_LONG
ival
=
PyLong_FromLongLong
((
PY_LONG_LONG
)
sec
);
#else
ival
=
PyLong_FromLong
((
long
)
sec
);
#endif
if
(
!
ival
)
return
;
PyObject
*
s
=
_PyLong_FromTime_t
(
sec
);
PyObject
*
ns_fractional
=
PyLong_FromUnsignedLong
(
nsec
);
PyObject
*
s_in_ns
=
NULL
;
PyObject
*
ns_total
=
NULL
;
PyObject
*
float_s
=
NULL
;
if
(
!
(
s
&&
ns_fractional
))
goto
exit
;
s_in_ns
=
PyNumber_Multiply
(
s
,
billion
);
if
(
!
s_in_ns
)
goto
exit
;
ns_total
=
PyNumber_Add
(
s_in_ns
,
ns_fractional
);
if
(
!
ns_total
)
goto
exit
;
if
(
_stat_float_times
)
{
fval
=
PyFloat_FromDouble
(
sec
+
1e-9
*
nsec
);
}
else
{
fval
=
ival
;
Py_INCREF
(
fval
);
float_s
=
PyFloat_FromDouble
(
sec
+
1e-9
*
nsec
);
if
(
!
float_s
)
goto
exit
;
}
else
{
float_s
=
s
;
Py_INCREF
(
float_s
);
}
PyStructSequence_SET_ITEM
(
v
,
index
,
ival
);
PyStructSequence_SET_ITEM
(
v
,
index
+
3
,
fval
);
PyStructSequence_SET_ITEM
(
v
,
index
,
s
);
PyStructSequence_SET_ITEM
(
v
,
index
+
3
,
float_s
);
PyStructSequence_SET_ITEM
(
v
,
index
+
6
,
ns_total
);
s
=
NULL
;
float_s
=
NULL
;
ns_total
=
NULL
;
exit:
Py_XDECREF
(
s
);
Py_XDECREF
(
ns_fractional
);
Py_XDECREF
(
s_in_ns
);
Py_XDECREF
(
ns_total
);
Py_XDECREF
(
float_s
);
}
/* pack a system stat C structure into the Python stat tuple
...
...
@@ -11627,6 +11655,10 @@ INITFUNC(void)
PyModule_AddObject
(
m
,
"terminal_size"
,
(
PyObject
*
)
&
TerminalSizeType
);
billion
=
PyLong_FromLong
(
1000000000
);
if
(
!
billion
)
return
NULL
;
return
m
;
}
...
...
Python/pytime.c
View file @
6fe20b3a
...
...
@@ -96,6 +96,17 @@ _PyLong_AsTime_t(PyObject *obj)
return
(
time_t
)
val
;
}
PyObject
*
_PyLong_FromTime_t
(
time_t
t
)
{
#if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
return
PyLong_FromLongLong
((
PY_LONG_LONG
)
t
);
#else
assert
(
sizeof
(
time_t
)
<=
sizeof
(
long
));
return
PyLong_FromLong
((
long
)
t
);
#endif
}
static
int
_PyTime_ObjectToDenominator
(
PyObject
*
obj
,
time_t
*
sec
,
long
*
numerator
,
double
denominator
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment