[Python-Dev] Accessing globals without dict lookup

Guido van Rossum guido@python.org
Mon, 11 Feb 2002 10:02:38 -0500


> Very nice.  One case I would like to see covered is that of a global
> that is deleted.  Something like:
> 
> 
>     import eggs
> 
>     i = -2
>     max = 3
>     j = 4
> 
>     def foo(n):
>         y = abs(i) + max
>         return eggs.ham(y + n)
> 
>     del j
> 
> I presume there would still be an entry in spam's module dict with a
> NULL objptr.

Yes.

> The whole think makes sense to me if it avoids the possible two
> PyDict_GetItem calls in the LOAD_GLOBAL opcode.  As I understand it, if
> accessed inside a function, LOAD_GLOBAL could be implemented something like
> this:
> 
>     case LOAD_GLOBAL:

Surely you meant LOAD_GLOBAL_CELL.

>         cell = func_cells[oparg];
>         if (cell.objptr) x = cell->objptr;
>         else x = cell->cellptr->objptr;
>         if (x == NULL) {
>             ... error recovery ...
>             break;
>         }
>         Py_INCREF(x);
>         continue;
> 
> This looks a lot better to me (no complex function calls).

Here's my version:

       case LOAD_GLOBAL_CELL:
           cell = func_cells[oparg];
           x = cell->objptr;
           if (x == NULL) {
               x = cell->cellptr->objptr;
               if (x == NULL) {
                   ... error recovery ...
                   break;
               }
           }
           Py_INCREF(x);
           continue;

> What happens in the module's top-level code where there is
> presumably no func_cells array?  Do we simply have two different
> opcodes, one for use at the global level and one for use in
> functions?

It could use LOAD_GLOBAL which should use PyMapping_GetItem on the
globals dict.  Or maybe even LOAD_NAME which should do the same.
But we could also somehow create a func_cells array (hm, it would have
to be called differently then I suppose).

(I've added these to the FAQs in PEP 280 too.)

--Guido van Rossum (home page: http://www.python.org/~guido/)