[Python-Dev] peps 329, 266, 267 (original) (raw)
Jewett, Jim J jim.jewett at eds.com
Wed Apr 21 15:02:23 EDT 2004
- Previous message: [Python-Dev] CVS problems?
- Next message: [Python-Dev] peps 329, 266, 267
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
For all other names, the compiler may assume that the nearest enclosing binding of this name will always be in the same namespace. (Names need not all be in a single namespace, but once a particular name is found, that namespace will always be the correct place to look for that name.)
This actually isn't that different from my proposal for builtins,
I had been assuming that class (and instance) attribute resolution would be subject to the same speedup.
If this is really only about globals and builtins, then you can just initialize each module's dictionary with a copy of builtins. (Or cache them in the module dict on the first lookup, since you know where it would have gone.) This still won't catch updates to builtins, but it will eliminate the failed lookup and the second dictionary lookup.
If you really want to track changes to builtin, it is still faster to echo builtin changes across each module than it would be to track every name's referrers in every module (as in PEP 266.)
Instead, names that are determined to be builtin are not allowed to be bound via setattr, and are never looked up in the globals dictionary.
Some of the bugs that got the global tracking backed out involved changing builtins. If you only add to it, then I suppose the current method (which allows shadowing) is a reasonable fallback. It doesn't work so well if you want to remove names from builtin.
In fairness, the language spec does warn that a new builtin dict may contain more than you expect, and I suppose it could be created with extra names pointed to NotImplemented instead of just raising a NameError.
Question: Is there any reason that this should apply only to builtins, rather than to any namespace?
Simplicity. Functions today do only three kinds of lookups: LOADCELL(?), LOADFAST and LOADGLOBAL. LOADCELL is an indirect load from a known, specific nested scope. LOADFAST loads from an array offset into the current frame object. LOADGLOBAL checks globals and then builtins.
It could be converted to LOAD_CELL (or perhaps even LOAD_FAST) if the compiler were allowed to assume no changes in shadowing. (Including an assumption that the same dictionaries will continue to represent the globals and builtin namespaces for this code object.)
if it was desired to disallow shadowing by modifiying globals(), then perhaps globals() and module.dict could simply return a dictionary proxy that prevented modification of the disallowed values. (But the bare dictionary would still be used by the eval loop.)
Why not just make NameDict a subclass that has a different setitem? The times when eval cares should be exactly the times when you need to do extra checks. This also lets you use something like DLict (PEP 267) to move most lookup overhead to compile-time.
-jJ
- Previous message: [Python-Dev] CVS problems?
- Next message: [Python-Dev] peps 329, 266, 267
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]