[Zope3-dev] Re: Make message ids into "rocks", was Re: Re: SVN: Zope3/trunk/src/zope/ Internationalized apidoc modules description.

Philipp von Weitershausen philipp at weitershausen.de
Fri Sep 3 09:31:21 EDT 2004


Jim,

>>> I would suggest to
>>>
>>> 1.) make the 'default' attribute a read-only attribute. 'default' and 
>>> message-id are to be seen as one set of information, always tied 
>>> together.
>>
>> The 'domain' attribute should be a read-only attribute too.
> 
> Yup. All of the attributes must be read only.

Yes, and the mapping attribute should be returned as a copy.

>>> 2.) use a different syntax for updating the mapping:
>>>
>>>   >>> msg = msg % {'foo':'bar'}
>>>
>>> Note how the __mod__ (method responsible for the % operator) returns 
>>> a new message id object.
>>>
>>> This is an analogy to
>>>
>>>   >>> "Insert %(text)s" % {'text': 'here'}
>>>   Insert here
>>
>>
>>
>> Maybe the 'mapping' attribute should be a read-only attribute which 
>> returns the mapping copy?
> 
> But that doesn't prevent the mapping from being changed in the
> message id. We need to prevent the messaage id's data from being
> mutated.

Yes, which is why I proposed that whenever you make an attempt to change 
the mapping, which in the future will only be possible using the % 
operator, a new message id is created. That effectively makes the 
combination of msgid, default and mapping immutable.

> I suggest we use Python dict proxies, which are proxies
> used by new-style classes to prevent modification of their
> dictionaries.  Unfortunately, creation of these is not
> exposed to Python code. Someone will have to whip up a small
> C extension to make these creatable from Python.  I've proposed
> on python-dev to make these creatable from Python, but that wouldn't
> happen until Python 2.4 at the soonest.

This sounds complicated and I don't see why we need it.

>  > And the MessageID constructor should accept
> 
>> optional 'mapping' argument and save copy of the passed mapping in 
>> private attribute, like this:
>>
>> class MessageID(unicode):
>>
>>     def __new__(cls, ustr, domain=None, default=None, mapping={}):
>>         self = super(MessageID, cls).__new__(cls, ustr)
>>         self.__mapping = mapping.copy()
>>         ...
> 
> 
> I propose to use dictproxies instead, however, we should make a copy
> anyway and convert all of the keys and values to unicode as we make
> the copy. Otherwise, some of the data might be mutable.

I don't see the need for these dictproxies. Otherwise I agree. 
Specifically, I have something like this in mind:

def keys_and_values_to_unicode(mapping):
     items = [(unicode(key), unicode(value) for key, value
              in mapping.items()]
     return dict(items)

class MessageID(unicode):

     def __new__(cls, ustr, domain=None, default=None, mapping={}):
         self = super(MessageID, cls).__new__(cls, ustr)
         self._domain = domain
         self._default = default
         self._mapping = keys_and_values_to_unicode(mapping)

     def domain(self):
         return self._domain
     domain = property(domain)

     def default(self):
         return self._default
     default = property(default)

     def mapping(self):
         return self._mapping.copy()
     mapping = property(mapping)

     def __mod__(self, mapping):
         new_mapping = self.mapping
         new_mapping.update(keys_and_values_to_unicode(mapping))
         return self.__class__(
             self,
             domain=self._domain,
             default=self._default,
             mapping=new_mapping
         )

This class's instances would be immutable since their attributes can't 
be changed. Changing the mapping causes a new isntance to be created.

> Yes Phillipp, this is a great idea.  Please write a proposal.

Ok, I will.

Philipp



More information about the Zope3-dev mailing list