classification
Title: os.utimensat() and os.futimes() should accept (sec, nsec), drop os.futimens()
Type: Stage:
Components: Library (Lib) Versions: Python 3.3
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, larry, ncoghlan, python-dev, rosslagerwall, vstinner
Priority: normal Keywords: patch

Created on 2012-02-08 01:19 by vstinner, last changed 2012-03-13 13:05 by vstinner. This issue is now closed.

Files
File name Uploaded Description Edit
pytime.patch vstinner, 2012-02-21 00:24 review
utime.patch vstinner, 2012-03-04 00:01
Messages (19)
msg152825 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-02-08 01:19
Python 3.3 has 4 new functions to set the access and modification time of a file (only os.utime() was already present in Python 3.2). New functions taking timestamp with a nanonsecond resolution use a tuple of int because the float type doesn't support nanosecond resolution. Thanks to the PEP 410, we can simplify the API to use a simple number (int, float or Decimal) instead of a tuple of 2 integers.

Current API:

- futimes(fd[, (atime, mtime)]): 1 argument for timestamps
- lutimes(path[, (atime, mtime)]): 1 argument for timestamps
- utime(path[, (atime, mtime)]): 1 argument for timestamps

- futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)]): 2 arguments for timestamps
- utimensat(dirfd, path[, atime=(atime_sec, atime_nsec), mtime=(mtime_sec, mtime_nsec), flags=0]): 2 arguments for timestamps

I propose to:

- support Decimal type in all functions: avoid conversion to float to not lose precision
- remove os.futimens(): os.futimes() does already use futimens() if the function is present (and Decimal can be used to get nanosecond resolution)
- change os.utimensat() API to: os.utimensat(dirfd, path[, (atime, mtime), flags=0])
msg152828 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-02-08 02:00
New changeset d297f9b10c64 by Victor Stinner in branch 'default':
Issue #13964: Write tests for new os.*utime*() functions
http://hg.python.org/cpython/rev/d297f9b10c64
msg152829 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-02-08 02:02
> Current API:

Oh, I forgot:
- futimesat(dirfd, path[, (atime, mtime)])

This API looks fine.
msg152830 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-02-08 02:06
New changeset c6e9c4d18b36 by Victor Stinner in branch 'default':
Issue #13964: Test also os.futimesat()
http://hg.python.org/cpython/rev/c6e9c4d18b36
msg152831 - (view) Author: Arfrever Frehtes Taifersar Arahesis (Arfrever) * (Python triager) Date: 2012-02-08 02:16
I suggest to support the following functions:
futimes(fd, (atime, mtime), flags=0)
utimes(path, (atime, mtime), flags=0)
utimesat(dirfd, path, (atime, mtime), flags=0)

And deprecate other functions already present in 3.2.
flags argument of utimes*() would specify e.g. if symlinks should be dereferenced, so lutime*() wouldn't be needed.
msg152832 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-02-08 02:35
New changeset 478fb4869c99 by Victor Stinner in branch 'default':
Issue #13964: Split os.*utime*() subsecond tests into multiple tests to help
http://hg.python.org/cpython/rev/478fb4869c99
msg152833 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-02-08 03:09
New changeset 58bd6a58365d by Victor Stinner in branch 'default':
Issue #13964: Skip os.*utime*() tests if os.stat() doesn't support timestamp
http://hg.python.org/cpython/rev/58bd6a58365d
msg152834 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-02-08 03:14
> New changeset 478fb4869c99 by Victor Stinner in branch 'default':
> Issue #13964: Split os.*utime*() subsecond tests into multiple tests...

Oops, I also commited my change on extract_time() by mistake. But it is not completly a mistake: it was the goal of my patch serie :-)

This commit changes two things on extract_time().

 - always use nanoseconds: if we need microseconds, divide by 1000
 - use (long)(fmod()*1e9) to get nanoseconds instead of the previous code, I'm not sure that this change is correct
msg152919 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-02-09 00:28
signal.sigtimedwait() API should also be changed from:
  sigtimedwait(sigset, (timeout_sec, timeout_nsec))
to:
  sigtimedwait(sigset, timeout)

where timeout can be an int, float or decimal.Decimal. The function was introduced in Python 3.3, so its API can be changed.
msg152920 - (view) Author: Arfrever Frehtes Taifersar Arahesis (Arfrever) * (Python triager) Date: 2012-02-09 00:40
Updated version of my suggestion:
os.futime(fd, (atime, mtime))
os.utime(path, (atime, mtime), flags=0)
os.utimeat(dirfd, path, (atime, mtime), flags=0)

