diff --git a/NEWS.rst b/NEWS.rst index 00103d4..a0a00a9 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -6,6 +6,8 @@ Unreleased Removals ------------------------------ * Python 2 is no longer supported. +* Support for attribute lists in `defclass` has been removed. Use `setv` + and `defn` instead. 0.17.0 ============================== diff --git a/docs/contrib/hy_repr.rst b/docs/contrib/hy_repr.rst index fae2625..4b0bf9a 100644 --- a/docs/contrib/hy_repr.rst +++ b/docs/contrib/hy_repr.rst @@ -67,8 +67,8 @@ your choice to the keyword argument ``:placeholder`` of .. code-block:: hy (defclass Container [object] - [__init__ (fn [self value] - (setv self.value value))]) + (defn __init__ (fn [self value] + (setv self.value value)))) (hy-repr-register Container :placeholder "HY THERE" (fn [x] (+ "(Container " (hy-repr x.value) ")"))) (setv container (Container 5)) diff --git a/docs/language/api.rst b/docs/language/api.rst index 6b243ba..ca967a5 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -430,16 +430,16 @@ Whereas ``setv`` creates an assignment statement, ``setx`` creates an assignment defclass -------- -New classes are declared with ``defclass``. It can take three optional parameters in the following order: -a list defining (a) possible super class(es), a string (:term:`py:docstring`) and another list containing -attributes of the new class along with their corresponding values. +New classes are declared with ``defclass``. It can take optional parameters in the following order: +a list defining (a) possible super class(es) and a string (:term:`py:docstring`). .. code-block:: clj (defclass class-name [super-class-1 super-class-2] "docstring" - [attribute1 value1 - attribute2 value2] + + (setv attribute1 value1) + (setv attribute2 value2) (defn method [self] (print "hello!"))) @@ -449,8 +449,8 @@ below: .. code-block:: clj => (defclass Cat [] - ... [age None - ... colour "white"] + ... (setv age None) + ... (setv colour "white") ... ... (defn speak [self] (print "Meow"))) diff --git a/docs/tutorial.rst b/docs/tutorial.rst index cb2b272..e7dfa44 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -527,9 +527,9 @@ In Hy: .. code-block:: clj (defclass Customer [models.Model] - [name (models.CharField :max-length 255) - address (models.TextField) - notes (models.TextField)]) + (setv name (models.CharField :max-length 255)) + (setv address (models.TextField)) + (setv notes (models.TextField))) Macros ====== diff --git a/hy/compiler.py b/hy/compiler.py index 7638893..27ea786 100755 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1475,10 +1475,9 @@ class HyASTCompiler(object): @special("defclass", [ SYM, - maybe(brackets(many(FORM)) + maybe(STR) + - maybe(brackets(many(SYM + FORM))) + many(FORM))]) + maybe(brackets(many(FORM)) + maybe(STR) + many(FORM))]) def compile_class_expression(self, expr, root, name, rest): - base_list, docstring, attrs, body = rest or ([[]], None, None, []) + base_list, docstring, body = rest or ([[]], None, []) bases_expr, bases, keywords = ( self._compile_collect(base_list[0], with_kwargs=True)) @@ -1488,11 +1487,6 @@ class HyASTCompiler(object): if docstring is not None: bodyr += self.compile(docstring).expr_as_stmt() - if attrs is not None: - bodyr += self.compile(self._rewire_init(HyExpression( - [HySymbol("setv")] + - [x for pair in attrs[0] for x in pair]).replace(attrs))) - for e in body: e = self.compile(self._rewire_init( macroexpand(e, self.module, self))) diff --git a/hy/contrib/multi.hy b/hy/contrib/multi.hy index 7dba654..1a19fc9 100644 --- a/hy/contrib/multi.hy +++ b/hy/contrib/multi.hy @@ -6,11 +6,11 @@ (import [collections [defaultdict]] [hy [HyExpression HyList HyString]]) -(defclass MultiDispatch [object] [ +(defclass MultiDispatch [object] - _fns (defaultdict dict) + (setv _fns (defaultdict dict)) - __init__ (fn [self f] + (defn __init__ [self f] (setv self.f f) (setv self.__doc__ f.__doc__) (unless (in f.__name__ (.keys (get self._fns f.__module__))) @@ -18,14 +18,14 @@ (setv values f.__code__.co_varnames) (setv (get self._fns f.__module__ f.__name__ values) f)) - fn? (fn [self v args kwargs] + (defn fn? [self v args kwargs] "Compare the given (checked fn) to the called fn" (setv com (+ (list args) (list (.keys kwargs)))) (and (= (len com) (len v)) (.issubset (frozenset (.keys kwargs)) com))) - __call__ (fn [self &rest args &kwargs kwargs] + (defn __call__ [self &rest args &kwargs kwargs] (setv func None) (for [[i f] (.items (get self._fns self.f.__module__ self.f.__name__))] (when (.fn? self i args kwargs) @@ -33,7 +33,7 @@ (break))) (if func (func #* args #** kwargs) - (raise (TypeError "No matching functions with this signature"))))]) + (raise (TypeError "No matching functions with this signature"))))) (defn multi-decorator [dispatch-fn] (setv inner (fn [&rest args &kwargs kwargs] diff --git a/hy/contrib/sequences.hy b/hy/contrib/sequences.hy index 94b3236..01226c9 100644 --- a/hy/contrib/sequences.hy +++ b/hy/contrib/sequences.hy @@ -3,53 +3,60 @@ ;; license. See the LICENSE. (defclass Sequence [] - [--init-- (fn [self func] - "initialize a new sequence with a function to compute values" - (setv (. self func) func) - (setv (. self cache) []) - (setv (. self high-water) -1)) - --getitem-- (fn [self n] - "get nth item of sequence" - (if (hasattr n "start") - (gfor x (range n.start n.stop (or n.step 1)) - (get self x)) - (do (when (neg? n) - ; Call (len) to force the whole - ; sequence to be evaluated. - (len self)) - (if (<= n (. self high-water)) - (get (. self cache) n) - (do (while (< (. self high-water) n) - (setv (. self high-water) (inc (. self high-water))) - (.append (. self cache) (.func self (. self high-water)))) - (get self n)))))) - --iter-- (fn [self] - "create iterator for this sequence" - (setv index 0) - (try (while True - (yield (get self index)) - (setv index (inc index))) - (except [IndexError] - (return)))) - --len-- (fn [self] - "length of the sequence, dangerous for infinite sequences" - (setv index (. self high-water)) - (try (while True - (get self index) - (setv index (inc index))) - (except [IndexError] - (len (. self cache))))) - max-items-in-repr 10 - --str-- (fn [self] - "string representation of this sequence" - (setv items (list (take (inc self.max-items-in-repr) self))) - (.format (if (> (len items) self.max-items-in-repr) - "[{0}, ...]" - "[{0}]") - (.join ", " (map str items)))) - --repr-- (fn [self] - "string representation of this sequence" - (.--str-- self))]) + + (defn --init-- [self func] + "initialize a new sequence with a function to compute values" + (setv (. self func) func) + (setv (. self cache) []) + (setv (. self high-water) -1)) + + (defn --getitem-- [self n] + "get nth item of sequence" + (if (hasattr n "start") + (gfor x (range n.start n.stop (or n.step 1)) + (get self x)) + (do (when (neg? n) + ; Call (len) to force the whole + ; sequence to be evaluated. + (len self)) + (if (<= n (. self high-water)) + (get (. self cache) n) + (do (while (< (. self high-water) n) + (setv (. self high-water) (inc (. self high-water))) + (.append (. self cache) (.func self (. self high-water)))) + (get self n)))))) + + (defn --iter-- [self] + "create iterator for this sequence" + (setv index 0) + (try (while True + (yield (get self index)) + (setv index (inc index))) + (except [IndexError] + (return)))) + + (defn --len-- [self] + "length of the sequence, dangerous for infinite sequences" + (setv index (. self high-water)) + (try (while True + (get self index) + (setv index (inc index))) + (except [IndexError] + (len (. self cache))))) + + (setv max-items-in-repr 10) + + (defn --str-- [self] + "string representation of this sequence" + (setv items (list (take (inc self.max-items-in-repr) self))) + (.format (if (> (len items) self.max-items-in-repr) + "[{0}, ...]" + "[{0}]") + (.join ", " (map str items)))) + + (defn --repr-- [self] + "string representation of this sequence" + (.--str-- self))) (defmacro seq [param &rest seq-code] `(Sequence (fn ~param (do ~@seq-code)))) diff --git a/tests/native_tests/contrib/hy_repr.hy b/tests/native_tests/contrib/hy_repr.hy index 4a0a1ec..3fa807a 100644 --- a/tests/native_tests/contrib/hy_repr.hy +++ b/tests/native_tests/contrib/hy_repr.hy @@ -158,8 +158,8 @@ (assert (= (hy-repr (C)) "cuddles")) (defclass Container [object] - [__init__ (fn [self value] - (setv self.value value))]) + (defn __init__ [self value] + (setv self.value value))) (hy-repr-register Container :placeholder "(Container ...)" (fn [x] (+ "(Container " (hy-repr x.value) ")"))) (setv container (Container 5)) @@ -170,5 +170,5 @@ (defn test-hy-repr-fallback [] (defclass D [object] - [__repr__ (fn [self] "cuddles")]) + (defn __repr__ [self] "cuddles")) (assert (= (hy-repr (D)) "cuddles"))) diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index 0618766..eb1b1c3 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -300,7 +300,7 @@ result['y in globals'] = 'y' in globals()") (assert-requires-num inc) (defclass X [object] - [__add__ (fn [self other] (.format "__add__ got {}" other))]) + (defn __add__ [self other] (.format "__add__ got {}" other))) (assert-equal (inc (X)) "__add__ got 1")) (defn test-instance [] diff --git a/tests/native_tests/defclass.hy b/tests/native_tests/defclass.hy index 2563072..e27a20e 100644 --- a/tests/native_tests/defclass.hy +++ b/tests/native_tests/defclass.hy @@ -27,7 +27,7 @@ (defn test-defclass-attrs [] "NATIVE: test defclass attributes" (defclass A [] - [x 42]) + (setv x 42)) (assert (= A.x 42)) (assert (= (getattr (A) "x") 42))) @@ -35,9 +35,9 @@ (defn test-defclass-attrs-fn [] "NATIVE: test defclass attributes with fn" (defclass B [] - [x 42 - y (fn [self value] - (+ self.x value))]) + (setv x 42) + (setv y (fn [self value] + (+ self.x value)))) (assert (= B.x 42)) (assert (= (.y (B) 5) 47)) (setv b (B)) @@ -48,17 +48,17 @@ (defn test-defclass-dynamic-inheritance [] "NATIVE: test defclass with dynamic inheritance" (defclass A [((fn [] (if True list dict)))] - [x 42]) + (setv x 42)) (assert (isinstance (A) list)) (defclass A [((fn [] (if False list dict)))] - [x 42]) + (setv x 42)) (assert (isinstance (A) dict))) (defn test-defclass-no-fn-leak [] "NATIVE: test defclass attributes with fn" (defclass A [] - [x (fn [] 1)]) + (setv x (fn [] 1))) (try (do (x) @@ -68,13 +68,13 @@ (defn test-defclass-docstring [] "NATIVE: test defclass docstring" (defclass A [] - [--doc-- "doc string" - x 1]) + (setv --doc-- "doc string") + (setv x 1)) (setv a (A)) (assert (= a.__doc__ "doc string")) (defclass B [] "doc string" - [x 1]) + (setv x 1)) (setv b (B)) (assert (= b.x 1)) (assert (= b.__doc__ "doc string")) @@ -82,7 +82,7 @@ "begin a very long multi-line string to make sure that it comes out the way we hope and can span 3 lines end." - [x 1]) + (setv x 1)) (setv mL (MultiLine)) (assert (= mL.x 1)) (assert (in "begin" mL.__doc__)) @@ -100,8 +100,8 @@ "NATIVE: test defclass syntax with properties and methods and side-effects" (setv foo 1) (defclass A [] - [x 1 - y 2] + (setv x 1) + (setv y 2) (global foo) (setv foo 2) (defn greet [self] @@ -117,7 +117,7 @@ (defn test-defclass-implicit-none-for-init [] "NATIVE: test that defclass adds an implicit None to --init--" (defclass A [] - [--init-- (fn [self] (setv self.x 1) 42)]) + (setv --init-- (fn [self] (setv self.x 1) 42))) (defclass B [] (defn --init-- [self] (setv self.x 2) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 5593d01..e251840 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -129,8 +129,8 @@ (assert (none? (setv (get {} "x") 42))) (setv l []) (defclass Foo [object] - [__setattr__ (fn [self attr val] - (.append l [attr val]))]) + (defn __setattr__ [self attr val] + (.append l [attr val]))) (setv x (Foo)) (assert (none? (setv x.eggs "ham"))) (assert (not (hasattr x "eggs"))) @@ -443,9 +443,9 @@ (defclass X [object] []) (defclass M [object] - [meth (fn [self &rest args &kwargs kwargs] + (defn meth [self &rest args &kwargs kwargs] (.join " " (+ (, "meth") args - (tuple (map (fn [k] (get kwargs k)) (sorted (.keys kwargs)))))))]) + (tuple (map (fn [k] (get kwargs k)) (sorted (.keys kwargs)))))))) (setv x (X)) (setv m (M)) @@ -1667,7 +1667,7 @@ macros() (defn test-underscore_variables [] ; https://github.com/hylang/hy/issues/1340 (defclass XYZ [] - [_42 6]) + (setv _42 6)) (setv x (XYZ)) (assert (= (. x _42) 6))) @@ -1773,24 +1773,26 @@ macros() (defn test-pep-3115 [] (defclass member-table [dict] - [--init-- (fn [self] (setv self.member-names [])) + (defn --init-- [self] + (setv self.member-names [])) - --setitem-- (fn [self key value] - (if (not-in key self) - (.append self.member-names key)) - (dict.--setitem-- self key value))]) + (defn --setitem-- [self key value] + (if (not-in key self) + (.append self.member-names key)) + (dict.--setitem-- self key value))) (defclass OrderedClass [type] - [--prepare-- (classmethod (fn [metacls name bases] (member-table))) + (setv --prepare-- (classmethod (fn [metacls name bases] + (member-table)))) - --new-- (fn [cls name bases classdict] - (setv result (type.--new-- cls name bases (dict classdict))) - (setv result.member-names classdict.member-names) - result)]) + (defn --new-- [cls name bases classdict] + (setv result (type.--new-- cls name bases (dict classdict))) + (setv result.member-names classdict.member-names) + result)) (defclass MyClass [:metaclass OrderedClass] - [method1 (fn [self] (pass)) - method2 (fn [self] (pass))]) + (defn method1 [self] (pass)) + (defn method2 [self] (pass))) (assert (= (. (MyClass) member-names) ["__module__" "__qualname__" "method1" "method2"]))) diff --git a/tests/native_tests/mathematics.hy b/tests/native_tests/mathematics.hy index 8ad8797..5069644 100644 --- a/tests/native_tests/mathematics.hy +++ b/tests/native_tests/mathematics.hy @@ -34,7 +34,7 @@ "NATIVE: test that unary + calls __pos__" (defclass X [object] - [__pos__ (fn [self] "called __pos__")]) + (defn __pos__ [self] "called __pos__")) (assert (= (+ (X)) "called __pos__")) ; Make sure the shadowed version works, too. @@ -159,21 +159,20 @@ (defclass HyTestMatrix [list] - [--matmul-- - (fn [self other] - (setv n (len self) - m (len (. other [0])) - result []) - (for [i (range m)] - (setv result-row []) - (for [j (range n)] - (setv dot-product 0) - (for [k (range (len (. self [0])))] - (+= dot-product (* (. self [i] [k]) - (. other [k] [j])))) - (.append result-row dot-product)) - (.append result result-row)) - result)]) + (defn --matmul-- [self other] + (setv n (len self) + m (len (. other [0])) + result []) + (for [i (range m)] + (setv result-row []) + (for [j (range n)] + (setv dot-product 0) + (for [k (range (len (. self [0])))] + (+= dot-product (* (. self [i] [k]) + (. other [k] [j])))) + (.append result-row dot-product)) + (.append result result-row)) + result)) (setv first-test-matrix (HyTestMatrix [[1 2 3] [4 5 6] diff --git a/tests/native_tests/operators.hy b/tests/native_tests/operators.hy index 6f2ea4a..7c9b18b 100644 --- a/tests/native_tests/operators.hy +++ b/tests/native_tests/operators.hy @@ -34,7 +34,7 @@ (assert (= (f) 0)) - (defclass C [object] [__pos__ (fn [self] "called __pos__")]) + (defclass C [object] (defn __pos__ [self] "called __pos__")) (assert (= (f (C)) "called __pos__")) (assert (= (f 1 2) 3)) @@ -101,9 +101,9 @@ (op-and-shadow-test @ - (defclass C [object] [ - __init__ (fn [self content] (setv self.content content)) - __matmul__ (fn [self other] (C (+ self.content other.content)))]) + (defclass C [object] + (defn __init__ [self content] (setv self.content content)) + (defn __matmul__ [self other] (C (+ self.content other.content)))) (forbid (f)) (assert (do (setv c (C "a")) (is (f c) c))) (assert (= (. (f (C "b") (C "c")) content) "bc")) @@ -171,11 +171,11 @@ ; Make sure chained comparisons use `and`, not `&`. ; https://github.com/hylang/hy/issues/1191 - (defclass C [object] [ - __init__ (fn [self x] + (defclass C [object] + (defn __init__ [self x] (setv self.x x)) - __lt__ (fn [self other] - self.x)]) + (defn __lt__ [self other] + self.x)) (assert (= (f (C "a") (C "b") (C "c")) "b"))) diff --git a/tests/native_tests/py36_only_tests.hy b/tests/native_tests/py36_only_tests.hy index 40de6d9..3ba0c4f 100644 --- a/tests/native_tests/py36_only_tests.hy +++ b/tests/native_tests/py36_only_tests.hy @@ -40,8 +40,8 @@ (defn test-pep-487 [] (defclass QuestBase [] - [--init-subclass-- (fn [cls swallow &kwargs kwargs] - (setv cls.swallow swallow))]) + (defn --init-subclass-- [cls swallow &kwargs kwargs] + (setv cls.swallow swallow))) (defclass Quest [QuestBase :swallow "african"]) (assert (= (. (Quest) swallow) "african"))) diff --git a/tests/native_tests/with_decorator.hy b/tests/native_tests/with_decorator.hy index 68dd1fc..fa6abc1 100644 --- a/tests/native_tests/with_decorator.hy +++ b/tests/native_tests/with_decorator.hy @@ -27,7 +27,7 @@ cls) (with-decorator bardec (defclass cls [] - [attr1 123])) + (setv attr1 123))) (assert (= cls.attr1 123)) (assert (= cls.attr2 456))) diff --git a/tests/resources/pydemo.hy b/tests/resources/pydemo.hy index e98fb6d..5611177 100644 --- a/tests/resources/pydemo.hy +++ b/tests/resources/pydemo.hy @@ -142,13 +142,13 @@ Call me Ishmael. Some years ago—never mind how long precisely—having little (defclass C2 [C1] "class docstring" - [attr1 5 attr2 6] - (setv attr3 7)) + (setv attr1 5) + (setv attr2 6)) (import [contextlib [closing]]) (setv closed []) (defclass Closeable [] - [close (fn [self] (.append closed self.x))]) + (defn close [self] (.append closed self.x))) (with [c1 (closing (Closeable)) c2 (closing (Closeable))] (setv c1.x "v1") (setv c2.x "v2")) diff --git a/tests/test_hy2py.py b/tests/test_hy2py.py index 6428eef..69edc7e 100644 --- a/tests/test_hy2py.py +++ b/tests/test_hy2py.py @@ -113,7 +113,7 @@ def assert_stuff(m): assert m.C2.__doc__ == "class docstring" assert issubclass(m.C2, m.C1) - assert (m.C2.attr1, m.C2.attr2, m.C2.attr3) == (5, 6, 7) + assert (m.C2.attr1, m.C2.attr2) == (5, 6) assert m.closed == ["v2", "v1"]