Fix defclass construction

Python Class AST expects a body which is a list of ast.Expr. Force
every entry to be stored as a statement. This means we'll preserve
print statements.

Python also doesn't construct docstrings in classes by setting a
__doc__ attribute, it does it by inspecting the first ast.Expr node of
the class. But this means we can remove the special handler for it.
This commit is contained in:
Simon Gomizelj 2018-03-23 10:07:08 -07:00
parent 84e1c65bcd
commit b27cdfed69
3 changed files with 15 additions and 7 deletions

View File

@ -27,6 +27,7 @@ Bug Fixes
------------------------------
* Fix `(return)` so it works correctly to exit a Python 2 generator
* Fixed a case where `->` and `->>` duplicated an argument
* Fixed bugs that caused `defclass` to drop statements or crash
Misc. Improvements
----------------------------

View File

@ -2072,12 +2072,7 @@ class HyASTCompiler(object):
# grab the doc string, if there is one
if expressions and isinstance(expressions[0], HyString):
docstring = expressions.pop(0)
symb = HySymbol("__doc__")
symb.start_line = docstring.start_line
symb.start_column = docstring.start_column
body += self._compile_assign(symb, docstring)
body += body.expr_as_stmt()
body += self.compile(expressions.pop(0)).expr_as_stmt()
if expressions and isinstance(expressions[0], HyList) \
and not isinstance(expressions[0], HyExpression):
@ -2088,7 +2083,8 @@ class HyASTCompiler(object):
body += self.compile(rewire_init(expr))
for expression in expressions:
body += self.compile(rewire_init(macroexpand(expression, self)))
e = self.compile(rewire_init(macroexpand(expression, self)))
body += e + e.expr_as_stmt()
if not body.stmts:
body += asty.Pass(expressions)

View File

@ -127,3 +127,14 @@
(setv b (B))
(assert (= a.x 1))
(assert (= b.x 2)))
(defn test-class-sideeffects []
"NATIVE: test that defclass runs all expressions"
(defn set-sentinel []
(setv set-sentinel.set True))
(setv set-sentinel.set False)
(defclass A []
(set-sentinel))
(assert set-sentinel.set))