Merge pull request #1536 from vodik/fix-defclass

Fix `defclass`
This commit is contained in:
Kodi Arfer 2018-03-31 12:58:32 -07:00 committed by GitHub
commit 39587e6f23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 10 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

@ -20,10 +20,8 @@ import hy.inspect
import traceback
import importlib
import codecs
import ast
import sys
import keyword
import copy
from collections import defaultdict
@ -2038,7 +2036,10 @@ class HyASTCompiler(object):
def compile_class_expression(self, expressions):
def rewire_init(expr):
new_args = []
if expr[0] == HySymbol("setv"):
if (isinstance(expr, HyExpression)
and len(expr) > 1
and isinstance(expr[0], HySymbol)
and expr[0] == HySymbol("setv")):
pairs = expr[1:]
while len(pairs) > 0:
k, v = (pairs.pop(0), pairs.pop(0))
@ -2070,13 +2071,12 @@ class HyASTCompiler(object):
body = Result()
# grab the doc string, if there is one
docstring = None
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()
if not PY37:
body += self.compile(docstring).expr_as_stmt()
docstring = None
if expressions and isinstance(expressions[0], HyList) \
and not isinstance(expressions[0], HyExpression):
@ -2087,7 +2087,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)
@ -2100,7 +2101,8 @@ class HyASTCompiler(object):
starargs=None,
kwargs=None,
bases=bases_expr,
body=body.stmts)
body=body.stmts,
docstring=(None if docstring is None else str_type(docstring)))
@builds("dispatch-tag-macro")
@checkargs(exact=2)

View File

@ -212,6 +212,9 @@ def test_ast_good_defclass():
"Make sure AST can compile valid defclass"
can_compile("(defclass a)")
can_compile("(defclass a [])")
can_compile("(defclass a [] None 42)")
can_compile("(defclass a [] None \"test\")")
can_compile("(defclass a [] None (print \"foo\"))")
@pytest.mark.skipif(not PY3, reason="Python 3 supports class keywords")

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))