~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/importlib/test/source/test_file_loader.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import importlib
 
2
from importlib import _bootstrap
 
3
from .. import abc
 
4
from . import util as source_util
 
5
 
 
6
import imp
 
7
import os
 
8
import py_compile
 
9
import sys
 
10
import unittest
 
11
 
 
12
 
 
13
class SimpleTest(unittest.TestCase):
 
14
 
 
15
    """Should have no issue importing a source module [basic]. And if there is
 
16
    a syntax error, it should raise a SyntaxError [syntax error].
 
17
 
 
18
    """
 
19
 
 
20
    # [basic]
 
21
    def test_module(self):
 
22
        with source_util.create_modules('_temp') as mapping:
 
23
            loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
 
24
                                                    False)
 
25
            module = loader.load_module('_temp')
 
26
            self.assert_('_temp' in sys.modules)
 
27
            check = {'__name__': '_temp', '__file__': mapping['_temp'],
 
28
                     '__package__': ''}
 
29
            for attr, value in check.items():
 
30
                self.assertEqual(getattr(module, attr), value)
 
31
 
 
32
    def test_package(self):
 
33
        with source_util.create_modules('_pkg.__init__') as mapping:
 
34
            loader = _bootstrap._PyPycFileLoader('_pkg',
 
35
                                                 mapping['_pkg.__init__'],
 
36
                                                 True)
 
37
            module = loader.load_module('_pkg')
 
38
            self.assert_('_pkg' in sys.modules)
 
39
            check = {'__name__': '_pkg', '__file__': mapping['_pkg.__init__'],
 
40
                     '__path__': [os.path.dirname(mapping['_pkg.__init__'])],
 
41
                     '__package__': '_pkg'}
 
42
            for attr, value in check.items():
 
43
                self.assertEqual(getattr(module, attr), value)
 
44
 
 
45
 
 
46
    def test_lacking_parent(self):
 
47
        with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
 
48
            loader = _bootstrap._PyPycFileLoader('_pkg.mod',
 
49
                                                    mapping['_pkg.mod'], False)
 
50
            module = loader.load_module('_pkg.mod')
 
51
            self.assert_('_pkg.mod' in sys.modules)
 
52
            check = {'__name__': '_pkg.mod', '__file__': mapping['_pkg.mod'],
 
53
                     '__package__': '_pkg'}
 
54
            for attr, value in check.items():
 
55
                self.assertEqual(getattr(module, attr), value)
 
56
 
 
57
    def fake_mtime(self, fxn):
 
58
        """Fake mtime to always be higher than expected."""
 
59
        return lambda name: fxn(name) + 1
 
60
 
 
61
    def test_module_reuse(self):
 
62
        with source_util.create_modules('_temp') as mapping:
 
63
            loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
 
64
                                                    False)
 
65
            module = loader.load_module('_temp')
 
66
            module_id = id(module)
 
67
            module_dict_id = id(module.__dict__)
 
68
            with open(mapping['_temp'], 'w') as file:
 
69
                file.write("testing_var = 42\n")
 
70
            # For filesystems where the mtime is only to a second granularity,
 
71
            # everything that has happened above can be too fast;
 
72
            # force an mtime on the source that is guaranteed to be different
 
73
            # than the original mtime.
 
74
            loader.source_mtime = self.fake_mtime(loader.source_mtime)
 
75
            module = loader.load_module('_temp')
 
76
            self.assert_('testing_var' in module.__dict__,
 
77
                         "'testing_var' not in "
 
78
                            "{0}".format(list(module.__dict__.keys())))
 
79
            self.assertEqual(module, sys.modules['_temp'])
 
80
            self.assertEqual(id(module), module_id)
 
81
            self.assertEqual(id(module.__dict__), module_dict_id)
 
82
 
 
83
    def test_state_after_failure(self):
 
84
        # A failed reload should leave the original module intact.
 
85
        attributes = ('__file__', '__path__', '__package__')
 
86
        value = '<test>'
 
87
        name = '_temp'
 
88
        with source_util.create_modules(name) as mapping:
 
89
            orig_module = imp.new_module(name)
 
90
            for attr in attributes:
 
91
                setattr(orig_module, attr, value)
 
92
            with open(mapping[name], 'w') as file:
 
93
                file.write('+++ bad syntax +++')
 
94
            loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
 
95
                                                    False)
 
