Repository: hylang/hy

Issue:
`hy2py` doesn't work for `require` multiple modules
It seems that `hy2py` only generates the last module in `(require ...)`. It might be something wrong within `hy_compile` according to the generated AST.

Example source file `test.hy`:
```hy
(require
 [hy.contrib.loop [loop]]
 [hy.contrib.walk [let]])
```

Run with `hy2py -sa test.hy`:
```
HyExpression([
  HySymbol('do'),
  HyExpression([
    HySymbol('require'),
    HyList([
      HySymbol('hy.contrib.loop'),
      HyList([
        HySymbol('loop')])]),
    HyList([
      HySymbol('hy.contrib.walk'),
      HyList([
        HySymbol('let')])])])])


Module(
    body=[Import(names=[alias(name='hy.macros', asname=None)]),
        Expr(
            value=Call(
                func=Attribute(value=Attribute(value=Name(id='hy'), attr='macros'), attr='require'),
                args=[Str(s='hy.contrib.walk'), Name(id='None')],
                keywords=[
                    keyword(arg='assignments', value=List(elts=[List(elts=[Str(s='let'), Str(s='let')])])),
                    keyword(arg='prefix', value=Str(s=''))]))])


import hy.macros
hy.macros.require('hy.contrib.walk', None, assignments=[['let', 'let']],
    prefix='')
```


Discussion:
It might because `Result.__add__` at [compiler.py#L1207](https://github.com/hylang/hy/blob/master/hy/compiler.py#L1207) (`ret += self.compile(...)`)and [compiler.py#L312](https://github.com/hylang/hy/blob/master/hy/compiler.py#L312) (`result.expr = other.expr`); I printed `Result` before and after parsing the second `require`.

```py
# before adding
Result(imports=[],
       stmts=[],
       expr=Call(func=Attribute(value=Attribute(value=Name(id='hy', ctx=Load()), attr='macros', ctx=Load()), attr='require', ctx=Load()),
                 args=[Str(s='hy.contrib.loop'), Constant(value=None)], 
                 keywords=[keyword(arg='assignments', value=List(elts=[List(elts=[Str(s='loop'), Str(s='loop')], ctx=Load())], ctx=Load())), keyword(arg='prefix', value=Str(s=''))]))

# after adding
Result(imports=[],
       stmts=[],
       expr=Call(func=Attribute(value=Attribute(value=Name(id='hy', ctx=Load()), attr='macros', ctx=Load()), attr='require', ctx=Load()),
                 args=[Str(s='hy.contrib.walk'), Constant(value=None)],
                 keywords=[keyword(arg='assignments', value=List(elts=[List(elts=[Str(s='let'), Str(s='let')], ctx=Load())], ctx=Load())), keyword(arg='prefix', value=Str(s=''))]))
```

Resolving patch:
diff --git a/hy/compiler.py b/hy/compiler.py
--- a/hy/compiler.py
+++ b/hy/compiler.py
@@ -1213,6 +1213,7 @@ def compile_import_or_require(self, expr, root, entries):
                         [[HyString(k), HyString(v)] for k, v in assignments]),
                     HyKeyword('prefix'),
                     HyString(prefix)]).replace(expr))
+                ret += ret.expr_as_stmt()
 
         return ret
 


Test patch:
diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py
--- a/tests/compilers/test_ast.py
+++ b/tests/compilers/test_ast.py
@@ -294,6 +294,17 @@ def test_ast_import_require_dotted():
     cant_compile("(require [spam [foo.bar]])")
 
 
+def test_ast_multi_require():
+    # https://github.com/hylang/hy/issues/1903
+    x = can_compile("""(require
+      [tests.resources.tlib [qplah]]
+      [tests.resources.macros [threadtail-set-cd]])""")
+    assert sum(1 for stmt in x.body if isinstance(stmt, ast.Expr)) == 2
+    dump = ast.dump(x)
+    assert "qplah" in dump
+    assert "threadtail" in dump
+
+
 def test_ast_good_get():
     "Make sure AST can compile valid get"
     can_compile("(get x y)")
@@ -482,7 +493,6 @@ def test_ast_unicode_vs_bytes():
     assert s('b"\\xa0"') == bytes([160])
 
 
-@pytest.mark.skipif(not PY36, reason='f-strings require Python 3.6+')
 def test_format_string():
     assert can_compile('f"hello world"')
     assert can_compile('f"hello {(+ 1 1)} world"')