This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: [ast] fix for 1183468: return/yield in class
Type: Stage:
Components: None Versions:
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: nascheme Nosy List: logistix, nascheme
Priority: normal Keywords: patch

Created on 2005-04-16 22:01 by logistix, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
yield_return_in_class_fix.diff logistix, 2005-04-23 19:10 patch to check for yield/return scope
Messages (4)
msg48232 - (view) Author: Grant Olson (logistix) Date: 2005-04-16 22:01
I've got a patch that may or may not be acceptable.  I've 
added a 'u_flags' field to the compiler_unit structure to 
track what sort of block we are in.

This doesn't seem much different that it is in the current 
compiler, there is a boolean  field called 'isfunction' that 
checks for this.

There is a 'block_type' tracked by the symbol table 
entries, but I can't figure out how to harvest it.

Fell free to accept or reject.
msg48233 - (view) Author: Grant Olson (logistix) Date: 2005-04-16 22:04
Logged In: YES 
user_id=699438

Well, the patch attachment is failing due to a sf error with 
problems writing to an 'ArticleFile'.  I'll try again later.  Here it 
is in text for the curious:

Index: python/newcompile.c
=============================================
======================
RCS 
file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.
c,v
retrieving revision 1.1.2.107
diff -u -r1.1.2.107 newcompile.c
--- python/newcompile.c	15 Apr 2005 01:49:23 -0000
	1.1.2.107
+++ python/newcompile.c	16 Apr 2005 21:47:22 -0000
@@ -104,6 +104,13 @@
 /* The following items change on entry and exit of code 
blocks.
    They must be saved and restored when returning to a 
block.
 */
+
+#define UNIT_SCOPE_MODULE	1
+#define UNIT_SCOPE_CLASS	2
+#define UNIT_SCOPE_FUNCTION	4
+#define UNIT_SCOPE_LAMBDA	8
+#define UNIT_SCOPE_GENEXP	16
+
 struct compiler_unit {
 	PySTEntryObject *u_ste;
 
@@ -132,6 +139,8 @@
 	int u_lineno;      /* the lineno for the current stmt */
 	bool u_lineno_set; /* boolean to indicate whether 
instr
 			      has been generated 
with current lineno */
+	
+	unsigned int u_flags; /* only tracks type now */
 };
 
 struct compiler {
@@ -159,7 +168,7 @@
 	int a_lineno_off;      /* bytecode offset of last lineno 
*/
 };
 
-static int compiler_enter_scope(struct compiler *, identifier, 
void *, int);
+static int compiler_enter_scope(struct compiler *, identifier, 
void *, int, unsigned int);
 static void compiler_free(struct compiler *);
 static basicblock *compiler_new_block(struct compiler *);
 static int compiler_next_instr(struct compiler *, basicblock *);
@@ -568,7 +577,7 @@
 
 static int
 compiler_enter_scope(struct compiler *c, identifier name, 
void *key,
-		     int lineno)
+		     int lineno, unsigned int flags)
 {
 	struct compiler_unit *u;
 
@@ -600,6 +609,8 @@
 
         u->u_private = NULL;
 
+	u->u_flags = flags;
+
 	/* A little debugging output */
 	compiler_display_symbols(name, u->u_ste-
>ste_symbols);
 
@@ -1252,7 +1263,7 @@
 		if (!module)
 			return NULL;
 	}
-	if (!compiler_enter_scope(c, module, mod, 1))
+	if (!compiler_enter_scope(c, module, mod, 1, 
UNIT_SCOPE_MODULE))
 		return NULL;
 	switch (mod->kind) {
 	case Module_kind: 
@@ -1396,7 +1407,7 @@
 	if (args->defaults)
 		VISIT_SEQ(c, expr, args->defaults);
 	if (!compiler_enter_scope(c, s-
>v.FunctionDef.name, (void *)s,
-				  s->lineno))
+				  s-
>lineno,UNIT_SCOPE_FUNCTION))
 		return 0;
 
         st = asdl_seq_GET(s->v.FunctionDef.body, 0);
