[Python-checkins] python/dist/src/Python newcompile.c, 1.1.2.92, 1.1.2.93 future.c, 2.12.2.6, 2.12.2.7

jhylton at users.sourceforge.net jhylton at users.sourceforge.net
Wed Apr 21 10:42:24 EDT 2004


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

Modified Files:
      Tag: ast-branch
	newcompile.c future.c 
Log Message:
Catch illegal future statements.

Also add XXX comment about how macros like ADDOP_O() don't allow the
caller to cleanup (DECREF) locals before returning.


Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.92
retrieving revision 1.1.2.93
diff -C2 -d -r1.1.2.92 -r1.1.2.93
*** newcompile.c	21 Apr 2004 05:28:06 -0000	1.1.2.92
--- newcompile.c	21 Apr 2004 14:41:24 -0000	1.1.2.93
***************
*** 1006,1009 ****
--- 1006,1013 ----
  */
  
+ /* XXX The returns inside these macros make it impossible to decref
+    objects created in the local function.
+ */
+ 
  
  #define NEW_BLOCK(C) { \
***************
*** 1718,1724 ****
--- 1722,1740 ----
  	for (i = 0; i < n; i++) {
  		alias_ty alias = asdl_seq_GET(s->v.ImportFrom.names, i);
+ 		Py_INCREF(alias->name);
  		PyTuple_SET_ITEM(names, i, alias->name);
  	}
  
+ 	if (s->lineno > c->c_future->ff_lineno) {
+ 		if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module),
+ 			    "__future__")) {
+ 			Py_DECREF(names);
+ 			return compiler_error(c, 
+ 				      "from __future__ imports must occur "
+                                       "at the beginning of the file");
+ 
+ 		}
+ 	}
+ 
  	ADDOP_O(c, LOAD_CONST, names, consts);
  	ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
***************
*** 1739,1744 ****
  			store_name = alias->asname;
  
! 		if (!compiler_nameop(c, store_name, Store))
  			return 0;
  	}
  	if (!star) 
--- 1755,1762 ----
  			store_name = alias->asname;
  
! 		if (!compiler_nameop(c, store_name, Store)) {
! 			Py_DECREF(names);
  			return 0;
+ 		}
  	}
  	if (!star) 

Index: future.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/future.c,v
retrieving revision 2.12.2.6
retrieving revision 2.12.2.7
diff -C2 -d -r2.12.2.6 -r2.12.2.7
*** future.c	21 Mar 2004 19:34:11 -0000	2.12.2.6
--- future.c	21 Apr 2004 14:41:49 -0000	2.12.2.7
***************
*** 50,54 ****
  future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
  {
! 	int i;
  
  	static PyObject *future;
--- 50,54 ----
  future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
  {
! 	int i, found_docstring = 0, done = 0, prev_line = 0;
  
  	static PyObject *future;
***************
*** 61,67 ****
--- 61,81 ----
  	if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
  		return 1;
+ 
+ 	/* A subsequent pass will detect future imports that don't
+ 	   appear at the beginning of the file.  There's one case,
+ 	   however, that is easier to handl here: A series of imports
+ 	   joined by semi-colons, where the first import is a future
+ 	   statement but some subsequent import has the future form
+ 	   but is preceded by a regular import.
+ 	*/
+ 	   
+ 
  	for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
  		stmt_ty s = asdl_seq_GET(mod->v.Module.body, i);
  
+ 		if (done && s->lineno > prev_line)
+ 			return 1;
+ 		prev_line = s->lineno;
+ 
  		/* The tests below will return from this function unless it is
  		   still possible to find a future statement.  The only things
***************
*** 72,88 ****
  		if (s->kind == ImportFrom_kind) {
  			if (s->v.ImportFrom.module == future) {
  				if (!future_check_features(ff, s, filename))
  					return 0;
  			}
  			else
! 				return 1;
  		}
! 		else if (s->kind == Expr_kind) {
  			expr_ty e = s->v.Expr.value;
  			if (e->kind != Str_kind)
! 				return 1;
  		}
  		else
! 			return 1;
  	}
  	return 1;
--- 86,112 ----
  		if (s->kind == ImportFrom_kind) {
  			if (s->v.ImportFrom.module == future) {
+ 				if (done) {
+ 					PyErr_SetString(PyExc_SyntaxError,
+ 							ERR_LATE_FUTURE);
+ 					PyErr_SyntaxLocation(filename, 
+ 							     s->lineno);
+ 					return 0;
+ 				}
  				if (!future_check_features(ff, s, filename))
  					return 0;
+ 				ff->ff_lineno = s->lineno;
  			}
  			else
! 				done = 1;
  		}
! 		else if (s->kind == Expr_kind && !found_docstring) {
  			expr_ty e = s->v.Expr.value;
  			if (e->kind != Str_kind)
! 				done = 1;
! 			else
! 				found_docstring = 1;
  		}
  		else
! 			done = 1;
  	}
  	return 1;
***************
*** 98,104 ****
  	if (ff == NULL)
  		return NULL;
- 	ff->ff_found_docstring = 0;
- 	ff->ff_last_lineno = -1;
  	ff->ff_features = 0;
  
  	if (!future_parse(ff, mod, filename)) {
--- 122,127 ----
  	if (ff == NULL)
  		return NULL;
  	ff->ff_features = 0;
+ 	ff->ff_lineno = -1;
  
  	if (!future_parse(ff, mod, filename)) {




More information about the Python-checkins mailing list