summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2008-02-02 17:16:13 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2008-02-02 17:16:13 (GMT)
commit1dabdb25f83d55737c2154b63bc463240fd7bc03 (patch)
tree95d920acab8e1d161cbd81371319aa4b55d61ea5
parent5a6cfee6320383ccc20d9fefbd0ebf1555b17909 (diff)
downloadcpython-1dabdb25f83d55737c2154b63bc463240fd7bc03.zip
cpython-1dabdb25f83d55737c2154b63bc463240fd7bc03.tar.gz
cpython-1dabdb25f83d55737c2154b63bc463240fd7bc03.tar.bz2
Make the Rational constructor accept '3.' and '.2' as well as '3.2'.
-rwxr-xr-xLib/rational.py15
-rw-r--r--Lib/test/test_rational.py6
2 files changed, 18 insertions, 3 deletions
diff --git a/Lib/rational.py b/Lib/rational.py
index bc2259b..c76cba3 100755
--- a/Lib/rational.py
+++ b/Lib/rational.py
@@ -25,9 +25,18 @@ def gcd(a, b):
return a
-_RATIONAL_FORMAT = re.compile(
- r'^\s*(?P<sign>[-+]?)(?P<num>\d+)'
- r'(?:/(?P<denom>\d+)|\.(?P<decimal>\d+))?\s*$')
+_RATIONAL_FORMAT = re.compile(r"""
+ \A\s* # optional whitespace at the start, then
+ (?P<sign>[-+]?) # an optional sign, then
+ (?=\d|\.\d) # lookahead for digit or .digit
+ (?P<num>\d*) # numerator (possibly empty)
+ (?: # followed by an optional
+ /(?P<denom>\d+) # / and denominator
+ | # or
+ \.(?P<decimal>\d*) # decimal point and fractional part
+ )?
+ \s*\Z # and optional whitespace to finish
+""", re.VERBOSE)
class Rational(RationalAbc):
diff --git a/Lib/test/test_rational.py b/Lib/test/test_rational.py
index 1c37874..5679c5a 100644
--- a/Lib/test/test_rational.py
+++ b/Lib/test/test_rational.py
@@ -78,6 +78,8 @@ class RationalTest(unittest.TestCase):
self.assertEquals((16, 5), _components(R(" 3.2 ")))
self.assertEquals((-16, 5), _components(R(u" -3.2 ")))
+ self.assertEquals((-3, 1), _components(R(u" -3. ")))
+ self.assertEquals((3, 5), _components(R(u" .6 ")))
self.assertRaisesMessage(
@@ -113,6 +115,10 @@ class RationalTest(unittest.TestCase):
# Don't accept combinations of decimals and rationals.
ValueError, "Invalid literal for Rational: 3.2/7",
R, "3.2/7")
+ self.assertRaisesMessage(
+ # Allow 3. and .3, but not .
+ ValueError, "Invalid literal for Rational: .",
+ R, ".")
def testImmutable(self):
r = R(7, 3)