Skip to content

Change os.utime &c functions to use nanosecond precision where possible #57113

Closed

Description

@larryhastings
BPO 12904
Nosy @loewis, @larryhastings
Files
  • larry.utimensat.patch.r1
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/larryhastings'
    closed_at = <Date 2012-02-26.21:50:32.693>
    created_at = <Date 2011-09-05.21:08:02.180>
    labels = ['extension-modules', 'type-feature']
    title = 'Change os.utime &c functions to use nanosecond precision where possible'
    updated_at = <Date 2012-02-26.21:50:32.691>
    user = 'https://github.com/larryhastings'

    bugs.python.org fields:

    activity = <Date 2012-02-26.21:50:32.691>
    actor = 'larry'
    assignee = 'larry'
    closed = True
    closed_date = <Date 2012-02-26.21:50:32.693>
    closer = 'larry'
    components = ['Extension Modules']
    creation = <Date 2011-09-05.21:08:02.180>
    creator = 'larry'
    dependencies = []
    files = ['23104']
    hgrepos = []
    issue_num = 12904
    keywords = []
    message_count = 7.0
    messages = ['143563', '143566', '143568', '143571', '143587', '143750', '154399']
    nosy_count = 4.0
    nosy_names = ['loewis', 'larry', 'Arfrever', 'python-dev']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue12904'
    versions = ['Python 3.3']

    Activity

    1. larryhastings commented on Sep 5, 2011

      @larryhastings
      ContributorAuthor

      Since Linux 2.5 stat() has supported reading nanosecond resolution (1b/sec) for atime and mtime. However, the utime() family of functions could only write atime and mtime with microsecond resolution (1m/sec) until relatively recently.

      On POSIX platforms Python reads atime and mtime at nanosecond resolution but only writes them at microsecond resolution. This impedance mismatch can cause undesirable behavior. Consider the following code:

          import os
          import shutil
          import sys
      
          def mtime(path):
            return os.stat(path).st_mtime
      
          src = sys.argv[0]
          dest = src + ".new"
          shutil.copy2(src, dest)
          assert mtime(src) == mtime(dest)

      When run under Python on any modern Linux system, the assert fails. (I think any Python since 2.5 will do; I tested with 2.7.1 and a fresh 3.3 trunk.)

      The accompanying patch modifies Modules/posixmodule.c so all functions that write atime and mtime use nanosecond resolution when possible. With this patch applied, all the regression tests pass (except the ones for extension modules I didn't compile), and the above code runs to completion.

      Happy to hoist the patch up on Rietveld if there's interest.

      p.s. I have the commit bit set, so I'd like to be the one to check this in if we get that far.

    2. self-assigned this
      on Sep 5, 2011
    3. larryhastings commented on Sep 5, 2011

      @larryhastings
      ContributorAuthor

      A small aside:

      An IEEE 754 double is insufficient to store a modern timestamp with nanosecond accuracy. We're currently at just over 1.3 billion seconds since the epoch. This eats 28 bits of the mantissa. (The value is actually 31 bits to the left of the decimal point, but you get the leading 1 and the subsequent two 0s for free.) Precisely storing a billion values to the right of the decimal point would require another 30 bits. The mantissa of a double is sadly only 52 bits. So we're shy by 6 bits, give or take.

      So this patch doesn't make Python 100% accurate with respect to atime/mtime. What it *does* do is makes Python's loss of accuracy consistent. I claim that's a definite improvement.

    4. Arfrever commented on Sep 5, 2011

      Arfrevermannequin
      Mannequin

      It's a duplicate of issue bpo-11457.
      (Python >=3.3 has os.utimensat() and os.futimens().)

    5. larryhastings commented on Sep 5, 2011

      @larryhastings
      ContributorAuthor

      It's a duplicate of issue bpo-11457.

      No. bpo-11457 is a how-many-angels-on-the-head-of-a-pin discussion proposing new representations of ctime/mtime/atime to preserve nanosecond accuracy. This patch changes the behavior of os.utime, os.futimes, os.lutimes, and os.futimesat so they conserve all of the existing representation's accuracy, making them consistent with os.stat.

      (Python >=3.3 has os.utimensat() and os.futimens().)

      How is that relevant?

      I mean, sure, I leveraged some of the work from that support in my patch--it's heavily reliant on the preprocessor macros HAVE_UTIMENSAT and HAVE_FUTIMENS now generated by configure. (Thanks, Ross!) But the presence of those functions does not mitigate the loss of accuracy inside os.utime &c.

    6. loewis commented on Sep 6, 2011

      loewismannequin
      Mannequin

      The patch looks fine to me.

    7. python-dev commented on Sep 9, 2011

      python-devmannequin
      Mannequin

      New changeset 1de6619733d9 by Larry Hastings in branch 'default':
      Issue bpo-12904: os.utime, os.futimes, os.lutimes, and os.futimesat now write
      http://hg.python.org/cpython/rev/1de6619733d9

    8. larryhastings commented on Feb 26, 2012

      @larryhastings
      ContributorAuthor

      This was committed last September; I should have marked it closed then.

    9. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    extension-modulesC modules in the Modules dirtype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions