Hi Frank-Rene, and welcome. Comments below.
On Mon, 11 Nov 2013 21:47:45 +0100, Frank-Rene Schäfer wrote: > I prepared a PEP and was wondering what your thoughts are about it: > > PEP: <pep number> > Title: ``isimmutable(Obj)`` and/or ``ImmutableNester`` [...] > * Python-Version: 2.7.1 That won't do. Python 2.7 is in maintenance mode, it will not gain any new functionality. There won't be a Python 2.8 either. If you want to propose new functionality, it will have to go into 3.5. (You've missed the opportunity for 3.4, since "feature-freeze" is only weeks away.) > General Idea > ============ > > A built-in function 'isimmutable()' shall tell efficiently whether the > object of concern is mutable or not. That is it must reflect on the > whole object tree whether it contains mutable elements or not. For > example, in the code fragment This has been proposed before. It has failed because there is no way to tell in general whether an arbitrary object is immutable or not. If you only look at the common built-in types, it is quite trivial, e.g.: - int, str, bytes, float, frozenset, bool, None are immutable; - list, dict, set are not immutable; - tuple is immutable if all of its elements are immutable. But as soon as you allow arbitrary objects, you're in trouble. How do you tell whether an object is immutable? I recommend that you start by writing a reference implementation: def isimmutable(obj): ... # ? Some obvious thoughts: - It is not enough to include a big list of immutable classes: # don't do this if isinstance(obj, (float, int, frozenset, ...)): return True because that list will never be complete and can become out-of-date. - You could try writing to the object (how?), and if it succeeds, you know it is mutable. But if it fails, that might just mean that you haven't tried writing to it in the correct manner. - But if the obj is mutable, you've just mutated it. That's bad. - You can try hashing the object: hash(obj) If that fails, then the object *might as well* be mutable, since you can't use it in sets or as dict keys. But if that's all isimmutable() does, why not just call hash(obj) directly? Anyway, I recommend you spend some time on this exercise. The PEP will not be accepted without a reference implementation, so you're going to have to do it at some point. Another thing which your proto-PEP fails to cover in sufficient detail is why you think such a function and/all class would be useful. You do say this: > If an object is immutable then copying of it can be safely be replaced > by a setting of a reference. The principal scenario is when an instance > A gives an instance B access to some data D under the provision that B > does not change it. Therefore, B must either clone the data or it must > be safe to assume that the data cannot change, i.e. is immutable. but I really don't think much of this as the principle scenario. I don't think I've ever written code that matches this scenario. If possible, you should give a real example. If not real, at least a toy example. Either way, using code rather than just a vague description is better. > If the objects are large and/or many there a significant performance > impact may raise from a deepcopy or manual cloning of objects. > Therefore, the ``isimmutable()`` built-in function is key for a safe > implementation of reference-instead-of-copying. I don't think this is true. deepcopy (at least sometimes) will avoid making a copy if the object is immutable: py> import copy py> x = (10001, 20002, 30003, (40004, 50005, (60006, 70007)), 80008) py> copy.copy(x) is x True py> copy.deepcopy(x) is x True so what advantage does isimmutable give you? > Ensuring immutability is also key for the so called 'Flyweight Design > Pattern'. More details please. Ultimately, nothing knows whether an object is immutable or not better than the object itself. copy.copy and copy.deepcopy know this, and ask the object to copy itself rather than copy it from the outside. Since the object knows whether it is immutable, it knows whether or not to make a copy or just return itself. It seems to me that isimmutable() *appears* to be a useful function to have, but if you look into it in detail the apparently uses for it don't hold up. In practice, it would be almost impossible to implement (except as below) and even if you could you would never need it. Really, it seems to me that the only way to implement isimmutable would be to delegate to the object: def isimmutable(obj): return obj.__isimmutable__() This gives you: if isimmutable(obj): x = obj else: x = copy.copy(obj) function_that_might_modify(x) but that gives you no advantage at all that the simpler: function_that_might_modify(copy.copy(obj)) doesn't give. So what's the point? -- Steven -- https://mail.python.org/mailman/listinfo/python-list