Repository: hylang/hy

Issue:
Implicit return in generator when using with
```
=> (defn f [] (with [[f (StringIO)]] (yield (.read f))))
def f():
    with StringIO() as f:
        _hy_anon_var_1 = yield f.read()
    return _hy_anon_var_1
Traceback (most recent call last):
  File "/home/maresp/workbench/cbnxt/venv/lib/python2.7/site-packages/hy/importer.py", line 42, in ast_compile
    return compile(ast, filename, mode, flags)
SyntaxError: 'return' with argument inside generator (<input>, line 1)
```



Discussion:
This looks to be the same issue as #563 and #600.


Resolving patch:
diff --git a/hy/compiler.py b/hy/compiler.py
--- a/hy/compiler.py
+++ b/hy/compiler.py
@@ -1,10 +1,10 @@
 # -*- encoding: utf-8 -*-
 #
-# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
+# Copyright (c) 2013, 2014 Paul Tagliamonte <paultag@debian.org>
 # Copyright (c) 2013 Julien Danjou <julien@danjou.info>
 # Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
 # Copyright (c) 2013 James King <james@agentultra.com>
-# Copyright (c) 2013 Bob Tolbert <bob@tolbert.org>
+# Copyright (c) 2013, 2014 Bob Tolbert <bob@tolbert.org>
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -704,7 +704,8 @@ def compile_try_expression(self, expr):
                              lineno=expr.start_line,
                              col_offset=expr.start_column)
 
-        returnable = Result(expr=expr_name, temp_variables=[expr_name, name])
+        returnable = Result(expr=expr_name, temp_variables=[expr_name, name],
+                            contains_yield=body.contains_yield)
 
         body += ast.Assign(targets=[name],
                            value=body.force_expr,
@@ -996,7 +997,10 @@ def compile_global_expression(self, expr):
     @checkargs(max=1)
     def compile_yield_expression(self, expr):
         expr.pop(0)
-        ret = Result(contains_yield=True)
+        if PY33:
+            ret = Result(contains_yield=False)
+        else:
+            ret = Result(contains_yield=True)
 
         value = None
         if expr != []:


Test patch:
diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy
--- a/tests/native_tests/language.hy
+++ b/tests/native_tests/language.hy
@@ -3,6 +3,7 @@
         [sys :as systest])
 (import sys)
 
+(import [hy._compat [PY33 PY34]])
 
 (defn test-sys-argv []
   "NATIVE: test sys.argv"
@@ -448,6 +449,29 @@
   (for [y (gen)] (setv ret (+ ret y)))
   (assert (= ret 10)))
 
+(defn test-yield-with-return []
+  "NATIVE: test yield with return"
+  (defn gen [] (yield 3) "goodbye")
+  (if PY33
+    (do (setv gg (gen))
+        (assert (= 3 (next gg)))
+        (try (next gg)
+             (except [e StopIteration] (assert (hasattr e "value"))
+                                       (assert (= (getattr e "value") "goodbye")))))
+    (do (setv gg (gen))
+        (assert (= 3 (next gg)))
+        (try (next gg)
+             (except [e StopIteration] (assert (not (hasattr e "value"))))))))
+
+
+(defn test-yield-in-try []
+  "NATIVE: test yield in try"
+  (defn gen []
+    (let [[x 1]]
+    (try (yield x)
+         (finally (print x)))))
+  (setv output (list (gen)))
+  (assert (= [1] output)))
 
 (defn test-first []
   "NATIVE: test firsty things"