blob: 02679eff936fe6eeb5c3759c736c153fd36ac394 [file] [log] [blame]
Brett Cannon23cbd8a2009-01-18 00:24:28 +00001"""PEP 366 ("Main module explicit relative imports") specifies the
2semantics for the __package__ attribute on modules. This attribute is
3used, when available, to detect which package a module belongs to (instead
4of using the typical __path__/__name__ test).
5
6"""
7import unittest
Brett Cannonbcb26c52009-02-01 04:00:05 +00008from .. import util
Brett Cannond720b362009-02-01 04:28:04 +00009from . import util as import_util
Brett Cannon23cbd8a2009-01-18 00:24:28 +000010
11
12class Using__package__(unittest.TestCase):
13
14 """Use of __package__ supercedes the use of __name__/__path__ to calculate
15 what package a module belongs to. The basic algorithm is [__package__]::
16
17 def resolve_name(name, package, level):
18 level -= 1
19 base = package.rsplit('.', level)[0]
20 return '{0}.{1}'.format(base, name)
21
Brett Cannonde4ebfe2009-08-30 19:53:48 +000022 But since there is no guarantee that __package__ has been set (or not been
23 set to None [None]), there has to be a way to calculate the attribute's value
24 [__name__]::
Brett Cannon23cbd8a2009-01-18 00:24:28 +000025
26 def calc_package(caller_name, has___path__):
27 if has__path__:
28 return caller_name
29 else:
30 return caller_name.rsplit('.', 1)[0]
31
32 Then the normal algorithm for relative name imports can proceed as if
33 __package__ had been set.
34
35 """
36
37 def test_using___package__(self):
38 # [__package__]
Brett Cannonbcb26c52009-02-01 04:00:05 +000039 with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
40 with util.import_state(meta_path=[importer]):
Brett Cannond720b362009-02-01 04:28:04 +000041 import_util.import_('pkg.fake')
Brett Cannon2c318a12009-02-07 01:15:27 +000042 module = import_util.import_('',
43 globals={'__package__': 'pkg.fake'},
44 fromlist=['attr'], level=2)
Brett Cannon23cbd8a2009-01-18 00:24:28 +000045 self.assertEquals(module.__name__, 'pkg')
46
Brett Cannonde4ebfe2009-08-30 19:53:48 +000047 def test_using___name__(self, package_as_None=False):
Brett Cannon23cbd8a2009-01-18 00:24:28 +000048 # [__name__]
Brett Cannonde4ebfe2009-08-30 19:53:48 +000049 globals_ = {'__name__': 'pkg.fake', '__path__': []}
50 if package_as_None:
51 globals_['__package__'] = None
Brett Cannonbcb26c52009-02-01 04:00:05 +000052 with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
53 with util.import_state(meta_path=[importer]):
Brett Cannond720b362009-02-01 04:28:04 +000054 import_util.import_('pkg.fake')
Brett Cannonde4ebfe2009-08-30 19:53:48 +000055 module = import_util.import_('', globals= globals_,
56 fromlist=['attr'], level=2)
Brett Cannon23cbd8a2009-01-18 00:24:28 +000057 self.assertEquals(module.__name__, 'pkg')
58
Brett Cannonde4ebfe2009-08-30 19:53:48 +000059 def test_None_as___package__(self):
60 # [None]
61 self.test_using___name__(package_as_None=True)
62
Brett Cannon23cbd8a2009-01-18 00:24:28 +000063 def test_bad__package__(self):
64 globals = {'__package__': '<not real>'}
Brett Cannonc5951fc2009-08-27 23:46:38 +000065 with self.assertRaises(SystemError):
66 import_util.import_('', globals, {}, ['relimport'], 1)
Brett Cannon23cbd8a2009-01-18 00:24:28 +000067
68 def test_bunk__package__(self):
69 globals = {'__package__': 42}
Brett Cannonc5951fc2009-08-27 23:46:38 +000070 with self.assertRaises(ValueError):
71 import_util.import_('', globals, {}, ['relimport'], 1)
Brett Cannon23cbd8a2009-01-18 00:24:28 +000072
73
Brett Cannonc5951fc2009-08-27 23:46:38 +000074@import_util.importlib_only
Brett Cannon23cbd8a2009-01-18 00:24:28 +000075class Setting__package__(unittest.TestCase):
76
77 """Because __package__ is a new feature, it is not always set by a loader.
78 Import will set it as needed to help with the transition to relying on
79 __package__.
80
81 For a top-level module, __package__ is set to None [top-level]. For a
82 package __name__ is used for __package__ [package]. For submodules the
83 value is __name__.rsplit('.', 1)[0] [submodule].
84
85 """
86
87 # [top-level]
88 def test_top_level(self):
Brett Cannonbcb26c52009-02-01 04:00:05 +000089 with util.mock_modules('top_level') as mock:
90 with util.import_state(meta_path=[mock]):
Brett Cannon23cbd8a2009-01-18 00:24:28 +000091 del mock['top_level'].__package__
Brett Cannond720b362009-02-01 04:28:04 +000092 module = import_util.import_('top_level')
Brett Cannon2c318a12009-02-07 01:15:27 +000093 self.assertEqual(module.__package__, '')
Brett Cannon23cbd8a2009-01-18 00:24:28 +000094
95 # [package]
96 def test_package(self):
Brett Cannonbcb26c52009-02-01 04:00:05 +000097 with util.mock_modules('pkg.__init__') as mock:
98 with util.import_state(meta_path=[mock]):
Brett Cannon23cbd8a2009-01-18 00:24:28 +000099 del mock['pkg'].__package__
Brett Cannond720b362009-02-01 04:28:04 +0000100 module = import_util.import_('pkg')
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000101 self.assertEqual(module.__package__, 'pkg')
102
103 # [submodule]
104 def test_submodule(self):
Brett Cannonbcb26c52009-02-01 04:00:05 +0000105 with util.mock_modules('pkg.__init__', 'pkg.mod') as mock:
106 with util.import_state(meta_path=[mock]):
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000107 del mock['pkg.mod'].__package__
Brett Cannond720b362009-02-01 04:28:04 +0000108 pkg = import_util.import_('pkg.mod')
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000109 module = getattr(pkg, 'mod')
110 self.assertEqual(module.__package__, 'pkg')
111
112
113def test_main():
114 from test.support import run_unittest
115 run_unittest(Using__package__, Setting__package__)
116
117
118if __name__ == '__main__':
119 test_main()