33
44machinery = util .import_importlib ('importlib.machinery' )
55
6- import _imp
76import marshal
87import os .path
98import unittest
109import warnings
1110
12- from test .support import import_helper , REPO_ROOT
11+ from test .support import import_helper , REPO_ROOT , STDLIB_DIR
1312
1413
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'
1844
1945
2046class FindSpecTests (abc .FinderTests ):
@@ -26,49 +52,67 @@ def find(self, name, **kwargs):
2652 with import_helper .frozen_modules ():
2753 return finder .find_spec (name , ** kwargs )
2854
29- def check (self , spec , name , orig = None ):
55+ def check_basic (self , spec , name , ispkg = False ):
3056 self .assertEqual (spec .name , name )
3157 self .assertIs (spec .loader , self .machinery .FrozenImporter )
3258 self .assertEqual (spec .origin , 'frozen' )
3359 self .assertFalse (spec .has_location )
60+ if ispkg :
61+ self .assertIsNotNone (spec .submodule_search_locations )
62+ else :
63+ self .assertIsNone (spec .submodule_search_locations )
3464 self .assertIsNotNone (spec .loader_state )
3565
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+
3672 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 )
3875 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.)
3979 code = marshal .loads (data )
4080 self .assertEqual (code , expected )
4181
4282 def test_module (self ):
43- FROZEN_ONLY = os .path .join (REPO_ROOT , 'Tools' , 'freeze' , 'flag.py' )
4483 modules = {
4584 '__hello__' : None ,
46- '__phello__.__init__' : None ,
85+ '__phello__.__init__' : '<__phello__>' ,
4786 '__phello__.spam' : None ,
48- '__phello__.ham.__init__' : None ,
87+ '__phello__.ham.__init__' : '<__phello__.ham>' ,
4988 '__phello__.ham.eggs' : None ,
5089 '__hello_alias__' : '__hello__' ,
51- '__hello_only__' : FROZEN_ONLY ,
5290 }
53- for name in modules :
91+ for name , source in modules . items () :
5492 with self .subTest (name ):
5593 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 )
5996
6097 def test_package (self ):
6198 modules = {
6299 '__phello__' : None ,
63100 '__phello__.ham' : None ,
64101 '__phello_alias__' : '__hello__' ,
65102 }
66- for name in modules :
103+ for name , source in modules . items () :
67104 with self .subTest (name ):
68105 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 )
72116
73117 # These are covered by test_module() and test_package().
74118 test_module_in_package = None
0 commit comments