atime and mtime could be int, float, decimal.Decimal or None.
All other os.*utime*() functions were introduced in 3.3, so they would be removed.
flags argument of os.utime() and os.utimeat() could be 0 or os.SYMLINK_NOFOLLOW.
msg153825 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-02-21 00:24
Here is a first step: add _PyTime_ObjectToTimespec() to pytime.h and use it for signal.sigtimedwait().

signal.sigtimedwait(sigwait, (timeout_sec, timeout_nsec)) becomes signal.sigtimedwait(sigwait, timeout).

I chose pytime.h instead of timefuncs.h because I plan to use _PyTime_ObjectToTimespec() in the posix module. I don't want to have a copy of this function in each module: timefuncs.h requires to compile the module with _time.c.
msg154805 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-03-02 21:54
New changeset 67d9595a833c by Victor Stinner in branch 'default':
Issue #13964: signal.sigtimedwait() timeout is now a float instead of a tuple
http://hg.python.org/cpython/rev/67d9595a833c
msg154812 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-03-03 00:11
I created the issue #14180 to prepare a refactoring before changing os.*utime*() functions.
msg154813 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2012-03-03 00:12
Um, doesn't the rejection of PEP 410 mean this should be discontinued?
msg154814 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-03-03 00:17
> Um, doesn't the rejection of PEP 410 mean this should be discontinued?

There is an issue in shutil.copystat() on copying the timestamp: in this specific use case, we need nanosecond resolution.

Guido proposes (in a private mail thread) to add st_atime_ns, st_mtime_ns, st_ctime_ns fields to os.stat() and make os.*utime*() functions accept a (sec, nsec) tuple. It would still be possible to pass a number or seconds as an int or float.

I plan to implement this request.
msg154860 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-03-04 00:01
utime.patch: ugly draft to add support of (sec, nsec) tuple to os.*utime*() functions.
msg154862 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2012-03-04 00:09
After Guido rejected 410 and said "let's just do nanoseconds, take it to the bug tracker" I created issue #14127.  Your having changed this issue to be the same thing means that at least one of 'em is redundant.  Could you engage on that issue, or close it, or something?
msg155136 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2012-03-08 00:08
I just asked Guido in person, and he says he never intended to suggest accepting a (sec, nsec) tuple.  os.*utime* may accept atime and mtime as either float seconds-since-the-epoch, or int nanoseconds-since-the-epoch when passed in using the ns= named parameter.
msg155606 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2012-03-13 13:05
This issue is a duplicate of #14127.
History
Date User Action Args
2012-03-13 13:05:15vstinnersetstatus: open -> closed
resolution: duplicate
messages: + msg155606
2012-03-08 00:08:05larrysetmessages: + msg155136
2012-03-04 00:09:36larrysetmessages: + msg154862
2012-03-04 00:01:02vstinnersetfiles: + utime.patch

messages: + msg154860
2012-03-03 00:37:06vstinnersettitle: os.utimensat() and os.futimes() should accept Decimal, drop os.futimens() -> os.utimensat() and os.futimes() should accept (sec, nsec), drop os.futimens()
2012-03-03 00:17:24vstinnersetmessages: + msg154814
2012-03-03 00:12:35larrysetnosy: + larry
messages: + msg154813
2012-03-03 00:11:15vstinnersetmessages: + msg154812
2012-03-02 21:54:44python-devsetmessages: + msg154805
2012-02-21 00:24:10vstinnersetfiles: + pytime.patch
keywords: + patch
messages: + msg153825
2012-02-09 00:40:23Arfreversetmessages: + msg152920
2012-02-09 00:28:21vstinnersetmessages: + msg152919
2012-02-08 04:14:17rosslagerwallsetnosy: + rosslagerwall
2012-02-08 03:14:50vstinnersetmessages: + msg152834
2012-02-08 03:09:14python-devsetmessages: + msg152833
2012-02-08 02:35:53python-devsetmessages: + msg152832
2012-02-08 02:16:06Arfreversetmessages: + msg152831
2012-02-08 02:06:56python-devsetmessages: + msg152830
2012-02-08 02:02:32vstinnersetmessages: + msg152829
2012-02-08 02:00:43python-devsetnosy: + python-dev
messages: + msg152828
2012-02-08 01:32:46Arfreversetnosy: + Arfrever
2012-02-08 01:19:53vstinnercreate