commit
39587e6f23
1
NEWS.rst
1
NEWS.rst
@ -27,6 +27,7 @@ Bug Fixes
|
|||||||
------------------------------
|
------------------------------
|
||||||
* Fix `(return)` so it works correctly to exit a Python 2 generator
|
* Fix `(return)` so it works correctly to exit a Python 2 generator
|
||||||
* Fixed a case where `->` and `->>` duplicated an argument
|
* Fixed a case where `->` and `->>` duplicated an argument
|
||||||
|
* Fixed bugs that caused `defclass` to drop statements or crash
|
||||||
|
|
||||||
Misc. Improvements
|
Misc. Improvements
|
||||||
----------------------------
|
----------------------------
|
||||||
|
@ -20,10 +20,8 @@ import hy.inspect
|
|||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
import importlib
|
import importlib
|
||||||
import codecs
|
|
||||||
import ast
|
import ast
|
||||||
import sys
|
import sys
|
||||||
import keyword
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
@ -2038,7 +2036,10 @@ class HyASTCompiler(object):
|
|||||||
def compile_class_expression(self, expressions):
|
def compile_class_expression(self, expressions):
|
||||||
def rewire_init(expr):
|
def rewire_init(expr):
|
||||||
new_args = []
|
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:]
|
pairs = expr[1:]
|
||||||
while len(pairs) > 0:
|
while len(pairs) > 0:
|
||||||
k, v = (pairs.pop(0), pairs.pop(0))
|
k, v = (pairs.pop(0), pairs.pop(0))
|
||||||
@ -2070,13 +2071,12 @@ class HyASTCompiler(object):
|
|||||||
body = Result()
|
body = Result()
|
||||||
|
|
||||||
# grab the doc string, if there is one
|
# grab the doc string, if there is one
|
||||||
|
docstring = None
|
||||||
if expressions and isinstance(expressions[0], HyString):
|
if expressions and isinstance(expressions[0], HyString):
|
||||||
docstring = expressions.pop(0)
|
docstring = expressions.pop(0)
|
||||||
symb = HySymbol("__doc__")
|
if not PY37:
|
||||||
symb.start_line = docstring.start_line
|
body += self.compile(docstring).expr_as_stmt()
|
||||||
symb.start_column = docstring.start_column
|
docstring = None
|
||||||
body += self._compile_assign(symb, docstring)
|
|
||||||
body += body.expr_as_stmt()
|
|
||||||
|
|
||||||
if expressions and isinstance(expressions[0], HyList) \
|
if expressions and isinstance(expressions[0], HyList) \
|
||||||
and not isinstance(expressions[0], HyExpression):
|
and not isinstance(expressions[0], HyExpression):
|
||||||
@ -2087,7 +2087,8 @@ class HyASTCompiler(object):
|
|||||||
body += self.compile(rewire_init(expr))
|
body += self.compile(rewire_init(expr))
|
||||||
|
|
||||||
for expression in expressions:
|
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:
|
if not body.stmts:
|
||||||
body += asty.Pass(expressions)
|
body += asty.Pass(expressions)
|
||||||
@ -2100,7 +2101,8 @@ class HyASTCompiler(object):
|
|||||||
starargs=None,
|
starargs=None,
|
||||||
kwargs=None,
|
kwargs=None,
|
||||||
bases=bases_expr,
|
bases=bases_expr,
|
||||||
body=body.stmts)
|
body=body.stmts,
|
||||||
|
docstring=(None if docstring is None else str_type(docstring)))
|
||||||
|
|
||||||
@builds("dispatch-tag-macro")
|
@builds("dispatch-tag-macro")
|
||||||
@checkargs(exact=2)
|
@checkargs(exact=2)
|
||||||
|
@ -212,6 +212,9 @@ def test_ast_good_defclass():
|
|||||||
"Make sure AST can compile valid defclass"
|
"Make sure AST can compile valid defclass"
|
||||||
can_compile("(defclass a)")
|
can_compile("(defclass a)")
|
||||||
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")
|
@pytest.mark.skipif(not PY3, reason="Python 3 supports class keywords")
|
||||||
|
@ -127,3 +127,14 @@
|
|||||||
(setv b (B))
|
(setv b (B))
|
||||||
(assert (= a.x 1))
|
(assert (= a.x 1))
|
||||||
(assert (= b.x 2)))
|
(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))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user