[Python-Dev] Fast access to __builtins__

Guido van Rossum guido@python.org
Thu, 27 Mar 2003 23:49:16 -0500


> It seems like C extensions pose thorny problems that need to be solved. 
> In particular, the C API says that module's have a dictionary and that
> adding a key creates global variable in the module.  We'll have to break
> this one way or another, because we don't want to allow C extensions to
> add globals that shadow builtins.  Right?

I don't see the problem.  Typically, C extension modules don't have
Python code that runs in their globals, so messing with a C
extension's globals from the outside has no bad effect on Python code.

The problem is more that once a module is loaded, you can't tell from
the module whether it was loaded from a .py module or a C extension.

> There's a similar problem for Python code, but I imagine it's easy to
> come up with a dict proxy with the necessary restrictions along the
> lines of a new-style class dict proxy.

I'd be happy to proclaim that doing something like

  import X
  d = X.__dict__
  d["spam"] = 42    # or  exec "spam = 42" in d 

is always prohibited.

> How do we break the C API?  There's lots of extension code that relies
> on getting the dict.  My first guess is to add an exception that says
> setting a name that shadows a builtin has no effect.  Then extend the
> getattr code and the module-dict-proxy to ignore those names.

The C code can continue to access the real dict.  This is what happens
for new-style classes: in Python, C.__dict__ is a read-only proxy, but
in C, C->tp_dict is a real dict.  Then the setattr operation can do as
it pleases.  For new-style classes, it doesn't forbid anything but
updates the type struct when an operator was modified; for modules, it
could issue a warning when a name is set that didn't exist before and
that shadows a built-in.  (Ideally, it should only warn about
built-ins that are actually used by the module's code, but that
requires the parser to make the list of such built-ins available
somehow.)

Anyway, the C code that accesses the dict usually lives in the
extension module's init function.

Frankly, I'm a bit confused by your post.  Maybe I don't understand
what you're proposing?

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