How do you create constants?/immutable dicts

KevinL darius at bofh.net.au
Mon Nov 6 18:48:28 CET 2000


(I'm assuming this one follows my post the other day, 'cause it mentions 
immutable dicts, and I've been thinking about them lately.  Apologies to 
anyone who doesn't want to hear about my own little toy projects)

>>> Steve Horne wrote
> OK, I can understand your concern, but even so - in any language there
> are ways to break the const-ness of data. In C and C++, for example,
> you can directly typecast using const_cast which exists precisely for
> that purpose. In pascal, you'd probably have to use pointer tricks,
> but it could be done. At the end of the day, const-ness is only
> assured when the data is in ROM - not likely in a desktop app.

Except, where you control the context in which alien code can be executed.

Lemme give you the example I've been working with, that leads me to believe 
immutable dictionaries in particular would be a useful construct.  I've got a 
project, Moebius, which is 9/10ths of the way to being a fully fledged 
multi-user python - it provides persistant objects, upon which you can hang 
various (picklable) data structures.  It provides a scripting engine, by 
virtue of some bytecode trickery and various interesting namespace games, so 
that you can define and execute your own methods, shovel data around however 
you like, etc. etc.  It even has a little XMLish interface, which someone's 
trying to turn into a way to ship python objects from place to place and 
RPC-reference them, ala corba.  Anyways.

In giving people the ability to script within the engine, all sorts of 
interesting challenges come up - the one that interests me particularly in 
this case is "how do I give everyone a stable of standard 'safe' builtins 
etc - a reliable global namespace?"  Every time a function is executed
(actually, every time it's "compiled"), it has to have a global namespace
attached to it.

Now, here's where things get fun:  If I use a dictionary for my global 
namespace, I can guarantee some smart sod will change items in the global 
namespace - in fact, one of the first people on, many months ago, replaced the 
time module with None, which wreaked havoc.  So, I moved to a dictionary with 
a little "read-only" class pretending to be a dictionary, for it's 
__builtins__.  All well and good, but we've still got basically the same 
problem - people can reach up and change things in the global namespace (even 
if they can't reach the stuff inside __builtins__ to change it).

Here's the nasty bit:  Because there's a fundamental difference between 
dictionaries and anything you can create, you cannot bind user objects to 
functions/methods as their namespace - python spits it.  So I _can't_ protect 
that namespace.  The best I can do is make a new copy of it every time I bind 
a function to a different object.  Which a) feels kludgy, b) complicates 
things refcount-wise when I put interesting things in that namespace.

What I'd love to do is simply build the global namespace dictionary, call an 
"immutable(1)" method on it, and rest easy knowing that the dictionary cannot 
be changed from the restricted execution space users are playing in.  It's 
worth noting that, if you can do that, you've essentially got const variables 
- because python's so namespace-centric, simply executing code in a namespace 
you can't change basically means that the items in that namespace are consts 
(excepting the potential for overriding them in the local namespace, which I'm 
not concerned about because python doesn't have a hierarchical namespace, so 
the only person a method writer is kidding by doing that is themselves - no 
call they make will inherit their local namespace changes).

That's basically the problem I'm facing.  I know it's fairly specific, but I 
have trouble believing I'm the only one to come across this.  The restricted 
execution setup is almost really really useful - if I had more control over 
the namespaces it existed in, I'd be ultra-happy ;)  I agree with you that in 
normal use, there's various ways to get around it - but mixed in with a couple 
of the other standard python constructs, and it does get more useful.

I'd also be happy if the difference between dictionaries and my own 
class-based objects were done away with - but I still think even if that 
happened, immutable dictionaries would be a useful construct to have handy.  I 
don't believe this change would impact python negatively - other than the 
potential speed impact (which should be marginal anyway by rights), it simply 
works toward making dictionaries a little more useful, by implementing in them 
one of the more common reasons people resort to using their own 
dictionary-like classes.

I've been hunting through the archives, and unfortunately can't turn up any 
previous discussion, tho I'm fairly sure there must have been.  If anyone has 
any pointers as to why immutable dictionaries are a dumb idea, please let me 
know ;)

KL
(BTW, I made a really kludgy patch, that actually appeared to work but will 
probably break in interesting ways, and unfortunately places it's checks right 
in the line of execution, but does give the above "immutable()" method, at 
http://www.bofh.net.au/snippets/  Ideally, executing immutable(1) would simply 
change PyDict_SetItem to be a new function raising an error, but various other 
places in the code go straight to that function rather than through the 
PyMethodDef at the bottom, so it'd be a more wide-ranging (and probably higher 
impact) change anyway.)





More information about the Python-list mailing list