Skip to content

Commit c8b83ac

Browse files
committed
py, parse: float - fix parsing of out of range floats and floats with spaces
1 parent bdc70db commit c8b83ac

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

parser/lexer.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -695,24 +695,22 @@ isNumber:
695695
imaginary = true
696696
toParse = s[:len(s)-1]
697697
}
698-
f, err := strconv.ParseFloat(toParse, 64)
698+
value, err = py.FloatFromString(toParse)
699699
if err != nil {
700-
panic(py.ExceptionNewf(py.ValueError, "invalid literal for float: '%s' (%v)", toParse, err))
700+
panic(err)
701701
}
702702
if imaginary {
703-
value = py.Complex(complex(0, f))
704-
} else {
705-
value = py.Float(f)
703+
value = py.Complex(complex(0, value.(py.Float)))
706704
}
707705
} else if s = decimalInteger.FindString(x.line); s != "" {
708706
last := s[len(s)-1]
709707
if last == 'j' || last == 'J' {
710708
toParse := s[:len(s)-1]
711-
f, err := strconv.ParseFloat(toParse, 64)
709+
value, err = py.FloatFromString(toParse)
712710
if err != nil {
713-
panic(py.ExceptionNewf(py.ValueError, "invalid literal for imaginary number: '%s' (%v)", toParse, err))
711+
panic(err)
714712
}
715-
value = py.Complex(complex(0, f))
713+
value = py.Complex(complex(0, value.(py.Float)))
716714
} else {
717715
// Discard numbers with leading 0 except all 0s
718716
if illegalDecimalInteger.FindString(s) != "" {

py/float.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"math"
88
"math/big"
99
"strconv"
10+
"strings"
1011
)
1112

1213
var FloatType = ObjectType.NewType("float", "float(x) -> floating point number\n\nConvert a string or number to a floating point number, if possible.", FloatNew, nil)
@@ -52,9 +53,19 @@ func (a Float) M__repr__() (Object, error) {
5253

5354
// FloatFromString turns a string into a Float
5455
func FloatFromString(str string) (Object, error) {
56+
str = strings.TrimSpace(str)
5557
f, err := strconv.ParseFloat(str, 64)
5658
if err != nil {
57-
return nil, ExceptionNewf(ValueError, "could not convert string to float: '%s'", str)
59+
if numErr, ok := err.(*strconv.NumError); ok {
60+
if numErr.Err == strconv.ErrRange {
61+
if str[0] == '-' {
62+
return Float(math.Inf(-1)), nil
63+
} else {
64+
return Float(math.Inf(1)), nil
65+
}
66+
}
67+
}
68+
return nil, ExceptionNewf(ValueError, "invalid literal for float: '%s'", str)
5869
}
5970
return Float(f), nil
6071
}

py/tests/float.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from libtest import assertRaises
2+
3+
doc="float"
4+
assert float("1.5") == 1.5
5+
assert float(" 1.5") == 1.5
6+
assert float(" 1.5 ") == 1.5
7+
assert float("1.5 ") == 1.5
8+
assert float("-1E9") == -1E9
9+
assert float("1E400") == float("inf")
10+
assert float(" -1E400") == float("-inf")
11+
assertRaises(ValueError, float, "1 E200")
12+
13+
doc="finished"

0 commit comments

Comments
 (0)