How do you create constants?/immutable dicts
KevinL
darius at bofh.net.au
Mon Nov 6 12:48:28 EST 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