»Core Development>Code coverage>Lib/test/test_importlib/test_util.py

Python code coverage for Lib/test/test_importlib/test_util.py

#countcontent
1n/afrom . import util
2n/aabc = util.import_importlib('importlib.abc')
3n/ainit = util.import_importlib('importlib')
4n/amachinery = util.import_importlib('importlib.machinery')
5n/aimportlib_util = util.import_importlib('importlib.util')
6n/a
7n/aimport os
8n/aimport pathlib
9n/aimport string
10n/aimport sys
11n/afrom test import support
12n/aimport types
13n/aimport unittest
14n/aimport warnings
15n/a
16n/a
17n/aclass DecodeSourceBytesTests:
18n/a
19n/a source = "string ='ü'"
20n/a
21n/a def test_ut8_default(self):
22n/a source_bytes = self.source.encode('utf-8')
23n/a self.assertEqual(self.util.decode_source(source_bytes), self.source)
24n/a
25n/a def test_specified_encoding(self):
26n/a source = '# coding=latin-1\n' + self.source
27n/a source_bytes = source.encode('latin-1')
28n/a assert source_bytes != source.encode('utf-8')
29n/a self.assertEqual(self.util.decode_source(source_bytes), source)
30n/a
31n/a def test_universal_newlines(self):
32n/a source = '\r\n'.join([self.source, self.source])
33n/a source_bytes = source.encode('utf-8')
34n/a self.assertEqual(self.util.decode_source(source_bytes),
35n/a '\n'.join([self.source, self.source]))
36n/a
37n/a
38n/a(Frozen_DecodeSourceBytesTests,
39n/a Source_DecodeSourceBytesTests
40n/a ) = util.test_both(DecodeSourceBytesTests, util=importlib_util)
41n/a
42n/a
43n/aclass ModuleFromSpecTests:
44n/a
45n/a def test_no_create_module(self):
46n/a class Loader:
47n/a def exec_module(self, module):
48n/a pass
49n/a spec = self.machinery.ModuleSpec('test', Loader())
50n/a with self.assertRaises(ImportError):
51n/a module = self.util.module_from_spec(spec)
52n/a
53n/a def test_create_module_returns_None(self):
54n/a class Loader(self.abc.Loader):
55n/a def create_module(self, spec):
56n/a return None
57n/a spec = self.machinery.ModuleSpec('test', Loader())
58n/a module = self.util.module_from_spec(spec)
59n/a self.assertIsInstance(module, types.ModuleType)
60n/a self.assertEqual(module.__name__, spec.name)
61n/a
62n/a def test_create_module(self):
63n/a name = 'already set'
64n/a class CustomModule(types.ModuleType):
65n/a pass
66n/a class Loader(self.abc.Loader):
67n/a def create_module(self, spec):
68n/a module = CustomModule(spec.name)
69n/a module.__name__ = name
70n/a return module
71n/a spec = self.machinery.ModuleSpec('test', Loader())
72n/a module = self.util.module_from_spec(spec)
73n/a self.assertIsInstance(module, CustomModule)
74n/a self.assertEqual(module.__name__, name)
75n/a
76n/a def test___name__(self):
77n/a spec = self.machinery.ModuleSpec('test', object())
78n/a module = self.util.module_from_spec(spec)
79n/a self.assertEqual(module.__name__, spec.name)
80n/a
81n/a def test___spec__(self):
82n/a spec = self.machinery.ModuleSpec('test', object())
83n/a module = self.util.module_from_spec(spec)
84n/a self.assertEqual(module.__spec__, spec)
85n/a
86n/a def test___loader__(self):
87n/a loader = object()
88n/a spec = self.machinery.ModuleSpec('test', loader)
89n/a module = self.util.module_from_spec(spec)
90n/a self.assertIs(module.__loader__, loader)
91n/a
92n/a def test___package__(self):
93n/a spec = self.machinery.ModuleSpec('test.pkg', object())
94n/a module = self.util.module_from_spec(spec)
95n/a self.assertEqual(module.__package__, spec.parent)
96n/a
97n/a def test___path__(self):
98n/a spec = self.machinery.ModuleSpec('test', object(), is_package=True)
99n/a module = self.util.module_from_spec(spec)
100n/a self.assertEqual(module.__path__, spec.submodule_search_locations)
101n/a
102n/a def test___file__(self):
103n/a spec = self.machinery.ModuleSpec('test', object(), origin='some/path')
104n/a spec.has_location = True
105n/a module = self.util.module_from_spec(spec)
106n/a self.assertEqual(module.__file__, spec.origin)
107n/a
108n/a def test___cached__(self):
109n/a spec = self.machinery.ModuleSpec('test', object())
110n/a spec.cached = 'some/path'
111n/a spec.has_location = True
112n/a module = self.util.module_from_spec(spec)
113n/a self.assertEqual(module.__cached__, spec.cached)
114n/a
115n/a(Frozen_ModuleFromSpecTests,
116n/a Source_ModuleFromSpecTests
117n/a) = util.test_both(ModuleFromSpecTests, abc=abc, machinery=machinery,
118n/a util=importlib_util)
119n/a
120n/a
121n/aclass ModuleForLoaderTests:
122n/a
123n/a """Tests for importlib.util.module_for_loader."""
124n/a
125n/a @classmethod
126n/a def module_for_loader(cls, func):
127n/a with warnings.catch_warnings():
128n/a warnings.simplefilter('ignore', DeprecationWarning)
129n/a return cls.util.module_for_loader(func)
130n/a
131n/a def test_warning(self):
132n/a # Should raise a PendingDeprecationWarning when used.
133n/a with warnings.catch_warnings():
134n/a warnings.simplefilter('error', DeprecationWarning)
135n/a with self.assertRaises(DeprecationWarning):
136n/a func = self.util.module_for_loader(lambda x: x)
137n/a
138n/a def return_module(self, name):
139n/a fxn = self.module_for_loader(lambda self, module: module)
140n/a return fxn(self, name)
141n/a
142n/a def raise_exception(self, name):
143n/a def to_wrap(self, module):
144n/a raise ImportError
145n/a fxn = self.module_for_loader(to_wrap)
146n/a try:
147n/a fxn(self, name)
148n/a except ImportError:
149n/a pass
150n/a
151n/a def test_new_module(self):
152n/a # Test that when no module exists in sys.modules a new module is
153n/a # created.
154n/a module_name = 'a.b.c'
155n/a with util.uncache(module_name):
156n/a module = self.return_module(module_name)
157n/a self.assertIn(module_name, sys.modules)
158n/a self.assertIsInstance(module, types.ModuleType)
159n/a self.assertEqual(module.__name__, module_name)
160n/a
161n/a def test_reload(self):
162n/a # Test that a module is reused if already in sys.modules.
163n/a class FakeLoader:
164n/a def is_package(self, name):
165n/a return True
166n/a @self.module_for_loader
167n/a def load_module(self, module):
168n/a return module
169n/a name = 'a.b.c'
170n/a module = types.ModuleType('a.b.c')
171n/a module.__loader__ = 42
172n/a module.__package__ = 42
173n/a with util.uncache(name):
174n/a sys.modules[name] = module
175n/a loader = FakeLoader()
176n/a returned_module = loader.load_module(name)
177n/a self.assertIs(returned_module, sys.modules[name])
178n/a self.assertEqual(module.__loader__, loader)
179n/a self.assertEqual(module.__package__, name)
180n/a
181n/a def test_new_module_failure(self):
182n/a # Test that a module is removed from sys.modules if added but an
183n/a # exception is raised.
184n/a name = 'a.b.c'
185n/a with util.uncache(name):
186n/a self.raise_exception(name)
187n/a self.assertNotIn(name, sys.modules)
188n/a
189n/a def test_reload_failure(self):
190n/a # Test that a failure on reload leaves the module in-place.
191n/a name = 'a.b.c'
192n/a module = types.ModuleType(name)
193n/a with util.uncache(name):
194n/a sys.modules[name] = module
195n/a self.raise_exception(name)
196n/a self.assertIs(module, sys.modules[name])
197n/a
198n/a def test_decorator_attrs(self):
199n/a def fxn(self, module): pass
200n/a wrapped = self.module_for_loader(fxn)
201n/a self.assertEqual(wrapped.__name__, fxn.__name__)
202n/a self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
203n/a
204n/a def test_false_module(self):
205n/a # If for some odd reason a module is considered false, still return it
206n/a # from sys.modules.
207n/a class FalseModule(types.ModuleType):
208n/a def __bool__(self): return False
209n/a
210n/a name = 'mod'
211n/a module = FalseModule(name)
212n/a with util.uncache(name):
213n/a self.assertFalse(module)
214n/a sys.modules[name] = module
215n/a given = self.return_module(name)
216n/a self.assertIs(given, module)
217n/a
218n/a def test_attributes_set(self):
219n/a # __name__, __loader__, and __package__ should be set (when
220n/a # is_package() is defined; undefined implicitly tested elsewhere).
221n/a class FakeLoader:
222n/a def __init__(self, is_package):
223n/a self._pkg = is_package
224n/a def is_package(self, name):
225n/a return self._pkg
226n/a @self.module_for_loader
227n/a def load_module(self, module):
228n/a return module
229n/a
230n/a name = 'pkg.mod'
231n/a with util.uncache(name):
232n/a loader = FakeLoader(False)
233n/a module = loader.load_module(name)
234n/a self.assertEqual(module.__name__, name)
235n/a self.assertIs(module.__loader__, loader)
236n/a self.assertEqual(module.__package__, 'pkg')
237n/a
238n/a name = 'pkg.sub'
239n/a with util.uncache(name):
240n/a loader = FakeLoader(True)
241n/a module = loader.load_module(name)
242n/a self.assertEqual(module.__name__, name)
243n/a self.assertIs(module.__loader__, loader)
244n/a self.assertEqual(module.__package__, name)
245n/a
246n/a
247n/a(Frozen_ModuleForLoaderTests,
248n/a Source_ModuleForLoaderTests
249n/a ) = util.test_both(ModuleForLoaderTests, util=importlib_util)
250n/a
251n/a
252n/aclass SetPackageTests:
253n/a
254n/a """Tests for importlib.util.set_package."""
255n/a
256n/a def verify(self, module, expect):
257n/a """Verify the module has the expected value for __package__ after
258n/a passing through set_package."""
259n/a fxn = lambda: module
260n/a wrapped = self.util.set_package(fxn)
261n/a with warnings.catch_warnings():
262n/a warnings.simplefilter('ignore', DeprecationWarning)
263n/a wrapped()
264n/a self.assertTrue(hasattr(module, '__package__'))
265n/a self.assertEqual(expect, module.__package__)
266n/a
267n/a def test_top_level(self):
268n/a # __package__ should be set to the empty string if a top-level module.
269n/a # Implicitly tests when package is set to None.
270n/a module = types.ModuleType('module')
271n/a module.__package__ = None
272n/a self.verify(module, '')
273n/a
274n/a def test_package(self):
275n/a # Test setting __package__ for a package.
276n/a module = types.ModuleType('pkg')
277n/a module.__path__ = ['<path>']
278n/a module.__package__ = None
279n/a self.verify(module, 'pkg')
280n/a
281n/a def test_submodule(self):
282n/a # Test __package__ for a module in a package.
283n/a module = types.ModuleType('pkg.mod')
284n/a module.__package__ = None
285n/a self.verify(module, 'pkg')
286n/a
287n/a def test_setting_if_missing(self):
288n/a # __package__ should be set if it is missing.
289n/a module = types.ModuleType('mod')
290n/a if hasattr(module, '__package__'):
291n/a delattr(module, '__package__')
292n/a self.verify(module, '')
293n/a
294n/a def test_leaving_alone(self):
295n/a # If __package__ is set and not None then leave it alone.
296n/a for value in (True, False):
297n/a module = types.ModuleType('mod')
298n/a module.__package__ = value
299n/a self.verify(module, value)
300n/a
301n/a def test_decorator_attrs(self):
302n/a def fxn(module): pass
303n/a with warnings.catch_warnings():
304n/a warnings.simplefilter('ignore', DeprecationWarning)
305n/a wrapped = self.util.set_package(fxn)
306n/a self.assertEqual(wrapped.__name__, fxn.__name__)
307n/a self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
308n/a
309n/a
310n/a(Frozen_SetPackageTests,
311n/a Source_SetPackageTests
312n/a ) = util.test_both(SetPackageTests, util=importlib_util)
313n/a
314n/a
315n/aclass SetLoaderTests:
316n/a
317n/a """Tests importlib.util.set_loader()."""
318n/a
319n/a @property
320n/a def DummyLoader(self):
321n/a # Set DummyLoader on the class lazily.
322n/a class DummyLoader:
323n/a @self.util.set_loader
324n/a def load_module(self, module):
325n/a return self.module
326n/a self.__class__.DummyLoader = DummyLoader
327n/a return DummyLoader
328n/a
329n/a def test_no_attribute(self):
330n/a loader = self.DummyLoader()
331n/a loader.module = types.ModuleType('blah')
332n/a try:
333n/a del loader.module.__loader__
334n/a except AttributeError:
335n/a pass
336n/a with warnings.catch_warnings():
337n/a warnings.simplefilter('ignore', DeprecationWarning)
338n/a self.assertEqual(loader, loader.load_module('blah').__loader__)
339n/a
340n/a def test_attribute_is_None(self):
341n/a loader = self.DummyLoader()
342n/a loader.module = types.ModuleType('blah')
343n/a loader.module.__loader__ = None
344n/a with warnings.catch_warnings():
345n/a warnings.simplefilter('ignore', DeprecationWarning)
346n/a self.assertEqual(loader, loader.load_module('blah').__loader__)
347n/a
348n/a def test_not_reset(self):
349n/a loader = self.DummyLoader()
350n/a loader.module = types.ModuleType('blah')
351n/a loader.module.__loader__ = 42
352n/a with warnings.catch_warnings():
353n/a warnings.simplefilter('ignore', DeprecationWarning)
354n/a self.assertEqual(42, loader.load_module('blah').__loader__)
355n/a
356n/a
357n/a(Frozen_SetLoaderTests,
358n/a Source_SetLoaderTests
359n/a ) = util.test_both(SetLoaderTests, util=importlib_util)
360n/a
361n/a
362n/aclass ResolveNameTests:
363n/a
364n/a """Tests importlib.util.resolve_name()."""
365n/a
366n/a def test_absolute(self):
367n/a # bacon
368n/a self.assertEqual('bacon', self.util.resolve_name('bacon', None))
369n/a
370n/a def test_absolute_within_package(self):
371n/a # bacon in spam
372n/a self.assertEqual('bacon', self.util.resolve_name('bacon', 'spam'))
373n/a
374n/a def test_no_package(self):
375n/a # .bacon in ''
376n/a with self.assertRaises(ValueError):
377n/a self.util.resolve_name('.bacon', '')
378n/a
379n/a def test_in_package(self):
380n/a # .bacon in spam
381n/a self.assertEqual('spam.eggs.bacon',
382n/a self.util.resolve_name('.bacon', 'spam.eggs'))
383n/a
384n/a def test_other_package(self):
385n/a # ..bacon in spam.bacon
386n/a self.assertEqual('spam.bacon',
387n/a self.util.resolve_name('..bacon', 'spam.eggs'))
388n/a
389n/a def test_escape(self):
390n/a # ..bacon in spam
391n/a with self.assertRaises(ValueError):
392n/a self.util.resolve_name('..bacon', 'spam')
393n/a
394n/a
395n/a(Frozen_ResolveNameTests,
396n/a Source_ResolveNameTests
397n/a ) = util.test_both(ResolveNameTests, util=importlib_util)
398n/a
399n/a
400n/aclass FindSpecTests:
401n/a
402n/a class FakeMetaFinder:
403n/a @staticmethod
404n/a def find_spec(name, path=None, target=None): return name, path, target
405n/a
406n/a def test_sys_modules(self):
407n/a name = 'some_mod'
408n/a with util.uncache(name):
409n/a module = types.ModuleType(name)
410n/a loader = 'a loader!'
411n/a spec = self.machinery.ModuleSpec(name, loader)
412n/a module.__loader__ = loader
413n/a module.__spec__ = spec
414n/a sys.modules[name] = module
415n/a found = self.util.find_spec(name)
416n/a self.assertEqual(found, spec)
417n/a
418n/a def test_sys_modules_without___loader__(self):
419n/a name = 'some_mod'
420n/a with util.uncache(name):
421n/a module = types.ModuleType(name)
422n/a del module.__loader__
423n/a loader = 'a loader!'
424n/a spec = self.machinery.ModuleSpec(name, loader)
425n/a module.__spec__ = spec
426n/a sys.modules[name] = module
427n/a found = self.util.find_spec(name)
428n/a self.assertEqual(found, spec)
429n/a
430n/a def test_sys_modules_spec_is_None(self):
431n/a name = 'some_mod'
432n/a with util.uncache(name):
433n/a module = types.ModuleType(name)
434n/a module.__spec__ = None
435n/a sys.modules[name] = module
436n/a with self.assertRaises(ValueError):
437n/a self.util.find_spec(name)
438n/a
439n/a def test_sys_modules_loader_is_None(self):
440n/a name = 'some_mod'
441n/a with util.uncache(name):
442n/a module = types.ModuleType(name)
443n/a spec = self.machinery.ModuleSpec(name, None)
444n/a module.__spec__ = spec
445n/a sys.modules[name] = module
446n/a found = self.util.find_spec(name)
447n/a self.assertEqual(found, spec)
448n/a
449n/a def test_sys_modules_spec_is_not_set(self):
450n/a name = 'some_mod'
451n/a with util.uncache(name):
452n/a module = types.ModuleType(name)
453n/a try:
454n/a del module.__spec__
455n/a except AttributeError:
456n/a pass
457n/a sys.modules[name] = module
458n/a with self.assertRaises(ValueError):
459n/a self.util.find_spec(name)
460n/a
461n/a def test_success(self):
462n/a name = 'some_mod'
463n/a with util.uncache(name):
464n/a with util.import_state(meta_path=[self.FakeMetaFinder]):
465n/a self.assertEqual((name, None, None),
466n/a self.util.find_spec(name))
467n/a
468n/a def test_nothing(self):
469n/a # None is returned upon failure to find a loader.
470n/a self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule'))
471n/a
472n/a def test_find_submodule(self):
473n/a name = 'spam'
474n/a subname = 'ham'
475n/a with util.temp_module(name, pkg=True) as pkg_dir:
476n/a fullname, _ = util.submodule(name, subname, pkg_dir)
477n/a spec = self.util.find_spec(fullname)
478n/a self.assertIsNot(spec, None)
479n/a self.assertIn(name, sorted(sys.modules))
480n/a self.assertNotIn(fullname, sorted(sys.modules))
481n/a # Ensure successive calls behave the same.
482n/a spec_again = self.util.find_spec(fullname)
483n/a self.assertEqual(spec_again, spec)
484n/a
485n/a def test_find_submodule_parent_already_imported(self):
486n/a name = 'spam'
487n/a subname = 'ham'
488n/a with util.temp_module(name, pkg=True) as pkg_dir:
489n/a self.init.import_module(name)
490n/a fullname, _ = util.submodule(name, subname, pkg_dir)
491n/a spec = self.util.find_spec(fullname)
492n/a self.assertIsNot(spec, None)
493n/a self.assertIn(name, sorted(sys.modules))
494n/a self.assertNotIn(fullname, sorted(sys.modules))
495n/a # Ensure successive calls behave the same.
496n/a spec_again = self.util.find_spec(fullname)
497n/a self.assertEqual(spec_again, spec)
498n/a
499n/a def test_find_relative_module(self):
500n/a name = 'spam'
501n/a subname = 'ham'
502n/a with util.temp_module(name, pkg=True) as pkg_dir:
503n/a fullname, _ = util.submodule(name, subname, pkg_dir)
504n/a relname = '.' + subname
505n/a spec = self.util.find_spec(relname, name)
506n/a self.assertIsNot(spec, None)
507n/a self.assertIn(name, sorted(sys.modules))
508n/a self.assertNotIn(fullname, sorted(sys.modules))
509n/a # Ensure successive calls behave the same.
510n/a spec_again = self.util.find_spec(fullname)
511n/a self.assertEqual(spec_again, spec)
512n/a
513n/a def test_find_relative_module_missing_package(self):
514n/a name = 'spam'
515n/a subname = 'ham'
516n/a with util.temp_module(name, pkg=True) as pkg_dir:
517n/a fullname, _ = util.submodule(name, subname, pkg_dir)
518n/a relname = '.' + subname
519n/a with self.assertRaises(ValueError):
520n/a self.util.find_spec(relname)
521n/a self.assertNotIn(name, sorted(sys.modules))
522n/a self.assertNotIn(fullname, sorted(sys.modules))
523n/a
524n/a
525n/a(Frozen_FindSpecTests,
526n/a Source_FindSpecTests
527n/a ) = util.test_both(FindSpecTests, init=init, util=importlib_util,
528n/a machinery=machinery)
529n/a
530n/a
531n/aclass MagicNumberTests:
532n/a
533n/a def test_length(self):
534n/a # Should be 4 bytes.
535n/a self.assertEqual(len(self.util.MAGIC_NUMBER), 4)
536n/a
537n/a def test_incorporates_rn(self):
538n/a # The magic number uses \r\n to come out wrong when splitting on lines.
539n/a self.assertTrue(self.util.MAGIC_NUMBER.endswith(b'\r\n'))
540n/a
541n/a
542n/a(Frozen_MagicNumberTests,
543n/a Source_MagicNumberTests
544n/a ) = util.test_both(MagicNumberTests, util=importlib_util)
545n/a
546n/a
547n/aclass PEP3147Tests:
548n/a
549n/a """Tests of PEP 3147-related functions: cache_from_source and source_from_cache."""
550n/a
551n/a tag = sys.implementation.cache_tag
552n/a
553n/a @unittest.skipUnless(sys.implementation.cache_tag is not None,
554n/a 'requires sys.implementation.cache_tag not be None')
555n/a def test_cache_from_source(self):
556n/a # Given the path to a .py file, return the path to its PEP 3147
557n/a # defined .pyc file (i.e. under __pycache__).
558n/a path = os.path.join('foo', 'bar', 'baz', 'qux.py')
559n/a expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
560n/a 'qux.{}.pyc'.format(self.tag))
561n/a self.assertEqual(self.util.cache_from_source(path, optimization=''),
562n/a expect)
563n/a
564n/a def test_cache_from_source_no_cache_tag(self):
565n/a # No cache tag means NotImplementedError.
566n/a with support.swap_attr(sys.implementation, 'cache_tag', None):
567n/a with self.assertRaises(NotImplementedError):
568n/a self.util.cache_from_source('whatever.py')
569n/a
570n/a def test_cache_from_source_no_dot(self):
571n/a # Directory with a dot, filename without dot.
572n/a path = os.path.join('foo.bar', 'file')
573n/a expect = os.path.join('foo.bar', '__pycache__',
574n/a 'file{}.pyc'.format(self.tag))
575n/a self.assertEqual(self.util.cache_from_source(path, optimization=''),
576n/a expect)
577n/a
578n/a def test_cache_from_source_debug_override(self):
579n/a # Given the path to a .py file, return the path to its PEP 3147/PEP 488
580n/a # defined .pyc file (i.e. under __pycache__).
581n/a path = os.path.join('foo', 'bar', 'baz', 'qux.py')
582n/a with warnings.catch_warnings():
583n/a warnings.simplefilter('ignore')
584n/a self.assertEqual(self.util.cache_from_source(path, False),
585n/a self.util.cache_from_source(path, optimization=1))
586n/a self.assertEqual(self.util.cache_from_source(path, True),
587n/a self.util.cache_from_source(path, optimization=''))
588n/a with warnings.catch_warnings():
589n/a warnings.simplefilter('error')
590n/a with self.assertRaises(DeprecationWarning):
591n/a self.util.cache_from_source(path, False)
592n/a with self.assertRaises(DeprecationWarning):
593n/a self.util.cache_from_source(path, True)
594n/a
595n/a def test_cache_from_source_cwd(self):
596n/a path = 'foo.py'
597n/a expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
598n/a self.assertEqual(self.util.cache_from_source(path, optimization=''),
599n/a expect)
600n/a
601n/a def test_cache_from_source_override(self):
602n/a # When debug_override is not None, it can be any true-ish or false-ish
603n/a # value.
604n/a path = os.path.join('foo', 'bar', 'baz.py')
605n/a # However if the bool-ishness can't be determined, the exception
606n/a # propagates.
607n/a class Bearish:
608n/a def __bool__(self): raise RuntimeError
609n/a with warnings.catch_warnings():
610n/a warnings.simplefilter('ignore')
611n/a self.assertEqual(self.util.cache_from_source(path, []),
612n/a self.util.cache_from_source(path, optimization=1))
613n/a self.assertEqual(self.util.cache_from_source(path, [17]),
614n/a self.util.cache_from_source(path, optimization=''))
615n/a with self.assertRaises(RuntimeError):
616n/a self.util.cache_from_source('/foo/bar/baz.py', Bearish())
617n/a
618n/a
619n/a def test_cache_from_source_optimization_empty_string(self):
620n/a # Setting 'optimization' to '' leads to no optimization tag (PEP 488).
621n/a path = 'foo.py'
622n/a expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
623n/a self.assertEqual(self.util.cache_from_source(path, optimization=''),
624n/a expect)
625n/a
626n/a def test_cache_from_source_optimization_None(self):
627n/a # Setting 'optimization' to None uses the interpreter's optimization.
628n/a # (PEP 488)
629n/a path = 'foo.py'
630n/a optimization_level = sys.flags.optimize
631n/a almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
632n/a if optimization_level == 0:
633n/a expect = almost_expect + '.pyc'
634n/a elif optimization_level <= 2:
635n/a expect = almost_expect + '.opt-{}.pyc'.format(optimization_level)
636n/a else:
637n/a msg = '{!r} is a non-standard optimization level'.format(optimization_level)
638n/a self.skipTest(msg)
639n/a self.assertEqual(self.util.cache_from_source(path, optimization=None),
640n/a expect)
641n/a
642n/a def test_cache_from_source_optimization_set(self):
643n/a # The 'optimization' parameter accepts anything that has a string repr
644n/a # that passes str.alnum().
645n/a path = 'foo.py'
646n/a valid_characters = string.ascii_letters + string.digits
647n/a almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
648n/a got = self.util.cache_from_source(path, optimization=valid_characters)
649n/a # Test all valid characters are accepted.
650n/a self.assertEqual(got,
651n/a almost_expect + '.opt-{}.pyc'.format(valid_characters))
652n/a # str() should be called on argument.
653n/a self.assertEqual(self.util.cache_from_source(path, optimization=42),
654n/a almost_expect + '.opt-42.pyc')
655n/a # Invalid characters raise ValueError.
656n/a with self.assertRaises(ValueError):
657n/a self.util.cache_from_source(path, optimization='path/is/bad')
658n/a
659n/a def test_cache_from_source_debug_override_optimization_both_set(self):
660n/a # Can only set one of the optimization-related parameters.
661n/a with warnings.catch_warnings():
662n/a warnings.simplefilter('ignore')
663n/a with self.assertRaises(TypeError):
664n/a self.util.cache_from_source('foo.py', False, optimization='')
665n/a
666n/a @unittest.skipUnless(os.sep == '\\' and os.altsep == '/',
667n/a 'test meaningful only where os.altsep is defined')
668n/a def test_sep_altsep_and_sep_cache_from_source(self):
669n/a # Windows path and PEP 3147 where sep is right of altsep.
670n/a self.assertEqual(
671n/a self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''),
672n/a '\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag))
673n/a
674n/a @unittest.skipUnless(sys.implementation.cache_tag is not None,
675n/a 'requires sys.implementation.cache_tag not be None')
676n/a def test_source_from_cache_path_like_arg(self):
677n/a path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py')
678n/a expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
679n/a 'qux.{}.pyc'.format(self.tag))
680n/a self.assertEqual(self.util.cache_from_source(path, optimization=''),
681n/a expect)
682n/a
683n/a @unittest.skipUnless(sys.implementation.cache_tag is not None,
684n/a 'requires sys.implementation.cache_tag to not be '
685n/a 'None')
686n/a def test_source_from_cache(self):
687n/a # Given the path to a PEP 3147 defined .pyc file, return the path to
688n/a # its source. This tests the good path.
689n/a path = os.path.join('foo', 'bar', 'baz', '__pycache__',
690n/a 'qux.{}.pyc'.format(self.tag))
691n/a expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
692n/a self.assertEqual(self.util.source_from_cache(path), expect)
693n/a
694n/a def test_source_from_cache_no_cache_tag(self):
695n/a # If sys.implementation.cache_tag is None, raise NotImplementedError.
696n/a path = os.path.join('blah', '__pycache__', 'whatever.pyc')
697n/a with support.swap_attr(sys.implementation, 'cache_tag', None):
698n/a with self.assertRaises(NotImplementedError):
699n/a self.util.source_from_cache(path)
700n/a
701n/a def test_source_from_cache_bad_path(self):
702n/a # When the path to a pyc file is not in PEP 3147 format, a ValueError
703n/a # is raised.
704n/a self.assertRaises(
705n/a ValueError, self.util.source_from_cache, '/foo/bar/bazqux.pyc')
706n/a
707n/a def test_source_from_cache_no_slash(self):
708n/a # No slashes at all in path -> ValueError
709n/a self.assertRaises(
710n/a ValueError, self.util.source_from_cache, 'foo.cpython-32.pyc')
711n/a
712n/a def test_source_from_cache_too_few_dots(self):
713n/a # Too few dots in final path component -> ValueError
714n/a self.assertRaises(
715n/a ValueError, self.util.source_from_cache, '__pycache__/foo.pyc')
716n/a
717n/a def test_source_from_cache_too_many_dots(self):
718n/a with self.assertRaises(ValueError):
719n/a self.util.source_from_cache(
720n/a '__pycache__/foo.cpython-32.opt-1.foo.pyc')
721n/a
722n/a def test_source_from_cache_not_opt(self):
723n/a # Non-`opt-` path component -> ValueError
724n/a self.assertRaises(
725n/a ValueError, self.util.source_from_cache,
726n/a '__pycache__/foo.cpython-32.foo.pyc')
727n/a
728n/a def test_source_from_cache_no__pycache__(self):
729n/a # Another problem with the path -> ValueError
730n/a self.assertRaises(
731n/a ValueError, self.util.source_from_cache,
732n/a '/foo/bar/foo.cpython-32.foo.pyc')
733n/a
734n/a def test_source_from_cache_optimized_bytecode(self):
735n/a # Optimized bytecode is not an issue.
736n/a path = os.path.join('__pycache__', 'foo.{}.opt-1.pyc'.format(self.tag))
737n/a self.assertEqual(self.util.source_from_cache(path), 'foo.py')
738n/a
739n/a def test_source_from_cache_missing_optimization(self):
740n/a # An empty optimization level is a no-no.
741n/a path = os.path.join('__pycache__', 'foo.{}.opt-.pyc'.format(self.tag))
742n/a with self.assertRaises(ValueError):
743n/a self.util.source_from_cache(path)
744n/a
745n/a @unittest.skipUnless(sys.implementation.cache_tag is not None,
746n/a 'requires sys.implementation.cache_tag to not be '
747n/a 'None')
748n/a def test_source_from_cache_path_like_arg(self):
749n/a path = pathlib.PurePath('foo', 'bar', 'baz', '__pycache__',
750n/a 'qux.{}.pyc'.format(self.tag))
751n/a expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
752n/a self.assertEqual(self.util.source_from_cache(path), expect)
753n/a
754n/a
755n/a(Frozen_PEP3147Tests,
756n/a Source_PEP3147Tests
757n/a ) = util.test_both(PEP3147Tests, util=importlib_util)
758n/a
759n/a
760n/aif __name__ == '__main__':
761n/a unittest.main()