|
20 | 20 | from test import script_helper |
21 | 21 |
|
22 | 22 |
|
23 | | -def remove_files(name): |
24 | | - for f in (name + ".py", |
25 | | - name + ".pyc", |
26 | | - name + ".pyo", |
27 | | - name + ".pyw", |
| 23 | +def _iter_files(name): |
| 24 | + for f in (name + os.extsep + "py", |
| 25 | + name + os.extsep + "pyc", |
| 26 | + name + os.extsep + "pyo", |
| 27 | + name + os.extsep + "pyw", |
28 | 28 | name + "$py.class"): |
| 29 | + yield f |
| 30 | + |
| 31 | +def chmod_files(name): |
| 32 | + for f in _iter_files(name): |
| 33 | + try: |
| 34 | + os.chmod(f, 0o600) |
| 35 | + except OSError as exc: |
| 36 | + if exc.errno != errno.ENOENT: |
| 37 | + raise |
| 38 | + |
| 39 | +def remove_files(name): |
| 40 | + for f in _iter_files(name): |
29 | 41 | unlink(f) |
30 | 42 | rmtree('__pycache__') |
31 | 43 |
|
@@ -122,6 +134,40 @@ def test_execute_bit_not_copied(self): |
122 | 134 | remove_files(TESTFN) |
123 | 135 | unload(TESTFN) |
124 | 136 |
|
| 137 | + def test_rewrite_pyc_with_read_only_source(self): |
| 138 | + # Issue 6074: a long time ago on posix, and more recently on Windows, |
| 139 | + # a read only source file resulted in a read only pyc file, which |
| 140 | + # led to problems with updating it later |
| 141 | + sys.path.insert(0, os.curdir) |
| 142 | + fname = TESTFN + os.extsep + "py" |
| 143 | + try: |
| 144 | + # Write a Python file, make it read-only and import it |
| 145 | + with open(fname, 'w') as f: |
| 146 | + f.write("x = 'original'\n") |
| 147 | + # Tweak the mtime of the source to ensure pyc gets updated later |
| 148 | + s = os.stat(fname) |
| 149 | + os.utime(fname, (s.st_atime, s.st_mtime-100000000)) |
| 150 | + os.chmod(fname, 0o400) |
| 151 | + m1 = __import__(TESTFN) |
| 152 | + self.assertEqual(m1.x, 'original') |
| 153 | + # Change the file and then reimport it |
| 154 | + os.chmod(fname, 0o600) |
| 155 | + with open(fname, 'w') as f: |
| 156 | + f.write("x = 'rewritten'\n") |
| 157 | + unload(TESTFN) |
| 158 | + m2 = __import__(TESTFN) |
| 159 | + self.assertEqual(m2.x, 'rewritten') |
| 160 | + # Now delete the source file and check the pyc was rewritten |
| 161 | + unlink(TESTFN) |
| 162 | + unload(TESTFN) |
| 163 | + m3 = __import__(TESTFN) |
| 164 | + self.assertEqual(m3.x, 'rewritten') |
| 165 | + finally: |
| 166 | + chmod_files(TESTFN) |
| 167 | + remove_files(TESTFN) |
| 168 | + unload(TESTFN) |
| 169 | + del sys.path[0] |
| 170 | + |
125 | 171 | def test_imp_module(self): |
126 | 172 | # Verify that the imp module can correctly load and find .py files |
127 | 173 | # XXX (ncoghlan): It would be nice to use support.CleanImport |
|
0 commit comments