Greg Ewing wrote:
Fuzzyman wrote:

  
I've had problems in code that needs to treat strings, lists and
dictionaries differently (assigning values to a container where all
three need different handling) and telling the difference but allowing
duck typing is *problematic*.
    

You need to rethink your design so that you don't
have to make that kind of distinction.

Well... to *briefly* explain the use case, it's for value assignment in ConfigObj.

It basically accepts as valid values strings and lists of strings [#]_. You can also create new subsections by assigning a dictionary.

It needs to be able to recognise lists in order to check each list member is a string. (See note below, it still needs to be able to recognise lists when writing, even if it is not doing type checking on assignment.)

It needs to be able to recognise dictionaries in order to create a new section instance (rather than directly assigning the dictionary).

This is *terribly* convenient for the user (trivial example of creating a new config file programatically) :

from configobj import ConfigObj
cfg = ConfigObj(newfilename)
cfg['key'] = 'value'
cfg['key2'] = ['value1', 'value2', 'value3']
cfg['section'] = {'key': 'value', 'key2': ['value1', 'value2', 'value3']}
cfg.write()

Writes out :

key = value
key2 = value1, value2, value3
[section]
key = value
key2 = value1, value2, value3

(Note none of those values needed quoting, so they aren't.)

Obviously I could force the creation of sections and the assignment of list values to use separate methods, but it's much less readable and unnecessary.

The code as is works and has a nice API. It still needs to be able to tell what *type* of value is being assigned.

Mapping and sequence protocols are so loosely defined that in order to support 'list like objects' and 'dictionary like objects' some arbitrary decision about what methods they should support has to be made. (For example a read only mapping container is unlikely to implement __setitem__ or methods like update).

At first we defined a mapping object as one that defines __getitem__ and keys (not update as  I previously said), and list like objects as ones that define __getitem__ and *not* keys. For strings we required a basestring subclass. In the end I think we ripped this out and just settled on isinstance tests.

All the best,

Michael Foord


.. [#] Although it has two modes. In the 'default' mode you can assign any object as a value and a string representation is written out. A more strict mode checks values at the point you assign  them - so errors will be raised at that point rather than propagating into the config file. When writing you still need to able to recognise lists because each element is properly quoted.


_______________________________________________
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

Reply via email to