Merge pull request #1580 from Kodiologist/nocons

Burninate HyCons
This commit is contained in:
Kodi Arfer 2018-04-12 16:59:15 -07:00 committed by GitHub
commit cef105edcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 21 additions and 455 deletions

View File

@ -3,6 +3,12 @@
Unreleased Unreleased
============================== ==============================
Removals
------------------------------
* Dotted lists, `HyCons`, `cons`, `cons?`, and `list*` have been removed.
These were redundant with Python's built-in data structures and Hy's most
common model types (`HyExpression`, `HyList`, etc.).
Other Breaking Changes Other Breaking Changes
------------------------------ ------------------------------
* Mangling rules have been overhauled, such that mangled names * Mangling rules have been overhauled, such that mangled names

View File

@ -98,49 +98,6 @@ inverted. So, ``((complement f) x)`` is equivalent to ``(not (f x))``.
True True
cons
----
.. versionadded:: 0.10.0
Usage: ``(cons a b)``
Returns a fresh :ref:`cons cell <hycons>` with car *a* and cdr *b*.
.. code-block:: hy
=> (setv a (cons 'hd 'tl))
=> (= 'hd (get a 0))
True
=> (= 'tl (cut a 1))
True
cons?
-----
.. versionadded:: 0.10.0
Usage: ``(cons? foo)``
Checks whether *foo* is a :ref:`cons cell <hycons>`.
.. code-block:: hy
=> (setv a (cons 'hd 'tl))
=> (cons? a)
True
=> (cons? None)
False
=> (cons? [1 2 3])
False
.. _constantly: .. _constantly:
constantly constantly
@ -606,41 +563,6 @@ Check whether *foo* is a :ref:`keyword<HyKeyword>`.
=> (keyword? foo) => (keyword? foo)
False False
.. _list*-fn:
list*
-----
Usage: ``(list* head &rest tail)``
Generates a chain of nested cons cells (a dotted list) containing the
arguments. If the argument list only has one element, return it.
.. code-block:: hy
=> (list* 1 2 3 4)
<HyCons (
HyInteger(1)
HyInteger(2)
HyInteger(3)
. HyInteger(4))>
=> (list* 1 2 3 [4])
[HyInteger(1), HyInteger(2), HyInteger(3), 4]
=> (list* 1)
1
=> (cons? (list* 1 2 3 4))
True
=> (list* 1 10 2 20 '{})
HyDict([
HyInteger(1), HyInteger(10),
HyInteger(2), HyInteger(20)])
=> (list* 1 10 2 20 {})
<HyCons (
HyInteger(1)
HyInteger(10)
HyInteger(2)
HyInteger(20)
. HyDict())>
.. _macroexpand-fn: .. _macroexpand-fn:

View File

@ -168,39 +168,6 @@ HyKeyword
``hy.models.HyKeyword`` represents keywords in Hy. Keywords are ``hy.models.HyKeyword`` represents keywords in Hy. Keywords are
symbols starting with a ``:``. See :ref:`syntax-keywords`. symbols starting with a ``:``. See :ref:`syntax-keywords`.
.. _hycons:
Cons Cells
==========
``hy.models.HyCons`` is a representation of Python-friendly `cons
cells`_. Cons cells are especially useful to mimic features of "usual"
LISP variants such as Scheme or Common Lisp.
.. _cons cells: https://en.wikipedia.org/wiki/Cons
A cons cell is a 2-item object, containing a ``car`` (head) and a
``cdr`` (tail). In some Lisp variants, the cons cell is the fundamental
building block, and S-expressions are actually represented as linked
lists of cons cells. This is not the case in Hy, as the usual
expressions are made of Python lists wrapped in a
``HyExpression``. However, the ``HyCons`` mimics the behavior of
"usual" Lisp variants thusly:
- ``(cons something None)`` is ``(HyExpression [something])``
- ``(cons something some-list)`` is ``((type some-list) (+ [something]
some-list))`` (if ``some-list`` inherits from ``list``).
- ``(get (cons a b) 0)`` is ``a``
- ``(cut (cons a b) 1)`` is ``b``
Hy supports a dotted-list syntax, where ``'(a . b)`` means ``(cons 'a
'b)`` and ``'(a b . c)`` means ``(cons 'a (cons 'b 'c))``. If the
compiler encounters a cons cell at the top level, it raises a
compilation error.
``HyCons`` wraps the passed arguments (car and cdr) in Hy types, to ease
the manipulation of cons cells in a macro context.
Hy Internal Theory Hy Internal Theory
================== ==================

View File

@ -5,7 +5,7 @@ except ImportError:
__version__ = 'unknown' __version__ = 'unknown'
from hy.models import HyExpression, HyInteger, HyKeyword, HyComplex, HyString, HyBytes, HySymbol, HyFloat, HyDict, HyList, HySet, HyCons # NOQA from hy.models import HyExpression, HyInteger, HyKeyword, HyComplex, HyString, HyBytes, HySymbol, HyFloat, HyDict, HyList, HySet # NOQA
import hy.importer # NOQA import hy.importer # NOQA

View File

@ -5,7 +5,7 @@
from hy.models import (HyObject, HyExpression, HyKeyword, HyInteger, HyComplex, from hy.models import (HyObject, HyExpression, HyKeyword, HyInteger, HyComplex,
HyString, HyBytes, HySymbol, HyFloat, HyList, HySet, HyString, HyBytes, HySymbol, HyFloat, HyList, HySet,
HyDict, HyCons, wrap_value) HyDict, wrap_value)
from hy.errors import HyCompileError, HyTypeError from hy.errors import HyCompileError, HyTypeError
from hy.lex.parser import mangle from hy.lex.parser import mangle
@ -89,7 +89,7 @@ def builds(*types, **kwargs):
def spoof_positions(obj): def spoof_positions(obj):
if not isinstance(obj, HyObject) or isinstance(obj, HyCons): if not isinstance(obj, HyObject):
return return
if not hasattr(obj, "start_column"): if not hasattr(obj, "start_column"):
obj.start_column = 0 obj.start_column = 0
@ -719,24 +719,6 @@ class HyASTCompiler(object):
return imports, HyExpression([HySymbol(name), return imports, HyExpression([HySymbol(name),
contents]).replace(form), False contents]).replace(form), False
elif isinstance(form, HyCons):
ret = HyExpression([HySymbol(name)])
nimport, contents, splice = self._render_quoted_form(form.car,
level)
if splice:
raise HyTypeError(form, "Can't splice dotted lists yet")
imports.update(nimport)
ret.append(contents)
nimport, contents, splice = self._render_quoted_form(form.cdr,
level)
if splice:
raise HyTypeError(form, "Can't splice the cdr of a cons")
imports.update(nimport)
ret.append(contents)
return imports, ret.replace(form), False
elif isinstance(form, HySymbol): elif isinstance(form, HySymbol):
return imports, HyExpression([HySymbol(name), return imports, HyExpression([HySymbol(name),
HyString(form)]).replace(form), False HyString(form)]).replace(form), False
@ -2131,10 +2113,6 @@ class HyASTCompiler(object):
if building == "eval_and_compile" if building == "eval_and_compile"
else Result()) else Result())
@builds(HyCons)
def compile_cons(self, cons):
raise HyTypeError(cons, "Can't compile a top-level cons cell")
@builds(HyInteger, HyFloat, HyComplex) @builds(HyInteger, HyFloat, HyComplex)
def compile_numeric_literal(self, x, building): def compile_numeric_literal(self, x, building):
f = {HyInteger: long_type, f = {HyInteger: long_type,

View File

@ -18,9 +18,6 @@
(outer (HyExpression (map inner form)))] (outer (HyExpression (map inner form)))]
[(instance? HyDict form) [(instance? HyDict form)
(HyDict (outer (HyExpression (map inner form))))] (HyDict (outer (HyExpression (map inner form))))]
[(cons? form)
(outer (cons (inner (first form))
(inner (rest form))))]
[(instance? list form) [(instance? list form)
((type form) (outer (HyExpression (map inner form))))] ((type form) (outer (HyExpression (map inner form))))]
[(coll? form) [(coll? form)

View File

@ -18,7 +18,7 @@
(if-python2 (if-python2
(import [collections :as cabc]) (import [collections :as cabc])
(import [collections.abc :as cabc])) (import [collections.abc :as cabc]))
(import [hy.models [HyCons HySymbol HyKeyword]]) (import [hy.models [HySymbol HyKeyword]])
(import [hy.lex [LexException PrematureEndOfInput tokenize]]) (import [hy.lex [LexException PrematureEndOfInput tokenize]])
(import [hy.lex.parser [mangle unmangle]]) (import [hy.lex.parser [mangle unmangle]])
(import [hy.compiler [HyASTCompiler spoof-positions]]) (import [hy.compiler [HyASTCompiler spoof-positions]])
@ -50,14 +50,6 @@
(fn [&rest args &kwargs kwargs] (fn [&rest args &kwargs kwargs]
(not (f #* args #** kwargs)))) (not (f #* args #** kwargs))))
(defn cons [a b]
"Return a fresh cons cell with car = `a` and cdr = `b`."
(HyCons a b))
(defn cons? [c]
"Check whether `c` is a cons cell."
(instance? HyCons c))
(defn constantly [value] (defn constantly [value]
"Create a new function that always returns `value` regardless of its input." "Create a new function that always returns `value` regardless of its input."
(fn [&rest args &kwargs kwargs] (fn [&rest args &kwargs kwargs]
@ -294,7 +286,7 @@ Return series of accumulated sums (or other binary function results)."
(defn juxt [f &rest fs] (defn juxt [f &rest fs]
"Return a function applying each `fs` to args, collecting results in a list." "Return a function applying each `fs` to args, collecting results in a list."
(setv fs (cons f fs)) (setv fs (+ (, f) fs))
(fn [&rest args &kwargs kwargs] (fn [&rest args &kwargs kwargs]
(list-comp (f #* args #** kwargs) [f fs]))) (list-comp (f #* args #** kwargs) [f fs])))
@ -302,12 +294,6 @@ Return series of accumulated sums (or other binary function results)."
"Return last item from `coll`." "Return last item from `coll`."
(get (tuple coll) -1)) (get (tuple coll) -1))
(defn list* [hd &rest tl]
"Return a chain of nested cons cells (dotted list) containing `hd` and `tl`."
(if (not tl)
hd
(cons hd (list* #* tl))))
(defn macroexpand [form] (defn macroexpand [form]
"Return the full macro expansion of `form`." "Return the full macro expansion of `form`."
(import hy.macros) (import hy.macros)
@ -488,11 +474,11 @@ Even objects with the __name__ magic will work."
(setv EXPORTS (setv EXPORTS
'[*map accumulate butlast calling-module-name chain coll? combinations '[*map accumulate butlast calling-module-name chain coll? combinations
comp complement compress cons cons? constantly count cycle dec distinct comp complement compress constantly count cycle dec distinct
disassemble drop drop-last drop-while empty? eval even? every? exec first disassemble drop drop-last drop-while empty? eval even? every? exec first
filter flatten float? fraction gensym group-by identity inc input instance? filter flatten float? fraction gensym group-by identity inc input instance?
integer integer? integer-char? interleave interpose islice iterable? integer integer? integer-char? interleave interpose islice iterable?
iterate iterator? juxt keyword keyword? last list* macroexpand iterate iterator? juxt keyword keyword? last macroexpand
macroexpand-1 mangle map merge-with multicombinations name neg? none? nth macroexpand-1 mangle map merge-with multicombinations name neg? none? nth
numeric? odd? partition permutations pos? product range read read-str numeric? odd? partition permutations pos? product range read read-str
remove repeat repeatedly rest reduce second some string string? symbol? remove repeat repeatedly rest reduce second some string string? symbol?

View File

@ -11,9 +11,8 @@ import string, re, unicodedata
from rply import ParserGenerator from rply import ParserGenerator
from hy._compat import PY3, str_type, isidentifier, UCS4 from hy._compat import PY3, str_type, isidentifier, UCS4
from hy.models import (HyBytes, HyComplex, HyCons, HyDict, HyExpression, from hy.models import (HyBytes, HyComplex, HyDict, HyExpression, HyFloat,
HyFloat, HyInteger, HyKeyword, HyList, HySet, HyString, HyInteger, HyKeyword, HyList, HySet, HyString, HySymbol)
HySymbol)
from .lexer import lexer from .lexer import lexer
from .exceptions import LexException, PrematureEndOfInput from .exceptions import LexException, PrematureEndOfInput
@ -151,28 +150,6 @@ def reject_spurious_dots(*items):
@pg.production("paren : LPAREN list_contents RPAREN") @pg.production("paren : LPAREN list_contents RPAREN")
@set_boundaries @set_boundaries
def paren(p): def paren(p):
cont = p[1]
# Dotted lists are expressions of the form
# (a b c . d)
# that evaluate to nested cons cells of the form
# (a . (b . (c . d)))
if len(cont) >= 3 and isinstance(cont[-2], HySymbol) and cont[-2] == ".":
reject_spurious_dots(cont[:-2], cont[-1:])
if len(cont) == 3:
# Two-item dotted list: return the cons cell directly
return HyCons(cont[0], cont[2])
else:
# Return a nested cons cell
return HyCons(cont[0], paren([p[0], cont[1:], p[2]]))
# Warn preemptively on a malformed dotted list.
# Only check for dots after the first item to allow for a potential
# attribute accessor shorthand
reject_spurious_dots(cont[1:])
return HyExpression(p[1]) return HyExpression(p[1])

View File

@ -334,101 +334,3 @@ class HySet(HyList):
color = staticmethod(colored.red) color = staticmethod(colored.red)
_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s) _wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)
class HyCons(HyObject):
"""
HyCons: a cons object.
Building a HyCons of something and a HyList really builds a HyList
"""
__slots__ = ["car", "cdr"]
def __new__(cls, car, cdr):
if isinstance(cdr, list):
# Keep unquotes in the cdr of conses
if type(cdr) == HyExpression:
if len(cdr) > 0 and type(cdr[0]) == HySymbol:
if cdr[0] in ("unquote", "unquote-splice"):
return super(HyCons, cls).__new__(cls)
return cdr.__class__([wrap_value(car)] + cdr)
elif cdr is None:
return HyExpression([wrap_value(car)])
else:
return super(HyCons, cls).__new__(cls)
def __init__(self, car, cdr):
self.car = wrap_value(car)
self.cdr = wrap_value(cdr)
def __getitem__(self, n):
if n == 0:
return self.car
if n == slice(1, None):
return self.cdr
raise IndexError(
"Can only get the car ([0]) or the cdr ([1:]) of a HyCons")
def __setitem__(self, n, new):
if n == 0:
self.car = new
return
if n == slice(1, None):
self.cdr = new
return
raise IndexError(
"Can only set the car ([0]) or the cdr ([1:]) of a HyCons")
def __iter__(self):
yield self.car
try:
iterator = (i for i in self.cdr)
except TypeError:
if self.cdr is not None:
yield self.cdr
raise TypeError("Iteration on malformed cons")
else:
for i in iterator:
yield i
def replace(self, other):
if self.car is not None:
replace_hy_obj(self.car, other)
if self.cdr is not None:
replace_hy_obj(self.cdr, other)
HyObject.replace(self, other)
def __repr__(self):
if PRETTY:
return str(self)
else:
return "HyCons({}, {})".format(
repr(self.car), repr(self.cdr))
def __str__(self):
with pretty():
c = colored.yellow
lines = ['' + c("<HyCons (")]
while True:
lines.append(" " + repr_indent(self.car))
if not isinstance(self.cdr, HyCons):
break
self = self.cdr
lines.append("{} {}{}".format(
c("."), repr_indent(self.cdr), c(")>")))
return '\n'.join(lines)
def __eq__(self, other):
return (
isinstance(other, self.__class__) and
self.car == other.car and
self.cdr == other.cdr
)

View File

@ -569,11 +569,6 @@ def test_attribute_empty():
cant_compile('[2].foo') cant_compile('[2].foo')
def test_cons_correct():
"""Ensure cons gets compiled correctly"""
can_compile("(cons a b)")
def test_invalid_list_comprehension(): def test_invalid_list_comprehension():
"""Ensure that invalid list comprehensions do not break the compiler""" """Ensure that invalid list comprehensions do not break the compiler"""
cant_compile("(genexpr x [])") cant_compile("(genexpr x [])")

View File

@ -1,71 +0,0 @@
;; Copyright 2018 the authors.
;; This file is part of Hy, which is free software licensed under the Expat
;; license. See the LICENSE.
(defmacro car [x] `(get ~x 0))
(defmacro cdr [x] `(cut ~x 1))
(defn test-cons-mutability []
"Test the mutability of conses"
(setv tree (cons (cons 1 2) (cons 2 3)))
(setv (car tree) "foo")
(assert (= tree (cons "foo" (cons 2 3))))
(setv (cdr tree) "bar")
(assert (= tree (cons "foo" "bar"))))
(defn test-cons-quoting []
"Test quoting of conses"
(assert (= (cons 1 2) (quote (1 . 2))))
(assert (= (quote foo) (car (quote (foo . bar)))))
(assert (= (quote bar) (cdr (quote (foo . bar))))))
(defn test-cons-behavior []
"NATIVE: test the behavior of cons is consistent"
(defn t= [a b]
(and (= a b) (= (type a) (type b))))
(assert (t= (cons 1 2) '(1 . 2)))
(assert (t= (cons 1 None) '(1)))
(assert (t= (cons None 2) '(None . 2)))
(assert (t= (cons 1 []) [1]))
(setv tree (cons (cons 1 2) (cons 2 3)))
(assert (t= (car tree) (cons 1 2)))
(assert (t= (cdr tree) (cons 2 3))))
(defn test-cons-iteration []
"NATIVE: test the iteration behavior of cons"
(setv x '(0 1 2 3 4 . 5))
(setv it (iter x))
(for* [i (range 6)]
(assert (= i (next it))))
(assert
(= 'success
(try
(do
(next it)
'failurenext)
(except [e TypeError] (if (= e.args (, "Iteration on malformed cons"))
'success
'failureexc))
(except [e Exception] 'failureexc2)))))
(defn test-cons? []
"NATIVE: test behavior of cons?"
(assert (cons? (cons 1 2)))
(assert (cons? '(1 . 2)))
(assert (cons? '(1 2 3 . 4)))
(assert (cons? (list* 1 2 3)))
(assert (not (cons? (cons 1 [2]))))
(assert (not (cons? (list* 1 None)))))
(defn test-list* []
"NATIVE: test behavior of list*"
(assert (= 1 (list* 1)))
(assert (= (cons 1 2) (list* 1 2)))
(assert (= (cons 1 (cons 2 3)) (list* 1 2 3)))
(assert (= '(1 2 3 4 . 5) (list* 1 2 3 4 5))))

View File

@ -10,7 +10,6 @@
(setv walk-form '(print {"foo" "bar" (setv walk-form '(print {"foo" "bar"
"array" [1 2 3 [4]] "array" [1 2 3 [4]]
"something" (+ 1 2 3 4) "something" (+ 1 2 3 4)
"cons!" (cons 1 2)
"quoted?" '(foo)})) "quoted?" '(foo)}))
(defn collector [acc x] (defn collector [acc x]

View File

@ -4,7 +4,7 @@
from math import isnan from math import isnan
from hy.models import (HyExpression, HyInteger, HyFloat, HyComplex, HySymbol, from hy.models import (HyExpression, HyInteger, HyFloat, HyComplex, HySymbol,
HyString, HyDict, HyList, HySet, HyCons, HyKeyword) HyString, HyDict, HyList, HySet, HyKeyword)
from hy.lex import LexException, PrematureEndOfInput, tokenize from hy.lex import LexException, PrematureEndOfInput, tokenize
import pytest import pytest
@ -350,34 +350,6 @@ def test_lex_comment_382():
assert entry == [HySymbol("foo")] assert entry == [HySymbol("foo")]
def test_simple_cons():
"""Check that cons gets tokenized correctly"""
entry = tokenize("(a . b)")[0]
assert entry == HyCons(HySymbol("a"), HySymbol("b"))
def test_dotted_list():
"""Check that dotted lists get tokenized correctly"""
entry = tokenize("(a b c . (d . e))")[0]
assert entry == HyCons(HySymbol("a"),
HyCons(HySymbol("b"),
HyCons(HySymbol("c"),
HyCons(HySymbol("d"),
HySymbol("e")))))
def test_cons_list():
"""Check that cons of something and a list gets tokenized as a list"""
entry = tokenize("(a . [])")[0]
assert entry == HyList([HySymbol("a")])
assert type(entry) == HyList
entry = tokenize("(a . ())")[0]
assert entry == HyExpression([HySymbol("a")])
assert type(entry) == HyExpression
entry = tokenize("(a b . {})")[0]
assert entry == HyDict([HySymbol("a"), HySymbol("b")])
assert type(entry) == HyDict
def test_discard(): def test_discard():
"""Check that discarded terms are removed properly.""" """Check that discarded terms are removed properly."""
# empty # empty

View File

@ -7,8 +7,7 @@ import hy
from clint.textui.colored import clean from clint.textui.colored import clean
from hy._compat import long_type, str_type from hy._compat import long_type, str_type
from hy.models import (wrap_value, replace_hy_obj, HyString, HyInteger, HyList, from hy.models import (wrap_value, replace_hy_obj, HyString, HyInteger, HyList,
HyDict, HySet, HyExpression, HyCons, HyComplex, HyFloat, HyDict, HySet, HyExpression, HyComplex, HyFloat, pretty)
pretty)
def test_wrap_long_type(): def test_wrap_long_type():
@ -96,41 +95,6 @@ def test_set():
assert hyset == [3, 1, 2, 2] assert hyset == [3, 1, 2, 2]
def test_cons_slicing():
"""Check that cons slicing works as expected"""
cons = HyCons("car", "cdr")
assert cons[0] == "car"
assert cons[1:] == "cdr"
try:
cons[:]
assert True is False
except IndexError:
pass
try:
cons[1]
assert True is False
except IndexError:
pass
def test_cons_replacing():
"""Check that assigning to a cons works as expected"""
cons = HyCons("foo", "bar")
cons[0] = "car"
assert cons == HyCons("car", "bar")
cons[1:] = "cdr"
assert cons == HyCons("car", "cdr")
try:
cons[:] = "foo"
assert True is False
except IndexError:
pass
def test_number_model_copy(): def test_number_model_copy():
i = HyInteger(42) i = HyInteger(42)
assert (i == copy.copy(i)) assert (i == copy.copy(i))
@ -146,7 +110,7 @@ def test_number_model_copy():
PRETTY_STRINGS = { PRETTY_STRINGS = {
k % ('[1.0] {1.0} (1.0) #{1.0} (0.0 1.0 . 2.0)',): k % ('[1.0] {1.0} (1.0) #{1.0}',):
v.format(""" v.format("""
HyList([ HyList([
HyFloat(1.0)]), HyFloat(1.0)]),
@ -156,16 +120,12 @@ PRETTY_STRINGS = {
HyExpression([ HyExpression([
HyFloat(1.0)]), HyFloat(1.0)]),
HySet([ HySet([
HyFloat(1.0)]), HyFloat(1.0)])""")
<HyCons (
HyFloat(0.0)
HyFloat(1.0)
. HyFloat(2.0))>""")
for k, v in {'[%s]': 'HyList([{}])', for k, v in {'[%s]': 'HyList([{}])',
'#{%s}': 'HySet([{}])'}.items()} '#{%s}': 'HySet([{}])'}.items()}
PRETTY_STRINGS.update({ PRETTY_STRINGS.update({
'{[1.0] {1.0} (1.0) #{1.0} (0.0 1.0 . 2.0)}': '{[1.0] {1.0} (1.0) #{1.0}}':
"""HyDict([ """HyDict([
HyList([ HyList([
HyFloat(1.0)]), HyFloat(1.0)]),
@ -177,29 +137,7 @@ PRETTY_STRINGS.update({
HyFloat(1.0)]), HyFloat(1.0)]),
HySet([ HySet([
HyFloat(1.0)]) HyFloat(1.0)])
, ])"""
<HyCons (
HyFloat(0.0)
HyFloat(1.0)
. HyFloat(2.0))> # odd
])"""
,
'([1.0] {1.0} (1.0) #{1.0} (0.0 1.0 . 2.0) . 3.0)':
"""<HyCons (
HyList([
HyFloat(1.0)])
HyDict([
HyFloat(1.0) # odd
])
HyExpression([
HyFloat(1.0)])
HySet([
HyFloat(1.0)])
<HyCons (
HyFloat(0.0)
HyFloat(1.0)
. HyFloat(2.0))>
. HyFloat(3.0))>"""
, ,
'[1.0 1j [] {} () #{}]': '[1.0 1j [] {} () #{}]':
"""HyList([ """HyList([
@ -239,8 +177,6 @@ PRETTY_STRINGS.update({
def test_compound_model_repr(): def test_compound_model_repr():
HY_LIST_MODELS = (HyExpression, HyDict, HySet, HyList) HY_LIST_MODELS = (HyExpression, HyDict, HySet, HyList)
with pretty(False): with pretty(False):
assert eval(repr(HyCons(1, 2))).__class__ is HyCons
assert eval(repr(HyCons(1, 2))) == HyCons(1, 2)
for model in HY_LIST_MODELS: for model in HY_LIST_MODELS:
assert eval(repr(model())).__class__ is model assert eval(repr(model())).__class__ is model
assert eval(repr(model([1, 2]))) == model([1, 2]) assert eval(repr(model([1, 2]))) == model([1, 2])