3
3
4
4
machinery = util .import_importlib ('importlib.machinery' )
5
5
6
- import _imp
7
6
import marshal
8
7
import os .path
9
8
import unittest
10
9
import warnings
11
10
12
- from test .support import import_helper , REPO_ROOT
11
+ from test .support import import_helper , REPO_ROOT , STDLIB_DIR
13
12
14
13
15
- def get_frozen_data (name , source = None ):
16
- with import_helper .frozen_modules ():
17
- return _imp .get_frozen_object (name )
14
+ def get_frozen_code (name , source = None , ispkg = False ):
15
+ """Return the code object for the given module.
16
+
17
+ This should match the data stored in the frozen .h file used
18
+ for the module.
19
+
20
+ "source" is the original module name or a .py filename.
21
+ """
22
+ if not source :
23
+ source = name
24
+ else :
25
+ ispkg = source .startswith ('<' ) and source .endswith ('>' )
26
+ if ispkg :
27
+ source = source [1 :- 1 ]
28
+ filename = resolve_filename (source , ispkg )
29
+ origname = name if filename == source else source
30
+ with open (filename ) as infile :
31
+ text = infile .read ()
32
+ return compile (text , f'<frozen { origname } >' , 'exec' )
33
+
34
+
35
+ def resolve_filename (source , ispkg = False ):
36
+ assert source
37
+ if source .endswith ('.py' ):
38
+ return source
39
+ name = source
40
+ if ispkg :
41
+ return os .path .join (STDLIB_DIR , * name .split ('.' ), '__init__.py' )
42
+ else :
43
+ return os .path .join (STDLIB_DIR , * name .split ('.' )) + '.py'
18
44
19
45
20
46
class FindSpecTests (abc .FinderTests ):
@@ -26,49 +52,67 @@ def find(self, name, **kwargs):
26
52
with import_helper .frozen_modules ():
27
53
return finder .find_spec (name , ** kwargs )
28
54
29
- def check (self , spec , name , orig = None ):
55
+ def check_basic (self , spec , name , ispkg = False ):
30
56
self .assertEqual (spec .name , name )
31
57
self .assertIs (spec .loader , self .machinery .FrozenImporter )
32
58
self .assertEqual (spec .origin , 'frozen' )
33
59
self .assertFalse (spec .has_location )
60
+ if ispkg :
61
+ self .assertIsNotNone (spec .submodule_search_locations )
62
+ else :
63
+ self .assertIsNone (spec .submodule_search_locations )
34
64
self .assertIsNotNone (spec .loader_state )
35
65
66
+ def check_search_location (self , spec , source = None ):
67
+ # For now frozen packages do not have any path entries.
68
+ # (See https://bugs.python.org/issue21736.)
69
+ expected = []
70
+ self .assertListEqual (spec .submodule_search_locations , expected )
71
+
36
72
def check_data (self , spec , source = None ):
37
- expected = get_frozen_data (spec .name , source )
73
+ ispkg = spec .submodule_search_locations is not None
74
+ expected = get_frozen_code (spec .name , source , ispkg )
38
75
data , = spec .loader_state
76
+ # We can't compare the marshaled data directly because
77
+ # marshal.dumps() would mark "expected" as a ref, which slightly
78
+ # changes the output. (See https://bugs.python.org/issue34093.)
39
79
code = marshal .loads (data )
40
80
self .assertEqual (code , expected )
41
81
42
82
def test_module (self ):
43
- FROZEN_ONLY = os .path .join (REPO_ROOT , 'Tools' , 'freeze' , 'flag.py' )
44
83
modules = {
45
84
'__hello__' : None ,
46
- '__phello__.__init__' : None ,
85
+ '__phello__.__init__' : '<__phello__>' ,
47
86
'__phello__.spam' : None ,
48
- '__phello__.ham.__init__' : None ,
87
+ '__phello__.ham.__init__' : '<__phello__.ham>' ,
49
88
'__phello__.ham.eggs' : None ,
50
89
'__hello_alias__' : '__hello__' ,
51
- '__hello_only__' : FROZEN_ONLY ,
52
90
}
53
- for name in modules :
91
+ for name , source in modules . items () :
54
92
with self .subTest (name ):
55
93
spec = self .find (name )
56
- self .check (spec , name )
57
- self .assertEqual (spec .submodule_search_locations , None )
58
- self .check_data (spec , modules [name ])
94
+ self .check_basic (spec , name )
95
+ self .check_data (spec , source )
59
96
60
97
def test_package (self ):
61
98
modules = {
62
99
'__phello__' : None ,
63
100
'__phello__.ham' : None ,
64
101
'__phello_alias__' : '__hello__' ,
65
102
}
66
- for name in modules :
103
+ for name , source in modules . items () :
67
104
with self .subTest (name ):
68
105
spec = self .find (name )
69
- self .check (spec , name )
70
- self .assertEqual (spec .submodule_search_locations , [])
71
- self .check_data (spec , modules [name ])
106
+ self .check_basic (spec , name , ispkg = True )
107
+ self .check_search_location (spec , source )
108
+ self .check_data (spec , source )
109
+
110
+ def test_frozen_only (self ):
111
+ name = '__hello_only__'
112
+ source = os .path .join (REPO_ROOT , 'Tools' , 'freeze' , 'flag.py' )
113
+ spec = self .find (name )
114
+ self .check_basic (spec , name )
115
+ self .check_data (spec , source )
72
116
73
117
# These are covered by test_module() and test_package().
74
118
test_module_in_package = None
0 commit comments