cpython: 744c96cd57da (original) (raw)
--- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2,33 +2,33 @@
does add tests for a few functions which have been determined to be more
portable than they had been thought to be.
-import os +import asynchat +import asyncore +import codecs +import contextlib +import decimal import errno +import fractions import getpass -import unittest -import warnings -import sys -import signal -import subprocess -import time -import shutil -from test import support -import contextlib +import itertools +import locale import mmap +import os +import pickle import platform import re -import uuid -import asyncore -import asynchat +import shutil +import signal import socket -import itertools import stat -import locale -import codecs -import decimal -import fractions -import pickle +import subprocess +import sys import sysconfig +import time +import unittest +import uuid +import warnings +from test import support try: import threading except ImportError: @@ -70,16 +70,6 @@ root_in_posix = False if hasattr(os, 'geteuid'): root_in_posix = (os.geteuid() == 0) -with warnings.catch_warnings():
-st = os.stat(file) -stat_supports_subsecond = (
check if float and int timestamps are different
- (st.st_atime != st[7])
- or (st.st_mtime != st[8])
- or (st.st_ctime != st[9]))
Detect whether we're on a Linux system that uses the (now outdated
and unmaintained) linuxthreads threading library. There's an issue
when combining linuxthreads with a failed execv call: see
@@ -383,179 +373,6 @@ class StatAttributeTests(unittest.TestCa unpickled = pickle.loads(p) self.assertEqual(result, unpickled)
- def test_utime_dir(self):
delta = 1000000[](#l1.78)
st = os.stat(support.TESTFN)[](#l1.79)
# round to int, because some systems may support sub-second[](#l1.80)
# time stamps in stat, but not in utime.[](#l1.81)
os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))[](#l1.82)
st2 = os.stat(support.TESTFN)[](#l1.83)
self.assertEqual(st2.st_mtime, int(st.st_mtime-delta))[](#l1.84)
- def _test_utime(self, filename, attr, utime, delta):
# Issue #13327 removed the requirement to pass None as the[](#l1.87)
# second argument. Check that the previous methods of passing[](#l1.88)
# a time tuple or None work in addition to no argument.[](#l1.89)
st0 = os.stat(filename)[](#l1.90)
# Doesn't set anything new, but sets the time tuple way[](#l1.91)
utime(filename, (attr(st0, "st_atime"), attr(st0, "st_mtime")))[](#l1.92)
# Setting the time to the time you just read, then reading again,[](#l1.93)
# should always return exactly the same times.[](#l1.94)
st1 = os.stat(filename)[](#l1.95)
self.assertEqual(attr(st0, "st_mtime"), attr(st1, "st_mtime"))[](#l1.96)
self.assertEqual(attr(st0, "st_atime"), attr(st1, "st_atime"))[](#l1.97)
# Set to the current time in the old explicit way.[](#l1.98)
os.utime(filename, None)[](#l1.99)
st2 = os.stat(support.TESTFN)[](#l1.100)
# Set to the current time in the new way[](#l1.101)
os.utime(filename)[](#l1.102)
st3 = os.stat(filename)[](#l1.103)
self.assertAlmostEqual(attr(st2, "st_mtime"), attr(st3, "st_mtime"), delta=delta)[](#l1.104)
- def test_utime(self):
def utime(file, times):[](#l1.107)
return os.utime(file, times)[](#l1.108)
self._test_utime(self.fname, getattr, utime, 10)[](#l1.109)
self._test_utime(support.TESTFN, getattr, utime, 10)[](#l1.110)
- def _test_utime_ns(self, set_times_ns, test_dir=True):
def getattr_ns(o, attr):[](#l1.114)
return getattr(o, attr + "_ns")[](#l1.115)
ten_s = 10 * 1000 * 1000 * 1000[](#l1.116)
self._test_utime(self.fname, getattr_ns, set_times_ns, ten_s)[](#l1.117)
if test_dir:[](#l1.118)
self._test_utime(support.TESTFN, getattr_ns, set_times_ns, ten_s)[](#l1.119)
- def test_utime_ns(self):
def utime_ns(file, times):[](#l1.122)
return os.utime(file, ns=times)[](#l1.123)
self._test_utime_ns(utime_ns)[](#l1.124)
- requires_utime_dir_fd = unittest.skipUnless(
os.utime in os.supports_dir_fd,[](#l1.127)
"dir_fd support for utime required for this test.")[](#l1.128)
- requires_utime_fd = unittest.skipUnless(
os.utime in os.supports_fd,[](#l1.130)
"fd support for utime required for this test.")[](#l1.131)
- requires_utime_nofollow_symlinks = unittest.skipUnless(
os.utime in os.supports_follow_symlinks,[](#l1.133)
"follow_symlinks support for utime required for this test.")[](#l1.134)
- @requires_utime_nofollow_symlinks
- def test_lutimes_ns(self):
def lutimes_ns(file, times):[](#l1.138)
return os.utime(file, ns=times, follow_symlinks=False)[](#l1.139)
self._test_utime_ns(lutimes_ns)[](#l1.140)
- @requires_utime_fd
- def test_futimes_ns(self):
def futimes_ns(file, times):[](#l1.144)
with open(file, "wb") as f:[](#l1.145)
os.utime(f.fileno(), ns=times)[](#l1.146)
self._test_utime_ns(futimes_ns, test_dir=False)[](#l1.147)
- def _utime_invalid_arguments(self, name, arg):
with self.assertRaises(ValueError):[](#l1.150)
getattr(os, name)(arg, (5, 5), ns=(5, 5))[](#l1.151)
- def test_utime_invalid_arguments(self):
self._utime_invalid_arguments('utime', self.fname)[](#l1.154)
- @unittest.skipUnless(stat_supports_subsecond,
"os.stat() doesn't has a subsecond resolution")[](#l1.158)
- def _test_utime_subsecond(self, set_time_func):
asec, amsec = 1, 901[](#l1.160)
atime = asec + amsec * 1e-3[](#l1.161)
msec, mmsec = 2, 901[](#l1.162)
mtime = msec + mmsec * 1e-3[](#l1.163)
filename = self.fname[](#l1.164)
os.utime(filename, (0, 0))[](#l1.165)
set_time_func(filename, atime, mtime)[](#l1.166)
with warnings.catch_warnings():[](#l1.167)
warnings.simplefilter("ignore", DeprecationWarning)[](#l1.168)
os.stat_float_times(True)[](#l1.169)
st = os.stat(filename)[](#l1.170)
self.assertAlmostEqual(st.st_atime, atime, places=3)[](#l1.171)
self.assertAlmostEqual(st.st_mtime, mtime, places=3)[](#l1.172)
- def test_utime_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.175)
os.utime(filename, (atime, mtime))[](#l1.176)
self._test_utime_subsecond(set_time)[](#l1.177)
- @requires_utime_fd
- def test_futimes_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.181)
with open(filename, "wb") as f:[](#l1.182)
os.utime(f.fileno(), times=(atime, mtime))[](#l1.183)
self._test_utime_subsecond(set_time)[](#l1.184)
- @requires_utime_fd
- def test_futimens_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.188)
with open(filename, "wb") as f:[](#l1.189)
os.utime(f.fileno(), times=(atime, mtime))[](#l1.190)
self._test_utime_subsecond(set_time)[](#l1.191)
- @requires_utime_dir_fd
- def test_futimesat_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.195)
dirname = os.path.dirname(filename)[](#l1.196)
dirfd = os.open(dirname, os.O_RDONLY)[](#l1.197)
try:[](#l1.198)
os.utime(os.path.basename(filename), dir_fd=dirfd,[](#l1.199)
times=(atime, mtime))[](#l1.200)
finally:[](#l1.201)
os.close(dirfd)[](#l1.202)
self._test_utime_subsecond(set_time)[](#l1.203)
- @requires_utime_nofollow_symlinks
- def test_lutimes_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.207)
os.utime(filename, (atime, mtime), follow_symlinks=False)[](#l1.208)
self._test_utime_subsecond(set_time)[](#l1.209)
- @requires_utime_dir_fd
- def test_utimensat_subsecond(self):
def set_time(filename, atime, mtime):[](#l1.213)
dirname = os.path.dirname(filename)[](#l1.214)
dirfd = os.open(dirname, os.O_RDONLY)[](#l1.215)
try:[](#l1.216)
os.utime(os.path.basename(filename), dir_fd=dirfd,[](#l1.217)
times=(atime, mtime))[](#l1.218)
finally:[](#l1.219)
os.close(dirfd)[](#l1.220)
self._test_utime_subsecond(set_time)[](#l1.221)
Restrict tests to Win32, since there is no guarantee other
systems support centiseconds
- def get_file_system(path):
if sys.platform == 'win32':[](#l1.226)
root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'[](#l1.227)
import ctypes[](#l1.228)
kernel32 = ctypes.windll.kernel32[](#l1.229)
buf = ctypes.create_unicode_buffer("", 100)[](#l1.230)
if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)):[](#l1.231)
return buf.value[](#l1.232)
- @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
- @unittest.skipUnless(get_file_system(support.TESTFN) == "NTFS",
"requires NTFS")[](#l1.236)
- def test_1565150(self):
t1 = 1159195039.25[](#l1.238)
os.utime(self.fname, (t1, t1))[](#l1.239)
self.assertEqual(os.stat(self.fname).st_mtime, t1)[](#l1.240)
- @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
- @unittest.skipUnless(get_file_system(support.TESTFN) == "NTFS",
"requires NTFS")[](#l1.244)
- def test_large_time(self):
t1 = 5000000000 # some day in 2128[](#l1.246)
os.utime(self.fname, (t1, t1))[](#l1.247)
self.assertEqual(os.stat(self.fname).st_mtime, t1)[](#l1.248)
- @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") def test_1686475(self): # Verify that an open file can be stat'ed @@ -602,6 +419,196 @@ class StatAttributeTests(unittest.TestCa result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY, stat.FILE_ATTRIBUTE_DIRECTORY) + +class UtimeTests(unittest.TestCase):
- def setUp(self):
self.dirname = support.TESTFN[](#l1.260)
self.fname = os.path.join(self.dirname, "f1")[](#l1.261)
self.addCleanup(support.rmtree, self.dirname)[](#l1.263)
os.mkdir(self.dirname)[](#l1.264)
with open(self.fname, 'wb') as fp:[](#l1.265)
fp.write(b"ABC")[](#l1.266)
# ensure that st_atime and st_mtime are float[](#l1.268)
with warnings.catch_warnings():[](#l1.269)
warnings.simplefilter("ignore", DeprecationWarning)[](#l1.270)
old_state = os.stat_float_times(-1)[](#l1.272)
self.addCleanup(os.stat_float_times, old_state)[](#l1.273)
os.stat_float_times(True)[](#l1.275)
- def support_subsecond(self, filename):
# Heuristic to check if the filesystem supports timestamp with[](#l1.278)
# subsecond resolution: check if float and int timestamps are different[](#l1.279)
st = os.stat(filename)[](#l1.280)
return ((st.st_atime != st[7])[](#l1.281)
or (st.st_mtime != st[8])[](#l1.282)
or (st.st_ctime != st[9]))[](#l1.283)
- def _test_utime(self, set_time, filename=None):
if not filename:[](#l1.286)
filename = self.fname[](#l1.287)
support_subsecond = self.support_subsecond(filename)[](#l1.289)
if support_subsecond:[](#l1.290)
# Timestamp with a resolution of 1 microsecond (10^-6).[](#l1.291)
#[](#l1.292)
# The resolution of the C internal function used by os.utime()[](#l1.293)
# depends on the platform: 1 sec, 1 us, 1 ns. Writing a portable[](#l1.294)
# test with a resolution of 1 ns requires more work:[](#l1.295)
# see the issue #15745.[](#l1.296)
atime_ns = 1002003000 # 1.002003 seconds[](#l1.297)
mtime_ns = 4005006000 # 4.005006 seconds[](#l1.298)
else:[](#l1.299)
# use a resolution of 1 second[](#l1.300)
atime_ns = 5 * 10**9[](#l1.301)
mtime_ns = 8 * 10**9[](#l1.302)
set_time(filename, (atime_ns, mtime_ns))[](#l1.304)
st = os.stat(filename)[](#l1.305)
if support_subsecond:[](#l1.307)
self.assertAlmostEqual(st.st_atime, atime_ns * 1e-9, delta=1e-6)[](#l1.308)
self.assertAlmostEqual(st.st_mtime, mtime_ns * 1e-9, delta=1e-6)[](#l1.309)
else:[](#l1.310)
self.assertEqual(st.st_atime, atime_ns * 1e-9)[](#l1.311)
self.assertEqual(st.st_mtime, mtime_ns * 1e-9)[](#l1.312)
self.assertEqual(st.st_atime_ns, atime_ns)[](#l1.313)
self.assertEqual(st.st_mtime_ns, mtime_ns)[](#l1.314)
- def test_utime(self):
def set_time(filename, ns):[](#l1.317)
# test the ns keyword parameter[](#l1.318)
os.utime(filename, ns=ns)[](#l1.319)
self._test_utime(set_time)[](#l1.320)
- @staticmethod
- def ns_to_sec(ns):
# Convert a number of nanosecond (int) to a number of seconds (float).[](#l1.324)
# Round towards infinity by adding 0.5 nanosecond to avoid rounding[](#l1.325)
# issue, os.utime() rounds towards minus infinity.[](#l1.326)
return (ns * 1e-9) + 0.5e-9[](#l1.327)
- def test_utime_by_indexed(self):
# pass times as floating point seconds as the second indexed parameter[](#l1.330)
def set_time(filename, ns):[](#l1.331)
atime_ns, mtime_ns = ns[](#l1.332)
atime = self.ns_to_sec(atime_ns)[](#l1.333)
mtime = self.ns_to_sec(mtime_ns)[](#l1.334)
# test utimensat(timespec), utimes(timeval), utime(utimbuf)[](#l1.335)
# or utime(time_t)[](#l1.336)
os.utime(filename, (atime, mtime))[](#l1.337)
self._test_utime(set_time)[](#l1.338)
- def test_utime_by_times(self):
def set_time(filename, ns):[](#l1.341)
atime_ns, mtime_ns = ns[](#l1.342)
atime = self.ns_to_sec(atime_ns)[](#l1.343)
mtime = self.ns_to_sec(mtime_ns)[](#l1.344)
# test the times keyword parameter[](#l1.345)
os.utime(filename, times=(atime, mtime))[](#l1.346)
self._test_utime(set_time)[](#l1.347)
- @unittest.skipUnless(os.utime in os.supports_follow_symlinks,
"follow_symlinks support for utime required "[](#l1.350)
"for this test.")[](#l1.351)
- def test_utime_nofollow_symlinks(self):
def set_time(filename, ns):[](#l1.353)
# use follow_symlinks=False to test utimensat(timespec)[](#l1.354)
# or lutimes(timeval)[](#l1.355)
os.utime(filename, ns=ns, follow_symlinks=False)[](#l1.356)
self._test_utime(set_time)[](#l1.357)
- @unittest.skipUnless(os.utime in os.supports_fd,
"fd support for utime required for this test.")[](#l1.360)
- def test_utime_fd(self):
def set_time(filename, ns):[](#l1.362)
with open(filename, 'wb') as fp:[](#l1.363)
# use a file descriptor to test futimens(timespec)[](#l1.364)
# or futimes(timeval)[](#l1.365)
os.utime(fp.fileno(), ns=ns)[](#l1.366)
self._test_utime(set_time)[](#l1.367)
- @unittest.skipUnless(os.utime in os.supports_dir_fd,
"dir_fd support for utime required for this test.")[](#l1.370)
- def test_utime_dir_fd(self):
def set_time(filename, ns):[](#l1.372)
dirname, name = os.path.split(filename)[](#l1.373)
dirfd = os.open(dirname, os.O_RDONLY)[](#l1.374)
try:[](#l1.375)
# pass dir_fd to test utimensat(timespec) or futimesat(timeval)[](#l1.376)
os.utime(name, dir_fd=dirfd, ns=ns)[](#l1.377)
finally:[](#l1.378)
os.close(dirfd)[](#l1.379)
self._test_utime(set_time)[](#l1.380)
- def test_utime_directory(self):
def set_time(filename, ns):[](#l1.383)
# test calling os.utime() on a directory[](#l1.384)
os.utime(filename, ns=ns)[](#l1.385)
self._test_utime(set_time, filename=self.dirname)[](#l1.386)
- def _test_utime_current(self, set_time):
# Get the system clock[](#l1.389)
current = time.time()[](#l1.390)
# Call os.utime() to set the timestamp to the current system clock[](#l1.392)
set_time(self.fname)[](#l1.393)
if not self.support_subsecond(self.fname):[](#l1.395)
delta = 1.0[](#l1.396)
else:[](#l1.397)
# On Windows, the usual resolution of time.time() is 15.6 ms[](#l1.398)
delta = 0.020[](#l1.399)
st = os.stat(self.fname)[](#l1.400)
msg = ("st_time=%r, current=%r, dt=%r"[](#l1.401)
% (st.st_mtime, current, st.st_mtime - current))[](#l1.402)
self.assertAlmostEqual(st.st_mtime, current,[](#l1.403)
delta=delta, msg=msg)[](#l1.404)
- def test_utime_current(self):
def set_time(filename):[](#l1.407)
# Set to the current time in the new way[](#l1.408)
os.utime(self.fname)[](#l1.409)
self._test_utime_current(set_time)[](#l1.410)
- def test_utime_current_old(self):
def set_time(filename):[](#l1.413)
# Set to the current time in the old explicit way.[](#l1.414)
os.utime(self.fname, None)[](#l1.415)
self._test_utime_current(set_time)[](#l1.416)
- def get_file_system(self, path):
if sys.platform == 'win32':[](#l1.419)
root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'[](#l1.420)
import ctypes[](#l1.421)
kernel32 = ctypes.windll.kernel32[](#l1.422)
buf = ctypes.create_unicode_buffer("", 100)[](#l1.423)
ok = kernel32.GetVolumeInformationW(root, None, 0,[](#l1.424)
None, None, None,[](#l1.425)
buf, len(buf))[](#l1.426)
if ok:[](#l1.427)
return buf.value[](#l1.428)
# return None if the filesystem is unknown[](#l1.429)
- def test_large_time(self):
# Many filesystems are limited to the year 2038. At least, the test[](#l1.432)
# pass with NTFS filesystem.[](#l1.433)
if self.get_file_system(self.dirname) != "NTFS":[](#l1.434)
self.skipTest("requires NTFS")[](#l1.435)
large = 5000000000 # some day in 2128[](#l1.437)
os.utime(self.fname, (large, large))[](#l1.438)
self.assertEqual(os.stat(self.fname).st_mtime, large)[](#l1.439)
- def test_utime_invalid_arguments(self):
# seconds and nanoseconds parameters are mutually exclusive[](#l1.442)
with self.assertRaises(ValueError):[](#l1.443)
os.utime(self.fname, (5, 5), ns=(5, 5))[](#l1.444)
+ + from test import mapping_tests class EnvironTests(mapping_tests.BasicTestMappingProtocol):