mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Issue #6074: Restore the long-broken support for running with read-only source files on Windows
This commit is contained in:
parent
02f69f6965
commit
b48c028ca7
3 changed files with 56 additions and 1 deletions
|
@ -15,12 +15,24 @@ from test.test_support import (unlink, TESTFN, unload, run_unittest, rmtree,
|
||||||
from test import symlink_support
|
from test import symlink_support
|
||||||
from test import script_helper
|
from test import script_helper
|
||||||
|
|
||||||
def remove_files(name):
|
def _iter_files(name):
|
||||||
for f in (name + os.extsep + "py",
|
for f in (name + os.extsep + "py",
|
||||||
name + os.extsep + "pyc",
|
name + os.extsep + "pyc",
|
||||||
name + os.extsep + "pyo",
|
name + os.extsep + "pyo",
|
||||||
name + os.extsep + "pyw",
|
name + os.extsep + "pyw",
|
||||||
name + "$py.class"):
|
name + "$py.class"):
|
||||||
|
yield f
|
||||||
|
|
||||||
|
def chmod_files(name):
|
||||||
|
for f in _iter_files(name):
|
||||||
|
try:
|
||||||
|
os.chmod(f, 0600)
|
||||||
|
except OSError as exc:
|
||||||
|
if exc.errno != errno.ENOENT:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def remove_files(name):
|
||||||
|
for f in _iter_files(name):
|
||||||
unlink(f)
|
unlink(f)
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,6 +132,40 @@ class ImportTests(unittest.TestCase):
|
||||||
unload(TESTFN)
|
unload(TESTFN)
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
|
|
||||||
|
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, 0400)
|
||||||
|
m1 = __import__(TESTFN)
|
||||||
|
self.assertEqual(m1.x, 'original')
|
||||||
|
# Change the file and then reimport it
|
||||||
|
os.chmod(fname, 0600)
|
||||||
|
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):
|
def test_imp_module(self):
|
||||||
# Verify that the imp module can correctly load and find .py files
|
# Verify that the imp module can correctly load and find .py files
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ What's New in Python 2.7.4
|
||||||
Core and Builtins
|
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() and long() docstrings and switch docstrings for
|
- Issue #14783: Improve int() and long() docstrings and switch docstrings for
|
||||||
unicode(), slice(), range(), and xrange() to use multi-line signatures.
|
unicode(), slice(), range(), and xrange() to use multi-line signatures.
|
||||||
|
|
||||||
|
|
|
@ -910,6 +910,12 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
|
||||||
time_t mtime = srcstat->st_mtime;
|
time_t mtime = srcstat->st_mtime;
|
||||||
#ifdef MS_WINDOWS /* since Windows uses different permissions */
|
#ifdef MS_WINDOWS /* since Windows uses different permissions */
|
||||||
mode_t mode = srcstat->st_mode & ~S_IEXEC;
|
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
|
#else
|
||||||
mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
|
mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue