freezing structures.

Aaron Watters (aaron@funcity.njit.edu)
Fri, 3 Mar 1995 13:22:55 GMT

A LESS EMBARASSING POST:
I just sent Guido a patch that he said he liked but it was too
late to get it into 1.2 -- If anyone wants it for 1.1.1 they can
have it.

The patch allows various objects to be frozen
(marked immutable). In particular things like modules and classes
can be frozen to enforce modularity. For example if I want to
make sure that nobody can redefine the global bindings of a module
the patch allows me to assert
freeze(module)
and any subsequent attempt to rebind
module.RealNeatFunction = TrojanHorse
will raise a "ValueError, cannot mutate; object is marked immutable".
This might be of particular interest if you ever "exec" strings
some creep passed to you over the net.

PYTHON LEVEL VIEW
=================
At the python level there are two new
builtins.
freeze(object)
-- marks an object as immutable if possible or raises
a TypeError if no freeze method is defined, or passes
on an error from the freeze method of the objects type.
If no error, returns None.
mutable(object)
-- returns 0 if the object is mutable, else 1.
Never raises an error.

I've added the ability to freeze
class, instance, mapping, module
In addition, I added a hash(dict) method that works only if the
dictionary is frozen (and all values are hashable).

EG:
=====
>>> D = {} # a dictionary
>>> D[2] = 3 # a mutation
>>> mutable(D)
1
>>> freeze(D) # make it immutable
>>> mutable(D)
0
>>> D[2] = 4
ValueError: cannot mutate; object is marked immutable
>>> hash(D)
572432
>>> {D:4} # use D as a key!
{{2: 3}: 4}
>>> hash({}) # but we can't hash a mutable dict.
ValueError: cannot hash mutable mapping
>>> class cl: # class
... pass
...
>>> cl.this = "that" # a mutation
>>> mutable(cl)
1
>>> freeze(cl) # freeze cl
>>> cl.that = "this" # try to mutate
ValueError: cannot mutate; object is marked immutable
>>> mutable(cl)
0
>>> inst = cl() # an instance
>>> inst.this = 1 # a mutation
>>> mutable(inst)
1
>>> freeze(inst) # freeze inst
>>> mutable(inst)
0
>>> inst.this = 2 # try to mutate
ValueError: cannot mutate; object is marked immutable
>>> import kjSet # get a module
>>> kjSet.garbage = "whoops" # pollute the module
>>> mutable(kjSet)
1
>>> freeze(kjSet) # freeze the module
>>> kjSet.junk = "Noone should ever do this"
ValueError: cannot mutate; object is marked immutable
>>> kjSet.junk
AttributeError: junk
======

I've added default behaviors for immutables
int, float, range, tuple, long, None, instance_method, type
If one of these isn't actually immutable, the patch should be patched.

EG:
=====
>>> class y:
... def f(self):
... return 1
...
>>> for x in (1, "this", (1,2), 1.0, 2736187632L, y.f, None, type({})):
... print x, mutable(x), freeze(x)
...
1 0 None
this 0 None
(1, 2) 0 None
1.0 0 None
2736187632L 0 None
<unbound method y.f> 0 None
None 0 None
<type 'dictionary'> 0 None
=====

I left lists alone (actually, I backed out a mod) because tuples
are already immutable lists, so there is no reason to add overhead
to lists (especially since the interpreter uses them).

======
>>> list = [1,2,6]
>>> freeze(list)
Traceback (innermost last):
File "<stdin>", line 1, in ?
TypeError: no freeze method defined
>>> mutable(list)
1
======

files, accesses, frames, funcs(?), and methods also default
to "mutable only" behavior (some of them because I didn't understand
them well enough to mess them up).

Let me know if you'd like to see it.
Aaron Watters
Department of Computer and Information Sciences
New Jersey Institute of Technology
University Heights
Newark, NJ 07102
phone (201)596-2666
fax (201)596-5777
home phone (908)545-3367
email: aaron@vienna.njit.edu
===

Want a multicultural musical experience? Get Inti-Ilimani's _Andadas_
CD. Okay, they're a bunch of white guys, but on the other hand
they're from Chile, they're unreformed communists, and they like to
dress up in traditional South American cloths and pound away at
traditional Latin American instruments because it makes them feel less
guilty. In spite of all that the music's not all that bad. While I
was at one of their concerts in Managua, Nicaragua, a gang lead by a
man they call Pineapple-face took many of the more important
politicians of the country hostage four blocks away (I think this was
a coincidence). I had to detour through some of the nastier parts of
Managua with my wife and 4 year old daughter on the way home to avoid
rioting mobs. You can't make this stuff up.