[Python-checkins] python/dist/src/Python ast.c, 1.1.2.49, 1.1.2.50 pythonrun.c, 2.161.2.12, 2.161.2.13

jhylton at users.sourceforge.net jhylton at users.sourceforge.net
Wed Apr 21 13:45:14 EDT 2004


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5803/Python

Modified Files:
      Tag: ast-branch
	ast.c pythonrun.c 
Log Message:
Improved error handling inside ast.c; fixes test_syntax.

Add ast_error() that captures line number of error and
ast_finish_error() to assign filename and location.  It's a little
complicated this way, but less intrusive than passing the filename to
every ast function that might raise an exception.

Need to pass filename to PyAST_FromNode() for error handling.


Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.49
retrieving revision 1.1.2.50
diff -C2 -d -r1.1.2.49 -r1.1.2.50
*** ast.c	13 Apr 2004 17:11:43 -0000	1.1.2.49
--- ast.c	21 Apr 2004 17:45:09 -0000	1.1.2.50
***************
*** 42,45 ****
--- 42,103 ----
  extern grammar _PyParser_Grammar; /* From graminit.c */
  
+ #ifndef LINENO
+ #define LINENO(n)	((n)->n_lineno)
+ #endif
+ 
+ #define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
+ 
+ /* This routine provides an invalid object for the syntax error.
+    The outermost routine must unpack this error and create the
+    proper object.  We do this so that we don't have to pass
+    the filename to everything function.
+ 
+    XXX Maybe we should just pass the filename...
+ */
+ 
+ static int
+ ast_error(const node *n, const char *errstr)
+ {
+     PyObject *u = Py_BuildValue("zi", errstr, LINENO(n));
+     if (!u)
+ 	return 0;
+     PyErr_SetObject(PyExc_SyntaxError, u);
+     Py_DECREF(u);
+     return 0;
+ }
+ 
+ static void
+ ast_error_finish(const char *filename)
+ {
+     PyObject *type, *value, *tback, *errstr, *loc, *tmp;
+     int lineno;
+ 
+     assert(PyErr_Occurred());
+     PyErr_Fetch(&type, &value, &tback);
+     errstr = PyTuple_GetItem(value, 0);
+     if (!errstr)
+ 	return;
+     Py_INCREF(errstr);
+     lineno = PyInt_AsLong(PyTuple_GetItem(value, 1));
+     if (lineno == -1)
+ 	return;
+     Py_DECREF(value);
+ 
+     loc = PyErr_ProgramText(filename, lineno);
+     if (!loc) {
+ 	Py_INCREF(Py_None);
+ 	loc = Py_None;
+     }
+     tmp = Py_BuildValue("(ziOO)", filename, lineno, Py_None, loc);
+     Py_DECREF(loc);
+     if (!tmp)
+ 	return;
+     value = Py_BuildValue("(OO)", errstr, tmp);
+     Py_DECREF(errstr);
+     Py_DECREF(tmp);
+     if (!value)
+ 	return;
+     PyErr_Restore(type, value, tback);
+ }
  
  /* num_stmts() returns number of contained statements.
***************
*** 108,112 ****
  
  mod_ty
! PyAST_FromNode(const node *n, PyCompilerFlags *flags)
  {
      int i, j, num;
--- 166,170 ----
  
  mod_ty
! PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename)
  {
      int i, j, num;
***************
*** 125,129 ****
      }
  
- 
      switch (TYPE(n)) {
          case file_input:
--- 183,186 ----
***************
*** 167,171 ****
                  stmts = asdl_seq_new(1);
                  if (!stmts)
!                     return NULL;
                  asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
                  return Interactive(stmts);
--- 224,228 ----
                  stmts = asdl_seq_new(1);
                  if (!stmts)
! 		    goto error;
                  asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
                  return Interactive(stmts);
***************
*** 176,182 ****
                  stmts = asdl_seq_new(num);
                  if (!stmts)
!                     return NULL;
                  if (num == 1) {
!                     asdl_seq_SET(stmts, 0, ast_for_stmt(&c, n));
                  }
                  else {
--- 233,242 ----
                  stmts = asdl_seq_new(num);
                  if (!stmts)
! 		    goto error;
                  if (num == 1) {
! 		    stmt_ty s = ast_for_stmt(&c, n);
! 		    if (!s)
! 			goto error;
!                     asdl_seq_SET(stmts, 0, s);
                  }
                  else {
***************
*** 202,216 ****
      if (stmts)
  	asdl_seq_free(stmts);
!     fprintf(stderr, "error in PyAST_FromNode() exc? %c\n",
!             PyErr_Occurred() ? 'Y': 'N');
      return NULL;
  }
  
- #ifndef LINENO
- #define LINENO(n)	((n)->n_lineno)
- #endif
- 
- #define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
- 
  /* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
  */
--- 262,269 ----
      if (stmts)
  	asdl_seq_free(stmts);
!     ast_error_finish(filename);
      return NULL;
  }
  
  /* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
  */
***************
*** 275,279 ****
  
  static int
