Require capitalizing NaN and Inf like so
This commit is contained in:
parent
a746ccb42c
commit
bb91b57dca
1
NEWS
1
NEWS
@ -8,6 +8,7 @@ Changes from 0.13.0
|
||||
* The compiler now automatically promotes values to Hy model objects
|
||||
as necessary, so you can write ``(eval `(+ 1 ~n))`` instead of
|
||||
``(eval `(+ 1 ~(HyInteger n)))``
|
||||
* Literal `Inf`s and `NaN`s must now be capitalized like that
|
||||
|
||||
[ Bug Fixes ]
|
||||
* Numeric literals are no longer parsed as symbols when followed by a dot
|
||||
|
@ -52,6 +52,9 @@ digits.
|
||||
|
||||
(print 10,000,000,000 10_000_000_000)
|
||||
|
||||
Unlike Python, Hy provides literal forms for NaN and infinity: `NaN`, `Inf`,
|
||||
and `-Inf`.
|
||||
|
||||
string literals
|
||||
---------------
|
||||
|
||||
|
31
hy/models.py
31
hy/models.py
@ -3,6 +3,7 @@
|
||||
# license. See the LICENSE.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from math import isnan, isinf
|
||||
from hy._compat import PY3, str_type, bytes_type, long_type, string_types
|
||||
from fractions import Fraction
|
||||
|
||||
@ -142,15 +143,24 @@ if not PY3: # do not add long on python3
|
||||
_wrappers[long_type] = HyInteger
|
||||
|
||||
|
||||
def check_inf_nan_cap(arg, value):
|
||||
if isinstance(arg, string_types):
|
||||
if isinf(value) and "Inf" not in arg:
|
||||
raise ValueError('Inf must be capitalized as "Inf"')
|
||||
if isnan(value) and "NaN" not in arg:
|
||||
raise ValueError('NaN must be capitalized as "NaN"')
|
||||
|
||||
|
||||
class HyFloat(HyObject, float):
|
||||
"""
|
||||
Internal representation of a Hy Float. May raise a ValueError as if
|
||||
float(foo) was called, given HyFloat(foo).
|
||||
"""
|
||||
|
||||
def __new__(cls, number, *args, **kwargs):
|
||||
number = float(strip_digit_separators(number))
|
||||
return super(HyFloat, cls).__new__(cls, number)
|
||||
def __new__(cls, num, *args, **kwargs):
|
||||
value = super(HyFloat, cls).__new__(cls, strip_digit_separators(num))
|
||||
check_inf_nan_cap(num, value)
|
||||
return value
|
||||
|
||||
_wrappers[float] = HyFloat
|
||||
|
||||
@ -161,9 +171,18 @@ class HyComplex(HyObject, complex):
|
||||
complex(foo) was called, given HyComplex(foo).
|
||||
"""
|
||||
|
||||
def __new__(cls, number, *args, **kwargs):
|
||||
number = complex(strip_digit_separators(number))
|
||||
return super(HyComplex, cls).__new__(cls, number)
|
||||
def __new__(cls, num, *args, **kwargs):
|
||||
value = super(HyComplex, cls).__new__(cls, strip_digit_separators(num))
|
||||
if isinstance(num, string_types):
|
||||
p1, _, p2 = num.lstrip("+-").replace("-", "+").partition("+")
|
||||
if p2:
|
||||
check_inf_nan_cap(p1, value.real)
|
||||
check_inf_nan_cap(p2, value.imag)
|
||||
elif "j" in p1:
|
||||
check_inf_nan_cap(p1, value.imag)
|
||||
else:
|
||||
check_inf_nan_cap(p1, value.real)
|
||||
return value
|
||||
|
||||
_wrappers[complex] = HyComplex
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# This file is part of Hy, which is free software licensed under the Expat
|
||||
# license. See the LICENSE.
|
||||
|
||||
from math import isnan
|
||||
from hy.models import (HyExpression, HyInteger, HyFloat, HyComplex, HySymbol,
|
||||
HyString, HyDict, HyList, HySet, HyCons)
|
||||
from hy.lex import LexException, PrematureEndOfInput, tokenize
|
||||
@ -91,6 +92,22 @@ def test_lex_expression_float():
|
||||
assert objs == [HyExpression([HySymbol("foo"), HyFloat(1.e7)])]
|
||||
|
||||
|
||||
def test_lex_nan_and_inf():
|
||||
|
||||
assert isnan(tokenize("NaN")[0])
|
||||
assert tokenize("Nan") == [HySymbol("Nan")]
|
||||
assert tokenize("nan") == [HySymbol("nan")]
|
||||
assert tokenize("NAN") == [HySymbol("NAN")]
|
||||
|
||||
assert tokenize("Inf") == [HyFloat(float("inf"))]
|
||||
assert tokenize("inf") == [HySymbol("inf")]
|
||||
assert tokenize("INF") == [HySymbol("INF")]
|
||||
|
||||
assert tokenize("-Inf") == [HyFloat(float("-inf"))]
|
||||
assert tokenize("-inf") == [HySymbol("_inf")]
|
||||
assert tokenize("-INF") == [HySymbol("_INF")]
|
||||
|
||||
|
||||
def test_lex_expression_complex():
|
||||
""" Make sure expressions can produce complex """
|
||||
|
||||
@ -102,6 +119,11 @@ def test_lex_expression_complex():
|
||||
assert t("-0.5j") == f(HyComplex(-0.5j))
|
||||
assert t("1.e7j") == f(HyComplex(1e7j))
|
||||
assert t("j") == f(HySymbol("j"))
|
||||
assert isnan(t("NaNj")[0][1].imag)
|
||||
assert t("nanj") == f(HySymbol("nanj"))
|
||||
assert t("Inf+Infj") == f(HyComplex(complex(float("inf"), float("inf"))))
|
||||
assert t("Inf-Infj") == f(HyComplex(complex(float("inf"), float("-inf"))))
|
||||
assert t("Inf-INFj") == f(HySymbol("Inf_INFj"))
|
||||
|
||||
|
||||
def test_lex_digit_separators():
|
||||
|
Loading…
Reference in New Issue
Block a user