Skip to content

Commit 93f408a

Browse files
Produce Python AST for require statements
1 parent d2319dc commit 93f408a

12 files changed

+437
-235
lines changed

hy/cmdline.py

+28-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# Copyright 2018 the authors.
22
# This file is part of Hy, which is free software licensed under the Expat
33
# license. See the LICENSE.
4-
5-
from __future__ import print_function
4+
from __future__ import absolute_import, print_function
65

76
import argparse
87
import code
@@ -13,6 +12,7 @@
1312
import importlib
1413
import py_compile
1514
import runpy
15+
import types
1616

1717
import astor.code_gen
1818

@@ -47,10 +47,12 @@ def __call__(self, code=None):
4747
builtins.exit = HyQuitter('exit')
4848

4949

50-
class HyREPL(code.InteractiveConsole):
50+
class HyREPL(code.InteractiveConsole, object):
5151
def __init__(self, spy=False, output_fn=None, locals=None,
5252
filename="<input>"):
5353

54+
super(HyREPL, self).__init__(locals=locals, filename=filename)
55+
5456
self.spy = spy
5557

5658
if output_fn is None:
@@ -65,13 +67,24 @@ def __init__(self, spy=False, output_fn=None, locals=None,
6567
else:
6668
self.output_fn = __builtins__[mangle(output_fn)]
6769

68-
code.InteractiveConsole.__init__(self, locals=locals,
69-
filename=filename)
70-
7170
# Pre-mangle symbols for repl recent results: *1, *2, *3
7271
self._repl_results_symbols = [mangle("*{}".format(i + 1)) for i in range(3)]
7372
self.locals.update({sym: None for sym in self._repl_results_symbols})
7473

74+
# Create a proper module for this REPL so that we can obtain it easily
75+
# (e.g. using `importlib.import_module`), have it be distinct from
76+
# `__main__`, and use it with `hy_compile`.
77+
module_name = self.locals['__name__']
78+
self.module = types.ModuleType(module_name)
79+
self.module.__dict__.update(self.locals)
80+
81+
self.locals = self.module.__dict__
82+
83+
sys.modules[module_name] = self.module
84+
85+
# Load cmdline-specific macros.
86+
require('hy.cmdline', '__console__', assignments='ALL')
87+
7588
def runsource(self, source, filename='<input>', symbol='single'):
7689
global SIMPLE_TRACEBACKS
7790

@@ -102,8 +115,7 @@ def ast_callback(main_ast, expr_ast):
102115
new_ast = ast.Module(main_ast.body +
103116
[ast.Expr(expr_ast.body)])
104117
print(astor.to_source(new_ast))
105-
value = hy_eval(do, self.locals, "__console__",
106-
ast_callback)
118+
value = hy_eval(do, self.locals, self.module, ast_callback)
107119
except HyTypeError as e:
108120
if e.source is None:
109121
e.source = source
@@ -181,7 +193,7 @@ def ideas_macro(ETname):
181193
182194
""")])
183195

184-
require("hy.cmdline", "__console__", assignments="ALL")
196+
185197
require("hy.cmdline", "__main__", assignments="ALL")
186198

187199
SIMPLE_TRACEBACKS = True
@@ -199,7 +211,8 @@ def pretty_error(func, *args, **kw):
199211

200212
def run_command(source):
201213
tree = hy_parse(source)
202-
pretty_error(hy_eval, tree, module_name="__main__")
214+
module = importlib.import_module('__main__')
215+
pretty_error(hy_eval, tree, None, module)
203216
return 0
204217

205218

@@ -208,12 +221,12 @@ def run_repl(hr=None, **kwargs):
208221
sys.ps1 = "=> "
209222
sys.ps2 = "... "
210223

211-
namespace = {'__name__': '__console__', '__doc__': ''}
224+
if not hr:
225+
hr = HyREPL(**kwargs)
212226

213-
with completion(Completer(namespace)):
227+
namespace = hr.locals
214228

215-
if not hr:
216-
hr = HyREPL(locals=namespace, **kwargs)
229+
with completion(Completer(namespace)):
217230

218231
hr.interact("{appname} {version} using "
219232
"{py}({build}) {pyversion} on {os}".format(
@@ -409,7 +422,6 @@ def hyc_main():
409422
# entry point for cmd line script "hy2py"
410423
def hy2py_main():
411424
import platform
412-
module_name = "<STDIN>"
413425

414426
options = dict(prog="hy2py", usage="%(prog)s [options] [FILE]",
415427
formatter_class=argparse.RawDescriptionHelpFormatter)
@@ -448,7 +460,7 @@ def hy2py_main():
448460
print()
449461
print()
450462

451-
_ast = pretty_error(hy_compile, hst, module_name)
463+
_ast = pretty_error(hy_compile, hst, '__main__')
452464
if options.with_ast:
453465
if PY3 and platform.system() == "Windows":
454466
_print_for_windows(astor.dump_tree(_ast))

0 commit comments

Comments
 (0)