! set_context(expr_ty e, expr_context_ty ctx)
  {
      asdl_seq *s = NULL;
--- 328,332 ----
  
  static int
! set_context(expr_ty e, expr_context_ty ctx, const node *n)
  {
      asdl_seq *s = NULL;
***************
*** 281,314 ****
      switch (e->kind) {
          case Attribute_kind:
!             e->v.Attribute.ctx = ctx;
!             break;
          case Subscript_kind:
!             e->v.Subscript.ctx = ctx;
!             break;
          case Name_kind:
!             e->v.Name.ctx = ctx;
!             break;
          case List_kind:
!             e->v.List.ctx = ctx;
!             s = e->v.List.elts;
!             break;
          case Tuple_kind:
!             e->v.Tuple.ctx = ctx;
!             s = e->v.Tuple.elts;
!             break;
          default:
! 	    /* XXX It's not clear why were't getting into this code,
! 	       although list comps seem like one possibility.
! 
!                This occurs in at least 2 cases:
!                  [x(i) for i in range(3)] # Call_kind (8)
!                  [i*2 for i in range(3)]  # BinOp_kind (2)
! 
!                The byte code generated seems to work fine.
!                Maybe there's a problem with nested list comps?
! 	    */
! 	    abort();
! 	    fprintf(stderr, "can't set context for %d\n", e->kind);
!             return 0;
      }
      if (s) {
--- 334,364 ----
      switch (e->kind) {
          case Attribute_kind:
! 	    e->v.Attribute.ctx = ctx;
! 	    break;
          case Subscript_kind:
! 	    e->v.Subscript.ctx = ctx;
! 	    break;
          case Name_kind:
! 	    e->v.Name.ctx = ctx;
! 	    break;
          case List_kind:
! 	    e->v.List.ctx = ctx;
! 	    s = e->v.List.elts;
! 	    break;
          case Tuple_kind:
! 	    e->v.Tuple.ctx = ctx;
! 	    s = e->v.Tuple.elts;
! 	    break;
!         case Call_kind:
! 	    if (ctx == Store)
! 		return ast_error(n, "can't assign to function call");
! 	    else if (ctx == Del)
! 		return ast_error(n, "can't delete function call");
! 	    else
! 		return ast_error(n, "unexpected operation on function call");
! 	    break;
          default:
! 	    return ast_error(n, "unexpected node in assignment");
! 	    break;
      }
      if (s) {
***************
*** 316,324 ****
  
  	for (i = 0; i < asdl_seq_LEN(s); i++) {
! 	    if (set_context(asdl_seq_GET(s, i), ctx) < 0)
! 		return -1;
  	}
      }
!     return 0;
  }
  
--- 366,374 ----
  
  	for (i = 0; i < asdl_seq_LEN(s); i++) {
! 	    if (!set_context(asdl_seq_GET(s, i), ctx, n))
! 		return 0;
  	}
      }
!     return 1;
  }
  
***************
*** 1348,1352 ****
      }
      else {
! 	int i, tmp;
  	asdl_seq *targets;
          expr_ty expression;
--- 1398,1402 ----
      }
      else {
! 	int i;
  	asdl_seq *targets;
          expr_ty expression;
***************
*** 1364,1369 ****
  		return NULL;
  	    }
! 	    tmp = set_context(e, Store);
!             if (tmp == -1) {
                  asdl_seq_free(targets);
                  return NULL;
--- 1414,1418 ----
  		return NULL;
  	    }
! 	    if (!set_context(e, Store, CHILD(n, i))) {
                  asdl_seq_free(targets);
                  return NULL;
***************
*** 1430,1435 ****
  	}
  	if (context) {
!             int context_result = set_context(e, context);
! 	    if (context_result == -1)
                  return NULL;
          }
--- 1479,1483 ----
  	}
  	if (context) {
! 	    if (!set_context(e, context, CHILD(n, i)))
                  return NULL;
          }
***************
*** 2037,2041 ****
  	if (!e)
              return NULL;
! 	if (set_context(e, Store) == -1)
              return NULL;
          expression = ast_for_expr(c, CHILD(exc, 1));
--- 2085,2089 ----
  	if (!e)
              return NULL;
! 	if (!set_context(e, Store, CHILD(exc, 3)))
              return NULL;
          expression = ast_for_expr(c, CHILD(exc, 1));

Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.161.2.12
retrieving revision 2.161.2.13
diff -C2 -d -r2.161.2.12 -r2.161.2.13
*** pythonrun.c	13 Apr 2004 15:04:01 -0000	2.161.2.12
--- pythonrun.c	21 Apr 2004 17:45:10 -0000	2.161.2.13
***************
*** 1175,1179 ****
  				      PARSER_FLAGS(flags));
  	if (n) {
! 		mod = PyAST_FromNode(n, flags);
  		PyNode_Free(n);
  		return mod;
--- 1175,1179 ----
  				      PARSER_FLAGS(flags));
  	if (n) {
! 		mod = PyAST_FromNode(n, flags, filename);
  		PyNode_Free(n);
  		return mod;
***************
*** 1195,1199 ****
  				    ps1, ps2, &err, PARSER_FLAGS(flags));
  	if (n) {
! 		mod = PyAST_FromNode(n, flags);
  		PyNode_Free(n);
  		return mod;
--- 1195,1199 ----
  				    ps1, ps2, &err, PARSER_FLAGS(flags));
  	if (n) {
! 		mod = PyAST_FromNode(n, flags, filename);
  		PyNode_Free(n);
  		return mod;




More information about the Python-checkins mailing list