[Python-Dev] SyntaxError patches
Fred L. Drake, Jr.
fdrake@beopen.com
Tue, 11 Jul 2000 12:22:43 -0400 (EDT)
--GVPtp1TfAH
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit
I wrote:
> At one point, we were discussing having specializations of
> SyntaxError, and I posted a patch that defined IndentationError and
> TabError. With Ping's changes, using these instead of plain
> SyntaxError is trivial. Should I include that, or only change the
> error messages using Ping's patch?
I've attached a combined patch, in case any is interested. This
does not include updated documentation, and could use additional
tests.
-Fred
--
Fred L. Drake, Jr. <fdrake at beopen.com>
BeOpen PythonLabs Team Member
--GVPtp1TfAH
Content-Type: text/plain
Content-Description: combined SyntaxError patch
Content-Disposition: inline;
filename="indentation-error.patch"
Content-Transfer-Encoding: 7bit
*** cvs-python/Include/errcode.h Fri Jun 30 19:58:04 2000
--- python/Include/errcode.h Tue Jul 11 11:06:11 2000
***************
*** 30,37 ****
#define E_NOMEM 15 /* Ran out of memory */
#define E_DONE 16 /* Parsing complete */
#define E_ERROR 17 /* Execution error */
! #define E_INDENT 18 /* Invalid indentation detected */
! #define E_OVERFLOW 19 /* Node had too many children */
#ifdef __cplusplus
}
--- 30,39 ----
#define E_NOMEM 15 /* Ran out of memory */
#define E_DONE 16 /* Parsing complete */
#define E_ERROR 17 /* Execution error */
! #define E_TABSPACE 18 /* Invalid indentation detected */
! #define E_OVERFLOW 19 /* Node had too many children */
! #define E_TOODEEP 20 /* Too many indentation levels */
! #define E_DEDENT 21 /* No matching outer block for dedent */
#ifdef __cplusplus
}
*** cvs-python/Include/parsetok.h Tue Jul 11 12:15:31 2000
--- python/Include/parsetok.h Tue Jul 11 11:04:40 2000
***************
*** 22,27 ****
--- 22,29 ----
int lineno;
int offset;
char *text;
+ int token;
+ int expected;
} perrdetail;
extern DL_IMPORT(node *) PyParser_ParseString(char *, grammar *, int,
*** cvs-python/Lib/test/test_exceptions.py Tue Jun 20 14:52:57 2000
--- python/Lib/test/test_exceptions.py Tue Jul 4 00:36:58 2000
***************
*** 86,91 ****
--- 86,99 ----
try: exec '/\n'
except SyntaxError: pass
+ r(IndentationError)
+
+ r(TabError)
+ # can only be tested under -tt, and is the only test for -tt
+ #try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", '<string>', 'exec')
+ #except TabError: pass
+ #else: raise TestFailed
+
r(SystemError)
print '(hard to reproduce)'
*** cvs-python/Lib/test/output/test_exceptions Sun Jun 25 06:44:57 2000
--- python/Lib/test/output/test_exceptions Tue Jul 4 00:43:31 2000
***************
*** 28,33 ****
--- 28,37 ----
spam
SyntaxError
spam
+ IndentationError
+ spam
+ TabError
+ spam
SystemError
(hard to reproduce)
spam
*** cvs-python/Parser/parser.c Tue Jul 11 12:15:34 2000
--- python/Parser/parser.c Tue Jul 11 11:11:19 2000
***************
*** 205,215 ****
}
int
! PyParser_AddToken(ps, type, str, lineno)
register parser_state *ps;
register int type;
char *str;
int lineno;
{
register int ilabel;
int err;
--- 205,216 ----
}
int
! PyParser_AddToken(ps, type, str, lineno, expected_ret)
register parser_state *ps;
register int type;
char *str;
int lineno;
+ int *expected_ret;
{
register int ilabel;
int err;
***************
*** 285,290 ****
--- 286,300 ----
/* Stuck, report syntax error */
D(printf(" Error.\n"));
+ if (expected_ret) {
+ if (s->s_lower == s->s_upper - 1) {
+ /* Only one possible expected token */
+ *expected_ret = ps->p_grammar->
+ g_ll.ll_label[s->s_lower].lb_type;
+ }
+ else
+ *expected_ret = -1;
+ }
return E_SYNTAX;
}
}
*** cvs-python/Parser/parser.h Tue Jul 11 12:15:34 2000
--- python/Parser/parser.h Tue Jul 11 11:13:02 2000
***************
*** 38,44 ****
parser_state *PyParser_New(grammar *g, int start);
void PyParser_Delete(parser_state *ps);
! int PyParser_AddToken(parser_state *ps, int type, char *str, int lineno);
void PyGrammar_AddAccelerators(grammar *g);
#ifdef __cplusplus
--- 38,45 ----
parser_state *PyParser_New(grammar *g, int start);
void PyParser_Delete(parser_state *ps);
! int PyParser_AddToken(parser_state *ps, int type, char *str, int lineno,
! int *expected_ret);
void PyGrammar_AddAccelerators(grammar *g);
#ifdef __cplusplus
*** cvs-python/Parser/parsetok.c Tue Jul 11 12:15:34 2000
--- python/Parser/parsetok.c Tue Jul 11 11:15:03 2000
***************
*** 139,146 ****
strncpy(str, a, len);
str[len] = '\0';
if ((err_ret->error =
! PyParser_AddToken(ps, (int)type, str,
! tok->lineno)) != E_OK) {
if (err_ret->error != E_DONE)
PyMem_DEL(str);
break;
--- 139,146 ----
strncpy(str, a, len);
str[len] = '\0';
if ((err_ret->error =
! PyParser_AddToken(ps, (int)type, str, tok->lineno,
! &(err_ret->expected))) != E_OK) {
if (err_ret->error != E_DONE)
PyMem_DEL(str);
break;
*** cvs-python/Parser/tokenizer.c Tue Jul 11 12:15:34 2000
--- python/Parser/tokenizer.c Tue Jul 11 11:32:37 2000
***************
*** 412,424 ****
struct tok_state *tok;
{
if (tok->alterror) {
! tok->done = E_INDENT;
tok->cur = tok->inp;
return 1;
}
if (tok->altwarning) {
! PySys_WriteStderr("%s: inconsistent tab/space usage\n",
! tok->filename);
tok->altwarning = 0;
}
return 0;
--- 412,424 ----
struct tok_state *tok;
{
if (tok->alterror) {
! tok->done = E_TABSPACE;
tok->cur = tok->inp;
return 1;
}
if (tok->altwarning) {
! PySys_WriteStderr("%s: inconsistent use of tabs and spaces "
! "in indentation\n", tok->filename);
tok->altwarning = 0;
}
return 0;
***************
*** 484,492 ****
else if (col > tok->indstack[tok->indent]) {
/* Indent -- always one */
if (tok->indent+1 >= MAXINDENT) {
! PySys_WriteStderr(
! "excessive indent\n");
! tok->done = E_TOKEN;
tok->cur = tok->inp;
return ERRORTOKEN;
}
--- 484,490 ----
else if (col > tok->indstack[tok->indent]) {
/* Indent -- always one */
if (tok->indent+1 >= MAXINDENT) {
! tok->done = E_TOODEEP;
tok->cur = tok->inp;
return ERRORTOKEN;
}
***************
*** 506,514 ****
tok->indent--;
}
if (col != tok->indstack[tok->indent]) {
! PySys_WriteStderr(
! "inconsistent dedent\n");
! tok->done = E_TOKEN;
tok->cur = tok->inp;
return ERRORTOKEN;
}
--- 504,510 ----
tok->indent--;
}
if (col != tok->indstack[tok->indent]) {
! tok->done = E_DEDENT;
tok->cur = tok->inp;
return ERRORTOKEN;
}
*** cvs-python/Python/exceptions.c Tue Jul 11 12:15:34 2000
--- python/Python/exceptions.c Sun Jul 9 22:59:18 2000
***************
*** 68,73 ****
--- 68,78 ----
|\n\
+-- AttributeError\n\
+-- SyntaxError\n\
+ | |\n\
+ | +-- IndentationError\n\
+ | |\n\
+ | +-- TabError\n\
+ |\n\
+-- TypeError\n\
+-- AssertionError\n\
+-- LookupError\n\
***************
*** 783,788 ****
--- 788,799 ----
static char
MemoryError__doc__[] = "Out of memory.";
+ static char
+ IndentationError__doc__[] = "Improper indentation.";
+
+ static char
+ TabError__doc__[] = "Improper mixture of spaces and tabs.";
+
/* module global functions */
***************
*** 817,822 ****
--- 828,835 ----
PyObject *PyExc_RuntimeError;
PyObject *PyExc_NotImplementedError;
PyObject *PyExc_SyntaxError;
+ PyObject *PyExc_IndentationError;
+ PyObject *PyExc_TabError;
PyObject *PyExc_SystemError;
PyObject *PyExc_SystemExit;
PyObject *PyExc_UnboundLocalError;
***************
*** 878,883 ****
--- 891,900 ----
{"AttributeError", &PyExc_AttributeError, 0, AttributeError__doc__},
{"SyntaxError", &PyExc_SyntaxError, 0, SyntaxError__doc__,
SyntaxError_methods, SyntaxError__classinit__},
+ {"IndentationError", &PyExc_IndentationError, &PyExc_SyntaxError,
+ IndentationError__doc__},
+ {"TabError", &PyExc_TabError, &PyExc_IndentationError,
+ TabError__doc__},
{"AssertionError", &PyExc_AssertionError, 0, AssertionError__doc__},
{"LookupError", &PyExc_LookupError, 0, LookupError__doc__},
{"IndexError", &PyExc_IndexError, &PyExc_LookupError,
*** cvs-python/Python/pythonrun.c Tue Jul 11 12:15:34 2000
--- python/Python/pythonrun.c Tue Jul 11 12:10:33 2000
***************
*** 14,19 ****
--- 14,20 ----
#include "grammar.h"
#include "node.h"
+ #include "token.h"
#include "parsetok.h"
#include "errcode.h"
#include "compile.h"
***************
*** 983,990 ****
err_input(err)
perrdetail *err;
{
! PyObject *v, *w;
char *msg = NULL;
v = Py_BuildValue("(ziiz)", err->filename,
err->lineno, err->offset, err->text);
if (err->text != NULL) {
--- 984,992 ----
err_input(err)
perrdetail *err;
{
! PyObject *v, *w, *errtype;
char *msg = NULL;
+ errtype = PyExc_SyntaxError;
v = Py_BuildValue("(ziiz)", err->filename,
err->lineno, err->offset, err->text);
if (err->text != NULL) {
***************
*** 993,999 ****
}
switch (err->error) {
case E_SYNTAX:
! msg = "invalid syntax";
break;
case E_TOKEN:
msg = "invalid token";
--- 995,1011 ----
}
switch (err->error) {
case E_SYNTAX:
! errtype = PyExc_IndentationError;
! if (err->expected == INDENT)
! msg = "expected an indented block";
! else if (err->token == INDENT)
! msg = "unexpected indent";
! else if (err->token == DEDENT)
! msg = "unexpected unindent";
! else {
! errtype = PyExc_SyntaxError;
! msg = "invalid syntax";
! }
break;
case E_TOKEN:
msg = "invalid token";
***************
*** 1009,1020 ****
case E_EOF:
msg = "unexpected EOF while parsing";
break;
! case E_INDENT:
msg = "inconsistent use of tabs and spaces in indentation";
break;
case E_OVERFLOW:
msg = "expression too long";
break;
default:
fprintf(stderr, "error=%d\n", err->error);
msg = "unknown parsing error";
--- 1021,1041 ----
case E_EOF:
msg = "unexpected EOF while parsing";
break;
! case E_TABSPACE:
! errtype = PyExc_TabError;
msg = "inconsistent use of tabs and spaces in indentation";
break;
case E_OVERFLOW:
msg = "expression too long";
break;
+ case E_DEDENT:
+ errtype = PyExc_IndentationError;
+ msg = "unindent does not match any outer indentation level";
+ break;
+ case E_TOODEEP:
+ errtype = PyExc_IndentationError;
+ msg = "too many levels of indentation";
+ break;
default:
fprintf(stderr, "error=%d\n", err->error);
msg = "unknown parsing error";
***************
*** 1022,1028 ****
}
w = Py_BuildValue("(sO)", msg, v);
Py_XDECREF(v);
! PyErr_SetObject(PyExc_SyntaxError, w);
Py_XDECREF(w);
}
--- 1043,1049 ----
}
w = Py_BuildValue("(sO)", msg, v);
Py_XDECREF(v);
! PyErr_SetObject(errtype, w);
Py_XDECREF(w);
}
--GVPtp1TfAH--