diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py index db9c8ef6fc0..8ed6b8f7951 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -1,12 +1,14 @@ import unittest import os +import stat import random import shutil import sys import py_compile import warnings import marshal -from test.test_support import unlink, TESTFN, unload, run_unittest, check_warnings +from test.test_support import (unlink, TESTFN, unload, run_unittest, + check_warnings, TestFailed) def remove_files(name): @@ -91,6 +93,32 @@ class ImportTest(unittest.TestCase): finally: del sys.path[0] + if os.name == 'posix': + def test_execute_bit_not_copied(self): + # Issue 6070: under posix .pyc files got their execute bit set if + # the .py file had the execute bit set, but they aren't executable. + oldmask = os.umask(022) + sys.path.insert(0, os.curdir) + try: + fname = TESTFN + os.extsep + "py" + f = open(fname, 'w').close() + os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | + stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)) + __import__(TESTFN) + fn = fname + 'c' + if not os.path.exists(fn): + fn = fname + 'o' + if not os.path.exists(fn): raise TestFailed("__import__ did " + "not result in creation of either a .pyc or .pyo file") + s = os.stat(fn) + self.assertEquals(stat.S_IMODE(s.st_mode), + stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + finally: + os.umask(oldmask) + remove_files(TESTFN) + if TESTFN in sys.modules: del sys.modules[TESTFN] + del sys.path[0] + def testImpModule(self): # Verify that the imp module can correctly load and find .py files import imp @@ -232,6 +260,7 @@ class ImportTest(unittest.TestCase): else: self.fail("import by path didn't raise an exception") + class TestPycRewriting(unittest.TestCase): # Test that the `co_filename` attribute on code objects always points # to the right file, even when various things happen (e.g. both the .py diff --git a/Misc/NEWS b/Misc/NEWS index 8e6cbb82bcc..078c30d382d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.6.3 Core and Builtins ----------------- +- Issue #6070: On posix platforms import no longer copies the execute bit + from the .py file to the .pyc file if it is set. + - Issue #4547: When debugging a very large function, it was not always possible to update the lineno attribute of the current frame. diff --git a/Python/import.c b/Python/import.c index 5270b3771cf..4846e1091a8 100644 --- a/Python/import.c +++ b/Python/import.c @@ -879,7 +879,11 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat) { FILE *fp; time_t mtime = srcstat->st_mtime; - mode_t mode = srcstat->st_mode; +#ifdef MS_WINDOWS /* since Windows uses different permissions */ + mode_t mode = srcstat->st_mode & ~S_IEXEC; +#else + mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH; +#endif fp = open_exclusive(cpathname, mode); if (fp == NULL) {