Commit 34937ce2 authored by Nick Coghlan's avatar Nick Coghlan

Issue #6074: Forward port Windows read-only source file fix from 2.7

parent 2d51f687
......@@ -20,12 +20,24 @@ from test.support import (
from test import script_helper
def remove_files(name):
for f in (name + ".py",
name + ".pyc",
name + ".pyo",
name + ".pyw",
def _iter_files(name):
for f in (name + os.extsep + "py",
name + os.extsep + "pyc",
name + os.extsep + "pyo",
name + os.extsep + "pyw",
name + "$py.class"):
yield f
def chmod_files(name):
for f in _iter_files(name):
try:
os.chmod(f, 0o600)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
def remove_files(name):
for f in _iter_files(name):
unlink(f)
rmtree('__pycache__')
......@@ -122,6 +134,40 @@ class ImportTests(unittest.TestCase):
remove_files(TESTFN)
unload(TESTFN)
def test_rewrite_pyc_with_read_only_source(self):
# Issue 6074: a long time ago on posix, and more recently on Windows,
# a read only source file resulted in a read only pyc file, which
# led to problems with updating it later
sys.path.insert(0, os.curdir)
fname = TESTFN + os.extsep + "py"
try:
# Write a Python file, make it read-only and import it
with open(fname, 'w') as f:
f.write("x = 'original'\n")
# Tweak the mtime of the source to ensure pyc gets updated later
s = os.stat(fname)
os.utime(fname, (s.st_atime, s.st_mtime-100000000))
os.chmod(fname, 0o400)
m1 = __import__(TESTFN)
self.assertEqual(m1.x, 'original')
# Change the file and then reimport it
os.chmod(fname, 0o600)
with open(fname, 'w') as f:
f.write("x = 'rewritten'\n")
unload(TESTFN)
m2 = __import__(TESTFN)
self.assertEqual(m2.x, 'rewritten')
# Now delete the source file and check the pyc was rewritten
unlink(TESTFN)
unload(TESTFN)
m3 = __import__(TESTFN)
self.assertEqual(m3.x, 'rewritten')
finally:
chmod_files(TESTFN)
remove_files(TESTFN)
unload(TESTFN)
del sys.path[0]
def test_imp_module(self):
# Verify that the imp module can correctly load and find .py files
# XXX (ncoghlan): It would be nice to use support.CleanImport
......
......@@ -10,6 +10,9 @@ What's New in Python 3.2.4
Core and Builtins
-----------------
- Issue #6074: Ensure cached bytecode files can always be updated by the
user that created them, even when the source file is read-only.
- Issue #14783: Improve int() docstring and switch docstrings for str(),
range(), and slice() to use multi-line signatures.
......
......@@ -1174,6 +1174,12 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
/* Issue #6074: We ensure user write access, so we can delete it later
* when the source file changes. (On POSIX, this only requires write
* access to the directory, on Windows, we need write access to the file
* as well)
*/
mode |= _S_IWRITE;
#else
mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
mode_t dirmode = (srcstat->st_mode |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment