@@ -1611,29 +1611,30 @@ compiler_mod(struct compiler *c, mod_ty mod)
1611
1611
static int
1612
1612
compiler_get_ref_type (struct compiler * c , PyObject * name )
1613
1613
{
1614
- int scope ;
1615
1614
if (c -> u -> u_scope_type == COMPILER_SCOPE_CLASS &&
1616
1615
(_PyUnicode_EqualToASCIIString (name , "__class__" ) ||
1617
1616
_PyUnicode_EqualToASCIIString (name , "__classdict__" ))) {
1618
1617
return CELL ;
1619
1618
}
1620
1619
PySTEntryObject * ste = SYMTABLE_ENTRY (c );
1621
- scope = _PyST_GetScope (ste , name );
1620
+ int scope = _PyST_GetScope (ste , name );
1622
1621
if (scope == 0 ) {
1623
1622
PyErr_Format (PyExc_SystemError ,
1624
1623
"_PyST_GetScope(name=%R) failed: "
1625
1624
"unknown scope in unit %S (%R); "
1626
- "symbols: %R; locals: %R; globals: %R" ,
1625
+ "symbols: %R; locals: %R; "
1626
+ "globals: %R" ,
1627
1627
name ,
1628
1628
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 );
1630
1631
return ERROR ;
1631
1632
}
1632
1633
return scope ;
1633
1634
}
1634
1635
1635
1636
static int
1636
- compiler_lookup_arg (PyObject * dict , PyObject * name )
1637
+ dict_lookup_arg (PyObject * dict , PyObject * name )
1637
1638
{
1638
1639
PyObject * v = PyDict_GetItemWithError (dict , name );
1639
1640
if (v == NULL ) {
@@ -1642,6 +1643,45 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
1642
1643
return PyLong_AS_LONG (v );
1643
1644
}
1644
1645
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
+
1645
1685
static int
1646
1686
compiler_make_closure (struct compiler * c , location loc ,
1647
1687
PyCodeObject * co , Py_ssize_t flags )
@@ -1653,40 +1693,8 @@ compiler_make_closure(struct compiler *c, location loc,
1653
1693
LOAD_DEREF but LOAD_CLOSURE is needed.
1654
1694
*/
1655
1695
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 );
1690
1698
ADDOP_I (c , loc , LOAD_CLOSURE , arg );
1691
1699
}
1692
1700
flags |= MAKE_FUNCTION_CLOSURE ;
@@ -2460,7 +2468,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
2460
2468
/* Set __classdictcell__ if necessary */
2461
2469
if (SYMTABLE_ENTRY (c )-> ste_needs_classdict ) {
2462
2470
/* 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__ ));
2464
2472
if (i < 0 ) {
2465
2473
compiler_exit_scope (c );
2466
2474
return ERROR ;
@@ -2474,7 +2482,7 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
2474
2482
/* Return __classcell__ if it is referenced, otherwise return None */
2475
2483
if (SYMTABLE_ENTRY (c )-> ste_needs_class_closure ) {
2476
2484
/* 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__ ));
2478
2486
if (i < 0 ) {
2479
2487
compiler_exit_scope (c );
2480
2488
return ERROR ;
0 commit comments