changeset: 70889:2d62ee4e7d98 parent: 70881:5dd75cdd445a user: Benjamin Peterson date: Sun Jun 19 19:42:22 2011 -0500 files: Lib/test/test_super.py Misc/NEWS Objects/typeobject.c Python/compile.c Python/symtable.c description: use a invalid name for the __class__ closure for super() (closes #12370) This prevents the assignment of __class__ in the class body from breaking super. (Although a determined person could do locals()["@__class__"] = 4) diff -r 5dd75cdd445a -r 2d62ee4e7d98 Lib/test/test_super.py --- a/Lib/test/test_super.py Sun Jun 19 17:49:22 2011 -0500 +++ b/Lib/test/test_super.py Sun Jun 19 19:42:22 2011 -0500 @@ -81,6 +81,16 @@ self.assertEqual(E().f(), 'AE') + def test___class___set(self): + # See issue #12370 + class X(A): + def f(self): + return super().f() + __class__ = 413 + x = X() + self.assertEqual(x.f(), 'A') + self.assertEqual(x.__class__, 413) + def test_main(): support.run_unittest(TestSuper) diff -r 5dd75cdd445a -r 2d62ee4e7d98 Misc/NEWS --- a/Misc/NEWS Sun Jun 19 17:49:22 2011 -0500 +++ b/Misc/NEWS Sun Jun 19 19:42:22 2011 -0500 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12370: Fix super with not arguments when __class__ is overriden in the + class body. + - Issue #12084: os.stat on Windows now works properly with relative symbolic links when called from any directory. diff -r 5dd75cdd445a -r 2d62ee4e7d98 Objects/typeobject.c --- a/Objects/typeobject.c Sun Jun 19 17:49:22 2011 -0500 +++ b/Objects/typeobject.c Sun Jun 19 19:42:22 2011 -0500 @@ -6399,7 +6399,7 @@ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); assert(PyUnicode_Check(name)); if (!PyUnicode_CompareWithASCIIString(name, - "__class__")) { + "@__class__")) { Py_ssize_t index = co->co_nlocals + PyTuple_GET_SIZE(co->co_cellvars) + i; PyObject *cell = f->f_localsplus[index]; diff -r 5dd75cdd445a -r 2d62ee4e7d98 Python/compile.c --- a/Python/compile.c Sun Jun 19 17:49:22 2011 -0500 +++ b/Python/compile.c Sun Jun 19 19:42:22 2011 -0500 @@ -1566,7 +1566,7 @@ return 0; } /* return the (empty) __class__ cell */ - str = PyUnicode_InternFromString("__class__"); + str = PyUnicode_InternFromString("@__class__"); if (str == NULL) { compiler_exit_scope(c); return 0; diff -r 5dd75cdd445a -r 2d62ee4e7d98 Python/symtable.c --- a/Python/symtable.c Sun Jun 19 17:49:22 2011 -0500 +++ b/Python/symtable.c Sun Jun 19 19:42:22 2011 -0500 @@ -225,10 +225,17 @@ struct symtable * PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) { - struct symtable *st = symtable_new(); + struct symtable *st; asdl_seq *seq; int i; + if (__class__ == NULL) { + __class__ = PyUnicode_InternFromString("@__class__"); + if (__class__ == NULL) + return NULL; + } + + st = symtable_new(); if (st == NULL) return st; st->st_filename = filename; @@ -744,8 +751,6 @@ } else { /* Special-case __class__ */ - if (!GET_IDENTIFIER(__class__)) - goto error; assert(PySet_Contains(local, __class__) == 1); if (PySet_Add(newbound, __class__) < 0) goto error; @@ -783,7 +788,7 @@ NULL)) goto error; else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree, - "__class__")) + "@__class__")) goto error; /* Records the results of the analysis in the symbol table entry */ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, @@ -1143,8 +1148,7 @@ if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, s->lineno, s->col_offset)) return 0; - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, DEF_LOCAL) || + if (!symtable_add_def(st, __class__, DEF_LOCAL) || !GET_IDENTIFIER(__locals__) || !symtable_add_def(st, __locals__, DEF_PARAM)) { symtable_exit_block(st, s); @@ -1417,8 +1421,7 @@ if (e->v.Name.ctx == Load && st->st_cur->ste_type == FunctionBlock && !PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) { - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE)) + if (!symtable_add_def(st, __class__, USE)) return 0; } break;

AltStyle によって変換されたページ (->オリジナル) /