Skip to content

Commit 74e0063

Browse files
committed
address review: handle more cases (exponent, underscore)
1 parent afe200a commit 74e0063

4 files changed

Lines changed: 16 additions & 6 deletions

File tree

Doc/faq/programming.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ a :exc:`SyntaxError` because the period is seen as a decimal point::
854854
>>> 1.__class__
855855
File "<stdin>", line 1
856856
1.__class__
857-
^
857+
^
858858
SyntaxError: invalid decimal literal
859859

860860
The solution is to separate the literal from the period

Lib/test/test_exceptions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def testSyntaxErrorOffset(self):
299299
check('(0x+1)', 1, 4)
300300
check('x = 0xI', 1, 7)
301301
check('0010 + 2', 1, 1)
302-
check('x = 32e-+4', 1, 8)
302+
check('x = 32e-+4', 1, 9)
303303
check('x = 0o9', 1, 7)
304304
check('\u03b1 = 0xI', 1, 7)
305305
check(b'\xce\xb1 = 0xI', 1, 7)
@@ -322,15 +322,15 @@ def baz():
322322
check("""f'''
323323
{
324324
(123_a)
325-
}'''""", 3, 17)
325+
}'''""", 3, 18)
326326
check("""f'''
327327
{
328328
f\"\"\"
329329
{
330330
(123_a)
331331
}
332332
\"\"\"
333-
}'''""", 5, 17)
333+
}'''""", 5, 18)
334334
check('''f"""
335335
336336

Lib/test/test_grammar.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ def check(test, error=False):
193193
("1jz", 3, "imaginary"),
194194
("0xI", 3, "hexadecimal"),
195195
("0bz", 3, "binary"),
196+
("100_a", 5, " decimal"),
197+
("1.__class__", 3, " decimal"),
198+
("1e+-3", 4, " decimal"),
196199
# SyntaxWarning's currently:
197200
("1or 0", 2, " decimal"),
198201
("0o1or 0", 4, "octal"),

Parser/lexer/number.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) {
4747
* other keyword or identifier.
4848
*/
4949
int r = 0;
50+
int in_exp = 0; /* do we handle exponent now? */
51+
5052
if (c == 'a') {
5153
r = lookahead(tok, "nd");
5254
}
5355
else if (c == 'e') {
5456
r = lookahead(tok, "lse");
57+
in_exp = 1;
5558
}
5659
else if (c == 'f') {
5760
r = lookahead(tok, "or");
@@ -69,6 +72,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) {
6972
else if (c == 'n') {
7073
r = lookahead(tok, "ot");
7174
}
75+
if (in_exp) {
76+
c = tok_nextc(tok);
77+
}
7278
if (r) {
7379
if (_PyTokenizer_parser_warn(tok, PyExc_SyntaxWarning,
7480
"invalid %s literal", kind))
@@ -81,6 +87,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) {
8187
_PyTokenizer_syntaxerror(tok, "invalid %s literal", kind);
8288
return 0;
8389
}
90+
if (in_exp) {
91+
tok_backup(tok, c);
92+
}
8493
return 1;
8594
}
8695

@@ -98,7 +107,6 @@ tok_decimal_tail(struct tok_state *tok)
98107
}
99108
c = tok_nextc(tok);
100109
if (!Py_ISDIGIT(c)) {
101-
tok_backup(tok, c);
102110
_PyTokenizer_syntaxerror(tok, "invalid decimal literal");
103111
return 0;
104112
}
@@ -269,7 +277,6 @@ _PyLexer_scan_number(struct tok_state *tok, struct token *token, int c,
269277
if (c == '+' || c == '-') {
270278
c = tok_nextc(tok);
271279
if (!Py_ISDIGIT(c)) {
272-
tok_backup(tok, c);
273280
return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid decimal literal"));
274281
}
275282
} else if (!Py_ISDIGIT(c)) {

0 commit comments

Comments
 (0)