@@ -1461,7 +1472,7 @@
 		VISIT_SEQ(c, expr, s-
>v.ClassDef.bases);
 	ADDOP_I(c, BUILD_TUPLE, n);
 	if (!compiler_enter_scope(c, s->v.ClassDef.name, 
(void *)s,
-				  s->lineno))
+				  s-
>lineno,UNIT_SCOPE_CLASS))
 		return 0;
         c->u->u_private = s->v.ClassDef.name;
         Py_INCREF(c->u->u_private);
@@ -1511,7 +1522,7 @@
 
 	if (args->defaults)
 		VISIT_SEQ(c, expr, args->defaults);
-	if (!compiler_enter_scope(c, name, (void *)e, c->u-
>u_lineno))
+	if (!compiler_enter_scope(c, name, (void *)e, c->u-
>u_lineno,UNIT_SCOPE_LAMBDA))
 		return 0;
 	c->u->u_argcount = asdl_seq_LEN(args->args);
 	VISIT(c, expr, e->v.Lambda.body);
@@ -1992,7 +2003,7 @@
         case ClassDef_kind:
 		return compiler_class(c, s);
         case Return_kind:
-                if (c->c_nestlevel <= 1)
+                if (!(c->u->u_flags & UNIT_SCOPE_FUNCTION))
                         return compiler_error(c, "'return' outside 
function");
 		if (s->v.Return.value) {
 			if (c->u->u_ste-
>ste_generator) {
@@ -2006,7 +2017,7 @@
 		ADDOP(c, RETURN_VALUE);
 		break;
         case Yield_kind:
-                if (c->c_nestlevel <= 1)
+                if (!(c->u->u_flags & UNIT_SCOPE_FUNCTION))
                         return compiler_error(c, "'yield' outside 
function");
 		for (i = 0; i < c->u->u_nfblocks; i++) {
 			if (c->u->u_fblock[i].fb_type 
== FINALLY_TRY)
@@ -2650,7 +2661,7 @@
 	if (!name)
     return 0;
 
-	if (!compiler_enter_scope(c, name, (void *)e, c->u-
>u_lineno))
+	if (!compiler_enter_scope(c, name, (void *)e, c->u-
>u_lineno,UNIT_SCOPE_GENEXP))
 		return 0;
 	compiler_genexp_generator(c, e-
>v.GeneratorExp.generators, 0,
 					e-
>v.GeneratorExp.elt);
Index: lib/test/test_grammar.py
=============================================
======================
RCS 
file: /cvsroot/python/python/dist/src/Lib/test/test_grammar.py,v
retrieving revision 1.40.8.3
diff -u -r1.40.8.3 test_grammar.py
--- lib/test/test_grammar.py	7 Jan 2005 06:59:09 -0000
	1.40.8.3
+++ lib/test/test_grammar.py	16 Apr 2005 21:51:39 -0000
@@ -413,6 +413,7 @@
 def g2(): return 1
 g1()
 x = g2()
+check_syntax("class foo:return 1")
 
 print 'raise_stmt' # 'raise' test [',' test]
 try: raise RuntimeError, 'just testing'
@@ -789,3 +790,7 @@
 x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
 x = 5; t = True;
 verify([(i,j) for i in range(10) for j in range(5)] == list(g))
+
+print 'yield_stmt'
+check_syntax("class foo:yield 1")
+
msg48234 - (view) Author: Grant Olson (logistix) Date: 2005-04-23 19:12
Logged In: YES 
user_id=699438

Sourceforge finally let me upload a real patch file.
msg48235 - (view) Author: Neil Schemenauer (nascheme) * (Python committer) Date: 2005-06-02 05:17
Logged In: YES 
user_id=35752

Using the block type from the symbol table seems like a
better solution.  I checked in a fix.
History
Date User Action Args
2022-04-11 14:56:10adminsetgithub: 41868
2005-04-16 22:01:33logistixcreate