96
            self.assertRaises(SyntaxError, loader.load_module, name)
 
97
            for attr in attributes:
 
98
                self.assertEqual(getattr(orig_module, attr), value)
 
99
 
 
100
    # [syntax error]
 
101
    def test_bad_syntax(self):
 
102
        with source_util.create_modules('_temp') as mapping:
 
103
            with open(mapping['_temp'], 'w') as file:
 
104
                file.write('=')
 
105
            loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
 
106
                                                    False)
 
107
            self.assertRaises(SyntaxError, loader.load_module, '_temp')
 
108
            self.assert_('_temp' not in sys.modules)
 
109
 
 
110
 
 
111
class BadBytecodeTest(unittest.TestCase):
 
112
 
 
113
    """But there are several things about the bytecode which might lead to the
 
114
    source being preferred. If the magic number differs from what the
 
115
    interpreter uses, then the source is used with the bytecode regenerated.
 
116
    If the timestamp is older than the modification time for the source then
 
117
    the bytecode is not used [bad timestamp].
 
118
 
 
119
    But if the marshal data is bad, even if the magic number and timestamp
 
120
    work, a ValueError is raised and the source is not used [bad marshal].
 
121
 
 
122
    """
 
123
 
 
124
    def import_(self, file, module_name):
 
125
        loader = _bootstrap._PyPycFileLoader(module_name, file, False)
 
126
        module = loader.load_module(module_name)
 
127
        self.assert_(module_name in sys.modules)
 
128
 
 
129
    # [bad magic]
 
130
    @source_util.writes_bytecode
 
131
    def test_bad_magic(self):
 
132
        with source_util.create_modules('_temp') as mapping:
 
133
            py_compile.compile(mapping['_temp'])
 
134
            bytecode_path = source_util.bytecode_path(mapping['_temp'])
 
135
            with open(bytecode_path, 'r+b') as bytecode_file:
 
136
                bytecode_file.seek(0)
 
137
                bytecode_file.write(b'\x00\x00\x00\x00')
 
138
            self.import_(mapping['_temp'], '_temp')
 
139
            with open(bytecode_path, 'rb') as bytecode_file:
 
140
                self.assertEqual(bytecode_file.read(4), imp.get_magic())
 
141
 
 
142
    # [bad timestamp]
 
143
    @source_util.writes_bytecode
 
144
    def test_bad_bytecode(self):
 
145
        zeros = b'\x00\x00\x00\x00'
 
146
        with source_util.create_modules('_temp') as mapping:
 
147
            py_compile.compile(mapping['_temp'])
 
148
            bytecode_path = source_util.bytecode_path(mapping['_temp'])
 
149
            with open(bytecode_path, 'r+b') as bytecode_file:
 
150
                bytecode_file.seek(4)
 
151
                bytecode_file.write(zeros)
 
152
            self.import_(mapping['_temp'], '_temp')
 
153
            source_mtime = os.path.getmtime(mapping['_temp'])
 
154
            source_timestamp = importlib._w_long(source_mtime)
 
155
            with open(bytecode_path, 'rb') as bytecode_file:
 
156
                bytecode_file.seek(4)
 
157
                self.assertEqual(bytecode_file.read(4), source_timestamp)
 
158
 
 
159
    # [bad marshal]
 
160
    def test_bad_marshal(self):
 
161
        with source_util.create_modules('_temp') as mapping:
 
162
            bytecode_path = source_util.bytecode_path(mapping['_temp'])
 
163
            source_mtime = os.path.getmtime(mapping['_temp'])
 
164
            source_timestamp = importlib._w_long(source_mtime)
 
165
            with open(bytecode_path, 'wb') as bytecode_file:
 
166
                bytecode_file.write(imp.get_magic())
 
167
                bytecode_file.write(source_timestamp)
 
168
                bytecode_file.write(b'AAAA')
 
169
            self.assertRaises(ValueError, self.import_, mapping['_temp'],
 
170
                                '_temp')
 
171
            self.assert_('_temp' not in sys.modules)
 
172
 
 
173
 
 
174
def test_main():
 
175
    from test.support import run_unittest
 
176
    run_unittest(SimpleTest, DontWriteBytecodeTest, BadDataTest,
 
177
                 SourceBytecodeInteraction, BadBytecodeTest)
 
178
 
 
179
 
 
180
if __name__ == '__main__':
 
181
    test_main()