On Tue, Feb 28, 2012 at 9:34 AM, Victor Stinner <victor.stin...@gmail.com> wrote: >>> The blacklist implementation has a major issue: it is still possible >>> to call write methods of the dict class (e.g. dict.set(my_frozendict, >>> key, value)). >> >> It is also possible to use ctypes and violate even more invariants. >> For most purposes, this falls under "consenting adults". > > My primary usage of frozendict would be pysandbox, a security module. > Attackers are not consenting adults :-) > > Read-only dict would also help optimization, in the CPython peephole > or the PyPy JIT.
I'm pretty sure the PyPy jit can already pick up and optimise cases where a dict goes "read-only" (i.e. stops being modified). I think you need to elaborate on your use cases further, and explain what *additional* changes would be needed, such as allowing frozendict instances as __dict__ attributes in order to create truly immutable objects in pure Python code. In fact, that may be a better way to pitch the entire PEP. In current Python, you *can't* create a truly immutable object without dropping down to a C extension: >>> from decimal import Decimal >>> x = Decimal(1) >>> x Decimal('1') >>> hash(x) 1 >>> x._exp = 10 >>> x Decimal('1E+10') >>> hash(x) 10000000000 Contrast that with the behaviour of a float instance: >>> 1.0.imag = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: attribute 'imag' of 'float' objects is not writable Yes, it's arguably covered by the "consenting adults" rule, but really, Decimal instances should be just as immutable as int and float instances. The only reason they aren't is that it's hard enough to set it up in Python code that the Decimal implementation settles for "near enough is good enough" and just uses __slots__ to prevent addition of new attributes, but doesn't introduce the overhead of custom __setattr__ and __delattr__ implementations to actively *prevent* modifications. We don't even need a new container type, we really just need an easy way to tell the __setattr__ and __delattr__ descriptors for "__slots__" that the instance initialisation is complete and further modifications should be disallowed. For example, if Decimal.__new__ could call "self.__lock_slots__()" at the end to set a flag on the instance object, then the slot descriptors could read that new flag and trigger an error: >>> x._exp = 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: attribute '_exp' of 'Decimal' objects is not writable To be clear, all of this is currently *possible* if you use custom descriptors (such as a property() implementation where setattr and delattr look for such a flag) or override __setattr__/__delattr__. However, for a micro-optimised type like Decimal, that's a hard choice to be asked to make (and the current implementation came down on the side of speed over enforcing correctness). Given that using __slots__ in the first place is, in and of itself, a micro-optimisation, I suspect Decimal is far from the only "immutable" type implemented in pure Python that finds itself having to make that trade-off. (An extra boolean check in C is a *good* trade-off of speed for correctness. Python level descriptor implementations or attribute access overrides, on the other hand... not so much). Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com