Merge pull request #1360 from gilch/model-repr
proper reprs for Hy models
This commit is contained in:
commit
db210929d0
@ -22,12 +22,18 @@ Example:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (import [hy.contrib.walk [walk]])
|
||||
=> (setv a '(a b c d e f))
|
||||
=> (walk ord identity a)
|
||||
(97 98 99 100 101 102)
|
||||
=> (walk ord first a)
|
||||
97
|
||||
=> (import [hy.contrib.walk [walk]])
|
||||
=> (setv a '(a b c d e f))
|
||||
=> (walk ord identity a)
|
||||
HyExpression([
|
||||
97,
|
||||
98,
|
||||
99,
|
||||
100,
|
||||
101,
|
||||
102])
|
||||
=> (walk ord first a)
|
||||
97
|
||||
|
||||
postwalk
|
||||
---------
|
||||
@ -41,25 +47,73 @@ each sub-form, uses ``f`` 's return value in place of the original.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (import [hy.contrib.walk [postwalk]])
|
||||
=> (def trail '([1 2 3] [4 [5 6 [7]]]))
|
||||
=> (defn walking [x]
|
||||
(print "Walking:" x)
|
||||
x )
|
||||
=> (postwalk walking trail)
|
||||
Walking: 1
|
||||
Walking: 2
|
||||
Walking: 3
|
||||
Walking: (1 2 3)
|
||||
Walking: 4
|
||||
Walking: 5
|
||||
Walking: 6
|
||||
Walking: 7
|
||||
Walking: (7)
|
||||
Walking: (5 6 [7])
|
||||
Walking: (4 [5 6 [7]])
|
||||
Walking: ([1 2 3] [4 [5 6 [7]]])
|
||||
([1 2 3] [4 [5 6 [7]]])
|
||||
=> (import [hy.contrib.walk [postwalk]])
|
||||
=> (def trail '([1 2 3] [4 [5 6 [7]]]))
|
||||
=> (defn walking [x]
|
||||
... (print "Walking:" x :sep "\n")
|
||||
... x)
|
||||
=> (postwalk walking trail)
|
||||
Walking:
|
||||
1
|
||||
Walking:
|
||||
2
|
||||
Walking:
|
||||
3
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)])
|
||||
Walking:
|
||||
4
|
||||
Walking:
|
||||
5
|
||||
Walking:
|
||||
6
|
||||
Walking:
|
||||
7
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyInteger(7)])
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)]),
|
||||
HyList([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])])
|
||||
HyExpression([
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)]),
|
||||
HyList([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])])
|
||||
|
||||
prewalk
|
||||
--------
|
||||
@ -73,22 +127,70 @@ each sub-form, uses ``f`` 's return value in place of the original.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (import [hy.contrib.walk [prewalk]])
|
||||
=> (def trail '([1 2 3] [4 [5 6 [7]]]))
|
||||
=> (defn walking [x]
|
||||
(print "Walking:" x)
|
||||
x )
|
||||
=> (prewalk walking trail)
|
||||
Walking: ([1 2 3] [4 [5 6 [7]]])
|
||||
Walking: [1 2 3]
|
||||
Walking: 1
|
||||
Walking: 2
|
||||
Walking: 3
|
||||
Walking: [4 [5 6 [7]]]
|
||||
Walking: 4
|
||||
Walking: [5 6 [7]]
|
||||
Walking: 5
|
||||
Walking: 6
|
||||
Walking: [7]
|
||||
Walking: 7
|
||||
([1 2 3] [4 [5 6 [7]]])
|
||||
=> (import [hy.contrib.walk [prewalk]])
|
||||
=> (def trail '([1 2 3] [4 [5 6 [7]]]))
|
||||
=> (defn walking [x]
|
||||
... (print "Walking:" x :sep "\n")
|
||||
... x)
|
||||
=> (prewalk walking trail)
|
||||
Walking:
|
||||
HyExpression([
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)]),
|
||||
HyList([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])])
|
||||
Walking:
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)])
|
||||
Walking:
|
||||
1
|
||||
Walking:
|
||||
2
|
||||
Walking:
|
||||
3
|
||||
Walking:
|
||||
HyList([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])
|
||||
Walking:
|
||||
4
|
||||
Walking:
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])
|
||||
Walking:
|
||||
5
|
||||
Walking:
|
||||
6
|
||||
Walking:
|
||||
HyList([
|
||||
HyInteger(7)])
|
||||
Walking:
|
||||
7
|
||||
HyExpression([
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2),
|
||||
HyInteger(3)]),
|
||||
HyList([
|
||||
HyInteger(4),
|
||||
HyList([
|
||||
HyInteger(5),
|
||||
HyInteger(6),
|
||||
HyList([
|
||||
HyInteger(7)])])])])
|
||||
|
@ -890,7 +890,7 @@ doto
|
||||
.. code-block:: clj
|
||||
|
||||
=> (doto [] (.append 1) (.append 2) .reverse)
|
||||
[2 1]
|
||||
[2, 1]
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
@ -899,7 +899,7 @@ doto
|
||||
=> (.append collection 2)
|
||||
=> (.reverse collection)
|
||||
=> collection
|
||||
[2 1]
|
||||
[2, 1]
|
||||
|
||||
|
||||
eval-and-compile
|
||||
@ -1383,9 +1383,10 @@ alternatively be written using the apostrophe (``'``) symbol.
|
||||
.. code-block:: clj
|
||||
|
||||
=> (setv x '(print "Hello World"))
|
||||
; variable x is set to expression & not evaluated
|
||||
=> x
|
||||
(u'print' u'Hello World')
|
||||
=> x ; varible x is set to unevaluated expression
|
||||
HyExpression([
|
||||
HySymbol('print'),
|
||||
HyString('Hello World')])
|
||||
=> (eval x)
|
||||
Hello World
|
||||
|
||||
@ -1694,12 +1695,17 @@ is aliased to the tilde (``~``) symbol.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(def name "Cuddles")
|
||||
(quasiquote (= name (unquote name)))
|
||||
;=> (u'=' u'name' u'Cuddles')
|
||||
|
||||
`(= name ~name)
|
||||
;=> (u'=' u'name' u'Cuddles')
|
||||
=> (setv nickname "Cuddles")
|
||||
=> (quasiquote (= nickname (unquote nickname)))
|
||||
HyExpression([
|
||||
HySymbol('='),
|
||||
HySymbol('nickname'),
|
||||
'Cuddles'])
|
||||
=> `(= nickname ~nickname)
|
||||
HyExpression([
|
||||
HySymbol('='),
|
||||
HySymbol('nickname'),
|
||||
'Cuddles'])
|
||||
|
||||
|
||||
unquote-splice
|
||||
@ -1715,15 +1721,25 @@ into the form. ``unquote-splice`` is aliased to the ``~@`` syntax.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(def nums [1 2 3 4])
|
||||
(quasiquote (+ (unquote-splice nums)))
|
||||
;=> ('+' 1 2 3 4)
|
||||
|
||||
`(+ ~@nums)
|
||||
;=> ('+' 1 2 3 4)
|
||||
|
||||
`[1 2 ~@(if (< (nth nums 0) 0) nums)]
|
||||
;=> ('+' 1 2)
|
||||
=> (setv nums [1 2 3 4])
|
||||
=> (quasiquote (+ (unquote-splice nums)))
|
||||
HyExpression([
|
||||
HySymbol('+'),
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4])
|
||||
=> `(+ ~@nums)
|
||||
HyExpression([
|
||||
HySymbol('+'),
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4])
|
||||
=> `[1 2 ~@(if (neg? (first nums)) nums)]
|
||||
HyList([
|
||||
HyInteger(1),
|
||||
HyInteger(2)])
|
||||
|
||||
Here, the last example evaluates to ``('+' 1 2)``, since the condition
|
||||
``(< (nth nums 0) 0)`` is ``False``, which makes this ``if`` expression
|
||||
|
@ -618,17 +618,29 @@ arguments. If the argument list only has one element, return it.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (list* 1 2 3 4)
|
||||
(1 2 3 . 4)
|
||||
|
||||
=> (list* 1 2 3 [4])
|
||||
[1, 2, 3, 4]
|
||||
|
||||
=> (list* 1)
|
||||
1
|
||||
|
||||
=> (cons? (list* 1 2 3 4))
|
||||
True
|
||||
=> (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:
|
||||
|
||||
@ -643,11 +655,23 @@ Returns the full macro expansion of *form*.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (macroexpand '(-> (a b) (x y)))
|
||||
(u'x' (u'a' u'b') u'y')
|
||||
|
||||
=> (macroexpand '(-> (a b) (-> (c d) (e f))))
|
||||
(u'e' (u'c' (u'a' u'b') u'd') u'f')
|
||||
=> (macroexpand '(-> (a b) (x y)))
|
||||
HyExpression([
|
||||
HySymbol('x'),
|
||||
HyExpression([
|
||||
HySymbol('a'),
|
||||
HySymbol('b')]),
|
||||
HySymbol('y')])
|
||||
=> (macroexpand '(-> (a b) (-> (c d) (e f))))
|
||||
HyExpression([
|
||||
HySymbol('e'),
|
||||
HyExpression([
|
||||
HySymbol('c'),
|
||||
HyExpression([
|
||||
HySymbol('a'),
|
||||
HySymbol('b')]),
|
||||
HySymbol('d')]),
|
||||
HySymbol('f')])
|
||||
|
||||
.. _macroexpand-1-fn:
|
||||
|
||||
@ -662,8 +686,18 @@ Returns the single step macro expansion of *form*.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (macroexpand-1 '(-> (a b) (-> (c d) (e f))))
|
||||
(u'_>' (u'a' u'b') (u'c' u'd') (u'e' u'f'))
|
||||
=> (macroexpand-1 '(-> (a b) (-> (c d) (e f))))
|
||||
HyExpression([
|
||||
HySymbol('_>'),
|
||||
HyExpression([
|
||||
HySymbol('a'),
|
||||
HySymbol('b')]),
|
||||
HyExpression([
|
||||
HySymbol('c'),
|
||||
HySymbol('d')]),
|
||||
HyExpression([
|
||||
HySymbol('e'),
|
||||
HySymbol('f')])])
|
||||
|
||||
|
||||
.. _merge-with-fn:
|
||||
@ -839,26 +873,26 @@ Chunks *coll* into *n*-tuples (pairs by default).
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (list (partition (range 10))) ; n=2
|
||||
[(, 0 1) (, 2 3) (, 4 5) (, 6 7) (, 8 9)]
|
||||
=> (list (partition (range 10))) ; n=2
|
||||
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
|
||||
|
||||
The *step* defaults to *n*, but can be more to skip elements, or less for a sliding window with overlap.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (list (partition (range 10) 2 3))
|
||||
[(, 0 1) (, 3 4) (, 6 7)]
|
||||
=> (list (partition (range 5) 2 1))
|
||||
[(, 0 1) (, 1 2) (, 2 3) (, 3 4)])
|
||||
=> (list (partition (range 10) 2 3))
|
||||
[(0, 1), (3, 4), (6, 7)]
|
||||
=> (list (partition (range 5) 2 1))
|
||||
[(0, 1), (1, 2), (2, 3), (3, 4)]
|
||||
|
||||
The remainder, if any, is not included unless a *fillvalue* is specified.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (list (partition (range 10) 3))
|
||||
[(, 0 1 2) (, 3 4 5) (, 6 7 8)]
|
||||
=> (list (partition (range 10) 3 :fillvalue "x"))
|
||||
[(, 0 1 2) (, 3 4 5) (, 6 7 8) (, 9 "x" "x")]
|
||||
=> (list (partition (range 10) 3))
|
||||
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
|
||||
=> (list (partition (range 10) 3 :fillvalue "x"))
|
||||
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 'x', 'x')]
|
||||
|
||||
.. _pos?-fn:
|
||||
|
||||
@ -1220,36 +1254,43 @@ if *from-file* ends before a complete expression can be parsed.
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (read)
|
||||
(+ 2 2)
|
||||
('+' 2 2)
|
||||
=> (eval (read))
|
||||
(+ 2 2)
|
||||
4
|
||||
=> (read)
|
||||
(+ 2 2)
|
||||
HyExpression([
|
||||
HySymbol('+'),
|
||||
HyInteger(2),
|
||||
HyInteger(2)])
|
||||
=> (eval (read))
|
||||
(+ 2 2)
|
||||
4
|
||||
=> (import io)
|
||||
=> (setv buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
|
||||
=> (eval (read :from_file buffer))
|
||||
4
|
||||
=> (eval (read :from_file buffer))
|
||||
1
|
||||
|
||||
=> (import io)
|
||||
=> (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
|
||||
=> (eval (read :from_file buffer))
|
||||
4
|
||||
=> (eval (read :from_file buffer))
|
||||
1
|
||||
|
||||
=> ; assuming "example.hy" contains:
|
||||
=> ; (print "hello")
|
||||
=> ; (print "hyfriends!")
|
||||
=> (with [f (open "example.hy")]
|
||||
... (try
|
||||
... (while True
|
||||
... (setv exp (read f))
|
||||
... (print "OHY" exp)
|
||||
... (eval exp))
|
||||
... (except [e EOFError]
|
||||
... (print "EOF!"))))
|
||||
OHY ('print' 'hello')
|
||||
hello
|
||||
OHY ('print' 'hyfriends!')
|
||||
hyfriends!
|
||||
EOF!
|
||||
=> (with [f (open "example.hy" "w")]
|
||||
... (.write f "(print 'hello)\n(print \"hyfriends!\")"))
|
||||
35
|
||||
=> (with [f (open "example.hy")]
|
||||
... (try (while True
|
||||
... (setv exp (read f))
|
||||
... (print "OHY" exp)
|
||||
... (eval exp))
|
||||
... (except [e EOFError]
|
||||
... (print "EOF!"))))
|
||||
OHY HyExpression([
|
||||
HySymbol('print'),
|
||||
HyExpression([
|
||||
HySymbol('quote'),
|
||||
HySymbol('hello')])])
|
||||
hello
|
||||
OHY HyExpression([
|
||||
HySymbol('print'),
|
||||
HyString('hyfriends!')])
|
||||
hyfriends!
|
||||
EOF!
|
||||
|
||||
read-str
|
||||
--------
|
||||
@ -1261,11 +1302,12 @@ string:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
=> (read-str "(print 1)")
|
||||
(u'print' 1L)
|
||||
=> (eval (read-str "(print 1)"))
|
||||
1
|
||||
=>
|
||||
=> (read-str "(print 1)")
|
||||
HyExpression([
|
||||
HySymbol('print'),
|
||||
HyInteger(1)])
|
||||
=> (eval (read-str "(print 1)"))
|
||||
1
|
||||
|
||||
.. _remove-fn:
|
||||
|
||||
@ -1409,3 +1451,4 @@ are available. Some of their names have been changed:
|
||||
- ``dropwhile`` has been changed to ``drop-while``
|
||||
|
||||
- ``filterfalse`` has been changed to ``remove``
|
||||
|
||||
|
@ -39,6 +39,15 @@ Compound Models
|
||||
Parenthesized and bracketed lists are parsed as compound models by the
|
||||
Hy parser.
|
||||
|
||||
Hy uses pretty-printing reprs for its compound models by default.
|
||||
If this is causing issues,
|
||||
it can be turned off globally by setting ``hy.models.PRETTY`` to ``False``,
|
||||
or temporarily by using the ``hy.models.pretty`` context manager.
|
||||
|
||||
Hy also attempts to color pretty reprs using ``clint.textui.colored``.
|
||||
This module has a flag to disable coloring,
|
||||
and a method ``clean`` to strip colored strings of their color tags.
|
||||
|
||||
.. _hylist:
|
||||
|
||||
HyList
|
||||
|
@ -66,7 +66,7 @@
|
||||
(or (is t HyKeyword) (and (is t str-type) (.startswith x HyKeyword.PREFIX)))
|
||||
(cut x 1)
|
||||
(in t [str-type HyString bytes-type HyBytes]) (do
|
||||
(setv r (.lstrip (repr x) "ub"))
|
||||
(setv r (.lstrip (base-repr x) "ub"))
|
||||
(+ (if (in t [bytes-type HyBytes]) "b" "") (if (.startswith "\"" r)
|
||||
; If Python's built-in repr produced a double-quoted string, use
|
||||
; that.
|
||||
@ -75,9 +75,9 @@
|
||||
; convert it.
|
||||
(+ "\"" (.replace (cut r 1 -1) "\"" "\\\"") "\""))))
|
||||
(and (not PY3) (is t int))
|
||||
(.format "(int {})" (repr x))
|
||||
(.format "(int {})" (base-repr x))
|
||||
(and (not PY3) (in t [long_type HyInteger]))
|
||||
(.rstrip (repr x) "L")
|
||||
(.rstrip (base-repr x) "L")
|
||||
(and (in t [float HyFloat]) (isnan x))
|
||||
"NaN"
|
||||
(and (in t [float HyFloat]) (= x Inf))
|
||||
@ -85,9 +85,18 @@
|
||||
(and (in t [float HyFloat]) (= x -Inf))
|
||||
"-Inf"
|
||||
(in t [complex HyComplex])
|
||||
(.replace (.replace (.strip (repr x) "()") "inf" "Inf") "nan" "NaN")
|
||||
(.replace (.replace (.strip (base-repr x) "()") "inf" "Inf") "nan" "NaN")
|
||||
(is t fraction)
|
||||
(.format "{}/{}" (f x.numerator q) (f x.denominator q))
|
||||
; else
|
||||
(repr x))))
|
||||
(base-repr x))))
|
||||
(f obj False))
|
||||
|
||||
(defn base-repr [x]
|
||||
(unless (instance? HyObject x)
|
||||
(return (repr x)))
|
||||
; Call (.repr x) using the first class of x that doesn't inherit from
|
||||
; HyObject.
|
||||
(.__repr__
|
||||
(next (genexpr t [t (. (type x) __mro__)] (not (issubclass t HyObject))))
|
||||
x))
|
||||
|
93
hy/models.py
93
hy/models.py
@ -3,9 +3,28 @@
|
||||
# license. See the LICENSE.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from contextlib import contextmanager
|
||||
from math import isnan, isinf
|
||||
from hy._compat import PY3, str_type, bytes_type, long_type, string_types
|
||||
from fractions import Fraction
|
||||
from clint.textui import colored
|
||||
|
||||
|
||||
PRETTY = True
|
||||
|
||||
|
||||
@contextmanager
|
||||
def pretty(pretty=True):
|
||||
"""
|
||||
Context manager to temporarily enable
|
||||
or disable pretty-printing of Hy model reprs.
|
||||
"""
|
||||
global PRETTY
|
||||
old, PRETTY = PRETTY, pretty
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
PRETTY = old
|
||||
|
||||
|
||||
class HyObject(object):
|
||||
@ -25,6 +44,9 @@ class HyObject(object):
|
||||
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, super(HyObject, self).__repr__())
|
||||
|
||||
|
||||
_wrappers = {}
|
||||
|
||||
@ -59,6 +81,10 @@ def replace_hy_obj(obj, other):
|
||||
% type(obj))
|
||||
|
||||
|
||||
def repr_indent(obj):
|
||||
return repr(obj).replace("\n", "\n ")
|
||||
|
||||
|
||||
class HyString(HyObject, str_type):
|
||||
"""
|
||||
Generic Hy String object. Helpful to store string literals from Hy
|
||||
@ -109,6 +135,9 @@ class HyKeyword(HyObject, str_type):
|
||||
obj = str_type.__new__(cls, value)
|
||||
return obj
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, repr(self[1:]))
|
||||
|
||||
|
||||
def strip_digit_separators(number):
|
||||
# Don't strip a _ or , if it's the first character, as _42 and
|
||||
@ -217,8 +246,22 @@ class HyList(HyObject, list):
|
||||
|
||||
return ret
|
||||
|
||||
color = staticmethod(colored.cyan)
|
||||
|
||||
def __repr__(self):
|
||||
return "[%s]" % (" ".join([repr(x) for x in self]))
|
||||
return str(self) if PRETTY else super(HyList, self).__repr__()
|
||||
|
||||
def __str__(self):
|
||||
with pretty():
|
||||
c = self.color
|
||||
if self:
|
||||
return ("{}{}\n {}{}").format(
|
||||
c(self.__class__.__name__),
|
||||
c("(["),
|
||||
(c(",") + "\n ").join([repr_indent(e) for e in self]),
|
||||
c("])"))
|
||||
else:
|
||||
return '' + c(self.__class__.__name__ + "()")
|
||||
|
||||
_wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)
|
||||
_wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)
|
||||
@ -229,8 +272,24 @@ class HyDict(HyList):
|
||||
HyDict (just a representation of a dict)
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return "{%s}" % (" ".join([repr(x) for x in self]))
|
||||
def __str__(self):
|
||||
with pretty():
|
||||
g = colored.green
|
||||
if self:
|
||||
pairs = []
|
||||
for k, v in zip(self[::2],self[1::2]):
|
||||
k, v = repr_indent(k), repr_indent(v)
|
||||
pairs.append(
|
||||
("{0}{c}\n {1}\n "
|
||||
if '\n' in k+v
|
||||
else "{0}{c} {1}").format(k, v, c=g(',')))
|
||||
if len(self) % 2 == 1:
|
||||
pairs.append("{} {}\n".format(
|
||||
repr_indent(self[-1]), g("# odd")))
|
||||
return "{}\n {}{}".format(
|
||||
g("HyDict(["), ("{c}\n ".format(c=g(',')).join(pairs)), g("])"))
|
||||
else:
|
||||
return '' + g("HyDict()")
|
||||
|
||||
def keys(self):
|
||||
return self[0::2]
|
||||
@ -248,9 +307,7 @@ class HyExpression(HyList):
|
||||
"""
|
||||
Hy S-Expression. Basically just a list.
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return "(%s)" % (" ".join([repr(x) for x in self]))
|
||||
color = staticmethod(colored.yellow)
|
||||
|
||||
_wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)
|
||||
_wrappers[Fraction] = lambda e: HyExpression(
|
||||
@ -261,9 +318,7 @@ class HySet(HyList):
|
||||
"""
|
||||
Hy set (just a representation of a set)
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return "#{%s}" % (" ".join([repr(x) for x in self]))
|
||||
color = staticmethod(colored.red)
|
||||
|
||||
_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)
|
||||
|
||||
@ -339,10 +394,24 @@ class HyCons(HyObject):
|
||||
HyObject.replace(self, other)
|
||||
|
||||
def __repr__(self):
|
||||
if isinstance(self.cdr, self.__class__):
|
||||
return "(%s %s)" % (repr(self.car), repr(self.cdr)[1:-1])
|
||||
if PRETTY:
|
||||
return str(self)
|
||||
else:
|
||||
return "(%s . %s)" % (repr(self.car), repr(self.cdr))
|
||||
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 (
|
||||
|
@ -3,9 +3,12 @@
|
||||
# license. See the LICENSE.
|
||||
|
||||
import copy
|
||||
import hy
|
||||
from clint.textui.colored import clean
|
||||
from hy._compat import long_type, str_type
|
||||
from hy.models import (wrap_value, replace_hy_obj, HyString, HyInteger, HyList,
|
||||
HyDict, HySet, HyExpression, HyCons, HyComplex, HyFloat)
|
||||
HyDict, HySet, HyExpression, HyCons, HyComplex, HyFloat,
|
||||
pretty)
|
||||
|
||||
|
||||
def test_wrap_long_type():
|
||||
@ -140,3 +143,117 @@ def test_number_model_copy():
|
||||
c = HyComplex(42j)
|
||||
assert (c == copy.copy(c))
|
||||
assert (c == copy.deepcopy(c))
|
||||
|
||||
|
||||
PRETTY_STRINGS = {
|
||||
k % ('[1.0] {1.0} (1.0) #{1.0} (0.0 1.0 . 2.0)',):
|
||||
v.format("""
|
||||
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))>""")
|
||||
for k, v in {'[%s]': 'HyList([{}])',
|
||||
'#{%s}': 'HySet([{}])'}.items()}
|
||||
|
||||
PRETTY_STRINGS.update({
|
||||
'{[1.0] {1.0} (1.0) #{1.0} (0.0 1.0 . 2.0)}':
|
||||
"""HyDict([
|
||||
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))> # 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 [] {} () #{}]':
|
||||
"""HyList([
|
||||
HyFloat(1.0),
|
||||
HyComplex(1j),
|
||||
HyList(),
|
||||
HyDict(),
|
||||
HyExpression(),
|
||||
HySet()])"""
|
||||
,
|
||||
'{{1j 2j} {1j 2j [][1j]} {[1j][] 1j 2j} {[1j][1j]}}':
|
||||
"""HyDict([
|
||||
HyDict([
|
||||
HyComplex(1j), HyComplex(2j)]),
|
||||
HyDict([
|
||||
HyComplex(1j), HyComplex(2j),
|
||||
HyList(),
|
||||
HyList([
|
||||
HyComplex(1j)])
|
||||
])
|
||||
,
|
||||
HyDict([
|
||||
HyList([
|
||||
HyComplex(1j)]),
|
||||
HyList()
|
||||
,
|
||||
HyComplex(1j), HyComplex(2j)]),
|
||||
HyDict([
|
||||
HyList([
|
||||
HyComplex(1j)]),
|
||||
HyList([
|
||||
HyComplex(1j)])
|
||||
])
|
||||
])"""})
|
||||
|
||||
|
||||
def test_compound_model_repr():
|
||||
HY_LIST_MODELS = (HyExpression, HyDict, HySet, HyList)
|
||||
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:
|
||||
assert eval(repr(model())).__class__ is model
|
||||
assert eval(repr(model([1, 2]))) == model([1, 2])
|
||||
assert eval(repr(model([1, 2, 3]))) == model([1, 2, 3])
|
||||
for k, v in PRETTY_STRINGS.items():
|
||||
# `str` should be pretty, even under `pretty(False)`.
|
||||
assert clean(str(hy.read_str(k))) == v
|
||||
for k in PRETTY_STRINGS.keys():
|
||||
assert eval(repr(hy.read_str(k))) == hy.read_str(k)
|
||||
with pretty(True):
|
||||
for model in HY_LIST_MODELS:
|
||||
assert eval(clean(repr(model()))).__class__ is model
|
||||
assert eval(clean(repr(model([1, 2])))) == model([1, 2])
|
||||
assert eval(clean(repr(model([1, 2, 3])))) == model([1, 2, 3])
|
||||
for k, v in PRETTY_STRINGS.items():
|
||||
assert clean(repr(hy.read_str(k))) == v
|
||||
|
Loading…
Reference in New Issue
Block a user