|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
Uses TreeFragment to test invalid syntax. |
|
|
""" |
|
|
|
|
|
from __future__ import absolute_import |
|
|
|
|
|
from ...TestUtils import CythonTest |
|
|
from ..Errors import CompileError |
|
|
from .. import ExprNodes |
|
|
|
|
|
|
|
|
VALID_UNDERSCORE_LITERALS = [ |
|
|
'0_0_0', |
|
|
'4_2', |
|
|
'1_0000_0000', |
|
|
'0b1001_0100', |
|
|
'0xffff_ffff', |
|
|
'0o5_7_7', |
|
|
'1_00_00.5', |
|
|
'1_00_00.5j', |
|
|
'1_00_00.5e5', |
|
|
'1_00_00j', |
|
|
'1_00_00e5_1', |
|
|
'1e1_0', |
|
|
'.1_4', |
|
|
'.1_4e1', |
|
|
'.1_4j', |
|
|
] |
|
|
|
|
|
|
|
|
INVALID_UNDERSCORE_LITERALS = [ |
|
|
|
|
|
'0_', |
|
|
'42_', |
|
|
'1.4j_', |
|
|
'0b1_', |
|
|
'0xf_', |
|
|
'0o5_', |
|
|
|
|
|
'0_b0', |
|
|
'0_xf', |
|
|
'0_o5', |
|
|
|
|
|
'0b_0', |
|
|
'0x_f', |
|
|
'0o_5', |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'0 if 1_Else 1', |
|
|
|
|
|
'1_.4', |
|
|
'1_.4j', |
|
|
|
|
|
'1._4', |
|
|
'1._4j', |
|
|
'._5', |
|
|
|
|
|
'1.0e+_1', |
|
|
|
|
|
'4_______2', |
|
|
'0.1__4', |
|
|
'0b1001__0100', |
|
|
'0xffff__ffff', |
|
|
'0o5__77', |
|
|
'1e1__0', |
|
|
|
|
|
'1.4_j', |
|
|
'1.4e5_j', |
|
|
|
|
|
'1_e1', |
|
|
'1.4_e1', |
|
|
|
|
|
'1e_1', |
|
|
'1.4e_1', |
|
|
|
|
|
'1_ 2', |
|
|
'1 _2', |
|
|
'1_2.2_ 1', |
|
|
'1_2.2 _1', |
|
|
'1_2e _1', |
|
|
'1_2e2 _1', |
|
|
'1_2e 2_1', |
|
|
] |
|
|
|
|
|
|
|
|
class TestGrammar(CythonTest): |
|
|
|
|
|
def test_invalid_number_literals(self): |
|
|
for literal in INVALID_UNDERSCORE_LITERALS: |
|
|
for expression in ['%s', '1 + %s', '%s + 1', '2 * %s', '%s * 2']: |
|
|
code = 'x = ' + expression % literal |
|
|
try: |
|
|
self.fragment(u'''\ |
|
|
# cython: language_level=3 |
|
|
''' + code) |
|
|
except CompileError as exc: |
|
|
assert code in [s.strip() for s in str(exc).splitlines()], str(exc) |
|
|
else: |
|
|
assert False, "Invalid Cython code '%s' failed to raise an exception" % code |
|
|
|
|
|
def test_valid_number_literals(self): |
|
|
for literal in VALID_UNDERSCORE_LITERALS: |
|
|
for i, expression in enumerate(['%s', '1 + %s', '%s + 1', '2 * %s', '%s * 2']): |
|
|
code = 'x = ' + expression % literal |
|
|
node = self.fragment(u'''\ |
|
|
# cython: language_level=3 |
|
|
''' + code).root |
|
|
assert node is not None |
|
|
|
|
|
literal_node = node.stats[0].rhs |
|
|
if i > 0: |
|
|
|
|
|
literal_node = literal_node.operand2 if i % 2 else literal_node.operand1 |
|
|
if 'j' in literal or 'J' in literal: |
|
|
assert isinstance(literal_node, ExprNodes.ImagNode) |
|
|
elif '.' in literal or 'e' in literal or 'E' in literal and not ('0x' in literal or '0X' in literal): |
|
|
assert isinstance(literal_node, ExprNodes.FloatNode) |
|
|
else: |
|
|
assert isinstance(literal_node, ExprNodes.IntNode) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
import unittest |
|
|
unittest.main() |
|
|
|