Skip to content

Commit 81a3bbc

Browse files
author
James William Pye
committed
Update pythoncommand
1 parent dad283f commit 81a3bbc

1 file changed

Lines changed: 23 additions & 26 deletions

File tree

postgresql/resolved/pythoncommand.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import sys
5050
import re
5151
import code
52+
import types
5253
import optparse
5354
import subprocess
5455
import contextlib
@@ -71,7 +72,7 @@ def get_filename(self, fullpath):
7172

7273
def get_code(self, fullpath):
7374
if fullpath == self.source:
74-
return compile(self.source, '<command>', 'single')
75+
return compile(self.source, '<command>', 'exec')
7576

7677
def get_source(self, fullpath):
7778
if fullpath == self.source:
@@ -307,7 +308,7 @@ def execfile(self, filepath):
307308
src.close()
308309
if co is not None:
309310
try:
310-
exec(co, globals(), self.locals)
311+
exec(co, self.globals, self.locals)
311312
except:
312313
e, v, tb = sys.exc_info()
313314
print_exception(e, v, tb.tb_next or tb)
@@ -390,16 +391,13 @@ def postmortem(funcpath):
390391

391392
class Execution(object):
392393
"""
393-
Given argv, context, locals, environ, make an execution instance that,
394-
when called, will execute the Python configured code.
394+
Given argv and context make an execution instance that, when called, will
395+
execute the configured Python code.
395396
396397
This class provides the ability to identify what the main part of the
397398
execution of the configured Python code. For instance, shall it execute a
398399
console, the file that the first argument points to, a -m option module
399400
appended to the python_context option value, or the code given within -c?
400-
401-
Primarily, it simply identifies what "__main__" is, while providing other
402-
conveniences such as postmortem.
403401
"""
404402
def __init__(self,
405403
args, context = (),
@@ -414,15 +412,14 @@ def __init__(self,
414412
context
415413
A list of loader descriptors that will be used to establish the
416414
context of __main__ module.
417-
locals
418-
The dictionary that will be used for __main__.
419415
main
420416
Overload to explicitly state what main is. None will cause the
421417
class to attempt to fill in the attribute using 'args' and other
422418
system objects like sys.stdin.
423419
"""
424420
self.args = args
425421
self.context = context and list(context) or ()
422+
self.reset_module__main__()
426423

427424
if main is not None:
428425
self.main = main
@@ -458,8 +455,13 @@ class to attempt to fill in the attribute using 'args' and other
458455
# console
459456
self.main = (None, None)
460457

458+
def reset_module__main__(self):
459+
mod = types.ModuleType('__main__')
460+
mod.__package__ = None
461+
mod.__builtins__ = __builtins__
462+
self.module__main__ = mod
463+
461464
def _call(self,
462-
locals = None,
463465
console = ExtendedConsole,
464466
context = None
465467
):
@@ -468,10 +470,8 @@ def _call(self,
468470
(Note: tramples on sys.argv, __main__ in sys.modules)
469471
(Use __call__ instead)
470472
"""
471-
if locals is None:
472-
locals = {}
473-
locals['__name__'] = '__context__'
474-
sys.modules['__context__'] = locals
473+
sys.modules['__main__'] = self.module__main__
474+
md = self.module__main__.__dict__
475475

476476
# Establish execution context in the locals;
477477
# iterate over all the loaders in self.context and
@@ -491,19 +491,17 @@ def _call(self,
491491
except:
492492
print_exception(*sys.exc_info())
493493
return 1
494-
locals['__file__'] = getattr(
494+
self.module__main__.__file__ = getattr(
495495
li, 'get_filename', lambda x: x
496496
)(rpath)
497-
locals['__loader__'] = li
497+
self.module__main__.__loader__ = li
498498
try:
499-
exec(code, globals(), locals)
499+
exec(code, md, md)
500500
except:
501501
e, v, tb = sys.exc_info()
502502
print_exception(e, v, tb.tb_next or tb)
503503
return 1
504504

505-
sys.modules['__main__'] = locals
506-
locals['__name__'] = '__main__'
507505
if self.main == (None, None):
508506
# It's interactive.
509507
sys.argv = self.args or ['<console>']
@@ -514,7 +512,7 @@ def _call(self,
514512
except ImportError:
515513
pass
516514

517-
ic = console(locals = locals)
515+
ic = console(locals = md)
518516
try:
519517
ic.interact()
520518
except SystemExit as e:
@@ -523,11 +521,11 @@ def _call(self,
523521
else:
524522
# It's ultimately a code object.
525523
path, loader = self.main
526-
locals['__file__'] = getattr(
524+
self.module__main__.__file__ = getattr(
527525
loader, 'get_filename', lambda x: x
528526
)(path)
529527
sys.argv = list(self.args)
530-
sys.argv.insert(0, locals['__file__'])
528+
sys.argv.insert(0, self.module__main__.__file__)
531529
try:
532530
code = loader.get_code(path)
533531
except:
@@ -540,13 +538,13 @@ def _call(self,
540538
if context is not None:
541539
with context:
542540
try:
543-
exec(code, globals(), locals)
541+
exec(code, md, md)
544542
except:
545543
exe_exception = True
546544
raise
547545
else:
548546
try:
549-
exec(code, globals(), locals)
547+
exec(code, md, md)
550548
except:
551549
exe_exception = True
552550
raise
@@ -610,9 +608,8 @@ def command_execution(args = sys.argv):
610608
loader = getattr(co, 'python_main', None),
611609
)
612610

613-
def command(args = sys.argv, locals = {}):
611+
def command(args = sys.argv):
614612
return command_execution(args = args)(
615-
locals = locals,
616613
context = postmortem(os.environ.get('PYTHON_POSTMORTEM'))
617614
)
618615

0 commit comments

Comments
 (0)