| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | #include "Python-ast.h"
 | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | #include "node.h"
 | 
					
						
							|  |  |  | #include "token.h"
 | 
					
						
							|  |  |  | #include "graminit.h"
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | #include "code.h"
 | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | #include "compile.h"
 | 
					
						
							|  |  |  | #include "symtable.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename) | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	asdl_seq *names; | 
					
						
							| 
									
										
										
										
											2004-08-31 10:07:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	assert(s->kind == ImportFrom_kind); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	names = s->v.ImportFrom.names; | 
					
						
							|  |  |  | 	for (i = 0; i < asdl_seq_LEN(names); i++) { | 
					
						
							|  |  |  |                 alias_ty name = asdl_seq_GET(names, i); | 
					
						
							| 
									
										
										
										
											2005-12-06 07:26:02 +00:00
										 |  |  | 		const char *feature = PyString_AsString(name->name); | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 		if (!feature) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 		if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { | 
					
						
							| 
									
										
										
										
											2001-08-10 21:41:33 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2001-07-15 21:08:29 +00:00
										 |  |  | 		} else if (strcmp(feature, FUTURE_GENERATORS) == 0) { | 
					
						
							| 
									
										
										
										
											2002-04-12 01:20:10 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2001-08-08 05:00:18 +00:00
										 |  |  | 		} else if (strcmp(feature, FUTURE_DIVISION) == 0) { | 
					
						
							| 
									
										
										
										
											2001-08-10 21:41:33 +00:00
										 |  |  | 			ff->ff_features |= CO_FUTURE_DIVISION; | 
					
						
							| 
									
										
										
										
											2001-02-28 17:47:12 +00:00
										 |  |  | 		} else if (strcmp(feature, "braces") == 0) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_SyntaxError, | 
					
						
							|  |  |  | 					"not a chance"); | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 			PyErr_SyntaxLocation(filename, s->lineno); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			PyErr_Format(PyExc_SyntaxError, | 
					
						
							|  |  |  | 				     UNDEFINED_FUTURE_FEATURE, feature); | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 			PyErr_SyntaxLocation(filename, s->lineno); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-13 18:41:28 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename) | 
					
						
							| 
									
										
										
										
											2001-02-28 01:58:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	int i, found_docstring = 0, done = 0, prev_line = 0; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	static PyObject *future; | 
					
						
							|  |  |  | 	if (!future) { | 
					
						
							|  |  |  | 		future = PyString_InternFromString("__future__"); | 
					
						
							|  |  |  | 		if (!future) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							| 
									
										
										
										
											2001-02-28 02:26:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	/* 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 | 
					
						
							|  |  |  | 		   that can precede a future statement are another future | 
					
						
							|  |  |  | 		   statement and a doc string. | 
					
						
							| 
									
										
										
										
											2001-08-20 20:32:33 +00:00
										 |  |  | 		*/ | 
					
						
							| 
									
										
										
										
											2001-02-28 01:58:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 		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; | 
					
						
							| 
									
										
										
										
											2001-02-28 01:58:08 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 				if (!future_check_features(ff, s, filename)) | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				ff->ff_lineno = s->lineno; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-02-28 01:58:08 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 				done = 1; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 		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; | 
					
						
							| 
									
										
										
										
											2001-02-28 01:58:08 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			done = 1; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | PyFutureFeatures * | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | PyFuture_FromAST(mod_ty mod, const char *filename) | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyFutureFeatures *ff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures)); | 
					
						
							|  |  |  | 	if (ff == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2001-08-10 21:41:33 +00:00
										 |  |  | 	ff->ff_features = 0; | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	ff->ff_lineno = -1; | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 	if (!future_parse(ff, mod, filename)) { | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | 		PyMem_Free((void *)ff); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ff; | 
					
						
							|  |  |  | } |