@@ -1611,29 +1611,30 @@ compiler_mod(struct compiler *c, mod_ty mod)
16111611static int
16121612compiler_get_ref_type (struct compiler * c , PyObject * name )
16131613{
1614- int scope ;
16151614 if (c -> u -> u_scope_type == COMPILER_SCOPE_CLASS &&
16161615 (_PyUnicode_EqualToASCIIString (name , "__class__" ) ||
16171616 _PyUnicode_EqualToASCIIString (name , "__classdict__" ))) {
16181617 return CELL ;
16191618 }
16201619 PySTEntryObject * ste = SYMTABLE_ENTRY (c );
1621- scope = _PyST_GetScope (ste , name );
1620+ int scope = _PyST_GetScope (ste , name );
16221621 if (scope == 0 ) {
16231622 PyErr_Format (PyExc_SystemError ,
16241623 "_PyST_GetScope(name=%R) failed: "
16251624 "unknown scope in unit %S (%R); "
1626- "symbols: %R; locals: %R; globals: %R" ,
1625+ "symbols: %R; locals: %R; "
1626+ "globals: %R" ,
16271627 name ,
16281628 c -> u -> u_metadata .u_name , ste -> ste_id ,
1629- ste -> ste_symbols , c -> u -> u_metadata .u_varnames , c -> u -> u_metadata .u_names );
1629+ ste -> ste_symbols , c -> u -> u_metadata .u_varnames ,
1630+ c -> u -> u_metadata .u_names );
16301631 return ERROR ;
16311632 }
16321633 return scope ;
16331634}
16341635
16351636static int
1636- compiler_lookup_arg (PyObject * dict , PyObject * name )
1637+ dict_lookup_arg (PyObject * dict , PyObject * name )
16371638{
16381639 PyObject * v = PyDict_GetItemWithError (dict , name );
16391640 if (v == NULL ) {
@@ -1642,6 +1643,45 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
16421643 return PyLong_AS_LONG (v );
16431644}
16441645
1646+ static int
1647+ compiler_lookup_arg (struct compiler * c , PyCodeObject * co , PyObject * name )
1648+ {
1649+ /* Special case: If a class contains a method with a
1650+ * free variable that has the same name as a method,
1651+ * the name will be considered free *and* local in the
1652+ * class. It should be handled by the closure, as
1653+ * well as by the normal name lookup logic.
1654+ */
1655+ int reftype = compiler_get_ref_type (c , name );
1656+ if (reftype == -1 ) {
1657+ return ERROR ;
1658+ }
1659+ int arg ;
1660+ if (reftype == CELL ) {
1661+ arg = dict_lookup_arg (c -> u -> u_metadata .u_cellvars , name );
1662+ }
1663+ else {
1664+ arg = dict_lookup_arg (c -> u -> u_metadata .u_freevars , name );
1665+ }
1666+ if (arg == -1 ) {
1667+ PyObject * freevars = _PyCode_GetFreevars (co );
1668+ if (freevars == NULL ) {
1669+ PyErr_Clear ();
1670+ }
1671+ PyErr_Format (PyExc_SystemError ,
1672+ "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
1673+ "freevars of code %S: %R" ,
1674+ name ,
1675+ reftype ,
1676+ c -> u -> u_metadata .u_name ,
1677+ co -> co_name ,
1678+ freevars );
1679+ Py_DECREF (freevars );
1680+ return ERROR ;
1681+ }
1682+ return arg ;
1683+ }
1684+
16451685static int
16461686compiler_make_closure (struct compiler * c , location loc ,
16471687 PyCodeObject * co , Py_ssize_t flags )
@@ -1653,40 +1693,8 @@ compiler_make_closure(struct compiler *c, location loc,
16531693 LOAD_DEREF but LOAD_CLOSURE is needed.
16541694 */
16551695 PyObject * name = PyTuple_GET_ITEM (co -> co_localsplusnames , i );
1656-
1657- /* Special case: If a class contains a method with a
1658- free variable that has the same name as a method,
1659- the name will be considered free *and* local in the
1660- class. It should be handled by the closure, as
1661- well as by the normal name lookup logic.
1662- */
1663- int reftype = compiler_get_ref_type (c , name );
1664- if (reftype == -1 ) {
1665- return ERROR ;
1666- }
1667- int arg ;
1668- if (reftype == CELL ) {
1669- arg = compiler_lookup_arg (c -> u -> u_metadata .u_cellvars , name );
1670- }
1671- else {
1672- arg = compiler_lookup_arg (c -> u -> u_metadata .u_freevars , name );
1673- }
1674- if (arg == -1 ) {
1675- PyObject * freevars = _PyCode_GetFreevars (co );
1676- if (freevars == NULL ) {
1677- PyErr_Clear ();
1678- }
1679- PyErr_Format (PyExc_SystemError ,
1680- "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
1681- "freevars of code %S: %R" ,
1682- name ,
1683- reftype ,
1684- c -> u -> u_metadata .u_name ,
1685- co -> co_name ,
1686- freevars );
1687- Py_DECREF (freevars );
1688- return ERROR ;
1689- }
1696+ int arg = compiler_lookup_arg (c , co , name );
1697+ RETURN_IF_ERROR (arg );
16901698 ADDOP_I (c , loc , LOAD_CLOSURE , arg );
16911699 }
16921700 flags |= MAKE_FUNCTION_CLOSURE ;
@@ -2460,7 +2468,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
24602468 /* Set __classdictcell__ if necessary */
24612469 if (SYMTABLE_ENTRY (c )-> ste_needs_classdict ) {
24622470 /* Store __classdictcell__ into class namespace */
2463- int i = compiler_lookup_arg (c -> u -> u_metadata .u_cellvars , & _Py_ID (__classdict__ ));
2471+ int i = dict_lookup_arg (c -> u -> u_metadata .u_cellvars , & _Py_ID (__classdict__ ));
24642472 if (i < 0 ) {
24652473 compiler_exit_scope (c );
24662474 return ERROR ;
@@ -2474,7 +2482,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
24742482 /* Return __classcell__ if it is referenced, otherwise return None */
24752483 if (SYMTABLE_ENTRY (c )-> ste_needs_class_closure ) {
24762484 /* Store __classcell__ into class namespace & return it */
2477- int i = compiler_lookup_arg (c -> u -> u_metadata .u_cellvars , & _Py_ID (__class__ ));
2485+ int i = dict_lookup_arg (c -> u -> u_metadata .u_cellvars , & _Py_ID (__class__ ));
24782486 if (i < 0 ) {
24792487 compiler_exit_scope (c );
24802488 return ERROR ;
0 commit comments