| 1 | from test.test_support import TESTFN, TestFailed |
| 2 | |
| 3 | import os |
| 4 | import random |
| 5 | import sys |
| 6 | import py_compile |
| 7 | |
| 8 | # Brief digression to test that import is case-sensitive: if we got this |
| 9 | # far, we know for sure that "random" exists. |
| 10 | try: |
| 11 | import RAnDoM |
| 12 | except ImportError: |
| 13 | pass |
| 14 | else: |
| 15 | raise TestFailed("import of RAnDoM should have failed (case mismatch)") |
| 16 | |
| 17 | # Another brief digression to test the accuracy of manifest float constants. |
| 18 | import double_const # don't blink -- that *was* the test |
| 19 | |
| 20 | def remove_files(name): |
| 21 | for f in (name + os.extsep + "py", |
| 22 | name + os.extsep + "pyc", |
| 23 | name + os.extsep + "pyo", |
| 24 | name + os.extsep + "pyw", |
| 25 | name + "$py.class"): |
| 26 | if os.path.exists(f): |
| 27 | os.remove(f) |
| 28 | |
| 29 | def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw" |
| 30 | source = TESTFN + ext |
| 31 | pyo = TESTFN + os.extsep + "pyo" |
| 32 | if sys.platform.startswith('java'): |
| 33 | pyc = TESTFN + "$py.class" |
| 34 | else: |
| 35 | pyc = TESTFN + os.extsep + "pyc" |
| 36 | |
| 37 | f = open(source, "w") |
| 38 | print >> f, "# This tests Python's ability to import a", ext, "file." |
| 39 | a = random.randrange(1000) |
| 40 | b = random.randrange(1000) |
| 41 | print >> f, "a =", a |
| 42 | print >> f, "b =", b |
| 43 | f.close() |
| 44 | |
| 45 | try: |
| 46 | try: |
| 47 | mod = __import__(TESTFN) |
| 48 | except ImportError, err: |
| 49 | raise ValueError("import from %s failed: %s" % (ext, err)) |
| 50 | |
| 51 | if mod.a != a or mod.b != b: |
| 52 | print a, "!=", mod.a |
| 53 | print b, "!=", mod.b |
| 54 | raise ValueError("module loaded (%s) but contents invalid" % mod) |
| 55 | finally: |
| 56 | os.unlink(source) |
| 57 | |
| 58 | try: |
| 59 | try: |
| 60 | reload(mod) |
| 61 | except ImportError, err: |
| 62 | raise ValueError("import from .pyc/.pyo failed: %s" % err) |
| 63 | finally: |
| 64 | try: |
| 65 | os.unlink(pyc) |
| 66 | except os.error: |
| 67 | pass |
| 68 | try: |
| 69 | os.unlink(pyo) |
| 70 | except os.error: |
| 71 | pass |
| 72 | del sys.modules[TESTFN] |
| 73 | |
| 74 | sys.path.insert(0, os.curdir) |
| 75 | try: |
| 76 | test_with_extension(os.extsep + "py") |
| 77 | if sys.platform.startswith("win"): |
| 78 | for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw": |
| 79 | test_with_extension(ext) |
| 80 | finally: |
| 81 | del sys.path[0] |
| 82 | |
| 83 | # Verify that the imp module can correctly load and find .py files |
| 84 | import imp |
| 85 | x = imp.find_module("os") |
| 86 | os = imp.load_module("os", *x) |
| 87 | |
| 88 | def test_module_with_large_stack(module): |
| 89 | # create module w/list of 65000 elements to test bug #561858 |
| 90 | filename = module + os.extsep + 'py' |
| 91 | |
| 92 | # create a file with a list of 65000 elements |
| 93 | f = open(filename, 'w+') |
| 94 | f.write('d = [\n') |
| 95 | for i in range(65000): |
| 96 | f.write('"",\n') |
| 97 | f.write(']') |
| 98 | f.close() |
| 99 | |
| 100 | # compile & remove .py file, we only need .pyc (or .pyo) |
| 101 | f = open(filename, 'r') |
| 102 | py_compile.compile(filename) |
| 103 | f.close() |
| 104 | os.unlink(filename) |
| 105 | |
| 106 | # need to be able to load from current dir |
| 107 | sys.path.append('') |
| 108 | |
| 109 | # this used to crash |
| 110 | exec 'import ' + module |
| 111 | |
| 112 | # cleanup |
| 113 | del sys.path[-1] |
| 114 | for ext in 'pyc', 'pyo': |
| 115 | fname = module + os.extsep + ext |
| 116 | if os.path.exists(fname): |
| 117 | os.unlink(fname) |
| 118 | |
| 119 | test_module_with_large_stack('longlist') |
| 120 | |
| 121 | def test_failing_import_sticks(): |
| 122 | source = TESTFN + os.extsep + "py" |
| 123 | f = open(source, "w") |
| 124 | print >> f, "a = 1/0" |
| 125 | f.close() |
| 126 | |
| 127 | # New in 2.4, we shouldn't be able to import that no matter how often |
| 128 | # we try. |
| 129 | sys.path.insert(0, os.curdir) |
| 130 | try: |
| 131 | for i in 1, 2, 3: |
| 132 | try: |
| 133 | mod = __import__(TESTFN) |
| 134 | except ZeroDivisionError: |
| 135 | if TESTFN in sys.modules: |
| 136 | raise TestFailed("damaged module in sys.modules", i) |
| 137 | else: |
| 138 | raise TestFailed("was able to import a damaged module", i) |
| 139 | finally: |
| 140 | sys.path.pop(0) |
| 141 | remove_files(TESTFN) |
| 142 | |
| 143 | test_failing_import_sticks() |
| 144 | |
| 145 | def test_failing_reload(): |
| 146 | # A failing reload should leave the module object in sys.modules. |
| 147 | source = TESTFN + os.extsep + "py" |
| 148 | f = open(source, "w") |
| 149 | print >> f, "a = 1" |
| 150 | print >> f, "b = 2" |
| 151 | f.close() |
| 152 | |
| 153 | sys.path.insert(0, os.curdir) |
| 154 | try: |
| 155 | mod = __import__(TESTFN) |
| 156 | if TESTFN not in sys.modules: |
| 157 | raise TestFailed("expected module in sys.modules") |
| 158 | if mod.a != 1 or mod.b != 2: |
| 159 | raise TestFailed("module has wrong attribute values") |
| 160 | |
| 161 | # On WinXP, just replacing the .py file wasn't enough to |
| 162 | # convince reload() to reparse it. Maybe the timestamp didn't |
| 163 | # move enough. We force it to get reparsed by removing the |
| 164 | # compiled file too. |
| 165 | remove_files(TESTFN) |
| 166 | |
| 167 | # Now damage the module. |
| 168 | f = open(source, "w") |
| 169 | print >> f, "a = 10" |
| 170 | print >> f, "b = 20//0" |
| 171 | f.close() |
| 172 | try: |
| 173 | reload(mod) |
| 174 | except ZeroDivisionError: |
| 175 | pass |
| 176 | else: |
| 177 | raise TestFailed("was able to reload a damaged module") |
| 178 | |
| 179 | # But we still expect the module to be in sys.modules. |
| 180 | mod = sys.modules.get(TESTFN) |
| 181 | if mod is None: |
| 182 | raise TestFailed("expected module to still be in sys.modules") |
| 183 | # We should have replaced a w/ 10, but the old b value should |
| 184 | # stick. |
| 185 | if mod.a != 10 or mod.b != 2: |
| 186 | raise TestFailed("module has wrong attribute values") |
| 187 | |
| 188 | finally: |
| 189 | sys.path.pop(0) |
| 190 | remove_files(TESTFN) |
| 191 | if TESTFN in sys.modules: |
| 192 | del sys.modules[TESTFN] |
| 193 | |
| 194 | test_failing_reload() |