Index: Include/token.h =================================================================== --- Include/token.h (revision 77447) +++ Include/token.h (working copy) @@ -60,7 +60,7 @@ #define AT 50 #define RARROW 51 #define ELLIPSIS 52 -/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ +/* Don't forget to update the tables _PyParser_TokenNames and _PyParser_TokenDescs in tokenizer.c! */ #define OP 53 #define ERRORTOKEN 54 #define N_TOKENS 55 @@ -75,6 +75,7 @@ PyAPI_DATA(char *) _PyParser_TokenNames[]; /* Token names */ +PyAPI_DATA(const char *) _PyParser_TokenDescs[]; /* Token descriptions */ PyAPI_FUNC(int) PyToken_OneChar(int); PyAPI_FUNC(int) PyToken_TwoChars(int, int); PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); Index: Parser/tokenizer.c =================================================================== --- Parser/tokenizer.c (revision 77447) +++ Parser/tokenizer.c (working copy) @@ -106,7 +106,66 @@ "" }; +const char *_PyParser_TokenDescs[] = { + "end marker", /* ENDMARKER */ + "name", /* "NAME", */ + "number", /* NUMBER */ + "string", /* STRING" */ + "newline", /* NEWLINE */ + "indent", /* INDENT */ + "de-indent", /* DEDENT */ + "'('", /* LPAR */ + "')'", /* RPAR */ + "'['", /* LSQB */ + "']'", /* RSQB */ + "':'", /* COLON */ + "','", /* COMMA */ + "';'", /* SEMI */ + "'+'", /* PLUS */ + "'-'", /* MINUS */ + "'*'", /* STAR */ + "'/'", /* SLASH */ + "'|'", /* VBAR */ + "'&'", /* AMPER */ + "'<'", /* LESS */ + "'>'", /* GREATER */ + "'='", /* EQUAL */ + "'.'", /* DOT */ + "'%'", /* PERCENT */ + "'{'", /* LBRACE */ + "'}'", /* RBRACE */ + "'=='", /* EQEQUAL */ + "'!='", /* NOTEQUAL */ + "'<='", /* LESSEQUAL */ + "'>='", /* GREATEREQUAL */ + "'~'", /* TILDE */ + "'^'", /* CIRCUMFLEX */ + "'<<'", /* LEFTSHIFT */ + "'>>'", /* RIGHTSHIFT */ + "'**'", /* DOUBLESTAR */ + "'+='", /* PLUSEQUAL */ + "'-='", /* MINEQUAL */ + "'*='", /* STAREQUAL */ + "'/='", /* SLASHEQUAL */ + "'%='", /* PERCENTEQUAL */ + "'&='", /* AMPEREQUAL */ + "'|='", /* VBAREQUAL */ + "'^='", /* CIRCUMFLEXEQUAL */ + "'<<='", /* LEFTSHIFTEQUAL */ + "'>>='", /* RIGHTSHIFTEQUAL */ + "'**='", /* DOUBLESTAREQUAL */ + "'//'", /* DOUBLESLASH */ + "'//='", /* DOUBLESLASHEQUAL */ + "'@'", /* AT */ + "'->'", /* RARROW */ + "'...'", /* ELLIPSIS */ + /* This table must match the #defines in token.h! */ + "OP", /* OP */ + "", /* */ + "" /* token == DEDENT) msg = "unexpected unindent"; else { + char buf[50]; errtype = PyExc_SyntaxError; - msg = "invalid syntax"; + if(err->expected != -1) { + snprintf(buf, 48, "invalid syntax - %.16s expected\0", + _PyParser_TokenDescs[err->expected]); + msg = buf; + } else { + msg = "invalid syntax"; + } } break; case E_TOKEN: Index: Lib/test/test_genexps.py =================================================================== --- Lib/test/test_genexps.py (revision 77447) +++ Lib/test/test_genexps.py (working copy) @@ -87,7 +87,7 @@ >>> dict(a = i for i in range(10)) Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: invalid syntax - ')' expected Verify that parenthesis are required when used as a keyword argument value Index: Lib/test/test_syntax.py =================================================================== --- Lib/test/test_syntax.py (revision 77447) +++ Lib/test/test_syntax.py (working copy) @@ -29,7 +29,7 @@ >>> obj.None = 1 Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: invalid syntax - name expected >>> None = 1 Traceback (most recent call last): @@ -106,17 +106,17 @@ >>> def f(x, None): ... pass Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: invalid syntax - ')' expected >>> def f(*None): ... pass Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: invalid syntax - ')' expected >>> def f(**None): ... pass Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: invalid syntax - name expected From ast_for_funcdef(): @@ -124,7 +124,7 @@ >>> def None(x): ... pass Traceback (most recent call last): -SyntaxError: invalid syntax +SyntaxError: invalid syntax - name expected From ast_for_call():