@@ -98,13 +98,25 @@ def run(self, cmd):
9898 return self .runctx (cmd , dict , dict )
9999
100100 def runctx (self , cmd , globals , locals ):
101+ # cmd has to run in __main__ namespace (or imports from __main__ will
102+ # break). Clear __main__ and replace with the globals provided.
103+ import __main__
104+ # Save a reference to the current __main__ namespace so that we can
105+ # restore it after cmd completes.
106+ original_main = __main__ .__dict__ .copy ()
107+ __main__ .__dict__ .clear ()
108+ __main__ .__dict__ .update (globals )
109+
101110 self .enable ()
102111 try :
103- exec (cmd , globals , locals )
112+ exec (cmd , __main__ . __dict__ , locals )
104113 finally :
105114 self .disable ()
115+ __main__ .__dict__ .clear ()
116+ __main__ .__dict__ .update (original_main )
106117 return self
107118
119+
108120 # This method is more useful to profile a single function call.
109121 def runcall (self , func , / , * args , ** kw ):
110122 self .enable ()
@@ -170,22 +182,19 @@ def main():
170182 else :
171183 progname = args [0 ]
172184 sys .path .insert (0 , os .path .dirname (progname ))
185+ with io .open_code (progname ) as fp :
186+ code = compile (fp .read (), progname , 'exec' )
173187 spec = importlib .machinery .ModuleSpec (name = '__main__' , loader = None ,
174188 origin = progname )
175- loader = importlib .machinery .SourceFileLoader ("__main__" , progname )
176- spec .loader = loader
177- module = importlib .util .module_from_spec (spec )
178189 globs = {
179190 '__spec__' : spec ,
180191 '__file__' : spec .origin ,
181192 '__name__' : spec .name ,
182193 '__package__' : None ,
183194 '__cached__' : None ,
184- 'module ' : module
195+ '__builtins__ ' : __builtins__ ,
185196 }
186197
187- sys .modules ["__main__" ] = module
188- code = "__spec__.loader.exec_module(module)"
189198 try :
190199 runctx (code , globs , None , options .outfile , options .sort )
191200 except BrokenPipeError as exc :
0 commit comments