Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting ConfigParser values to python data types

ConfigParser requires all sections, keys and values to be strings; no surprise. It has methods to convert the values to datatypes with getfloat, getint, getboolean. If you don't know the datatype, you can wrap the get() with an eval() to get have the string evaluated such as:

>>> from ConfigParser import SafeConfigParser
>>> cp = SafeConfigParser()
>>> cp.add_section('one')
>>> cp.set('one', 'key', '42')
>>> print cp.get('one', 'key')
'42'
>>> print eval(cp.get('one', 'key'))
42
>>> cp.set('one', 'key', 'None')
>>> print eval(cp.get('one', 'key'))
None
>>> 

Is there a better way? I assume there some grave security concerns with evaluating text from a file- which I acknowledge; I completely trust the file.

I thought I would use pickle for this, but I would really like to keep the config file human readable.

How would you do it?

like image 959
tMC Avatar asked Jun 02 '11 00:06

tMC


People also ask

What does Configparser do in Python?

The configparser module from Python's standard library defines functionality for reading and writing configuration files as used by Microsoft Windows OS. Such files usually have . INI extension.

Is Configparser built in Python?

configparser comes from Python 3 and as such it works well with Unicode. The library is generally cleaned up in terms of internal data storage and reading/writing files.

How do I print a Configparser object?

Just use a StringIO object and the configparser's write method. It looks like the only method for "printing" the contents of a config object is ConfigParser. write which takes a file-like object.


2 Answers

If you are using Python 2.6 or above you can use ast.literal_eval:

ast.literal_eval(node_or_string)
Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.

This will work like eval when the string is safe:

>>> literal_eval("{'key': 10}")
{'key': 10}

But it will fail if anything besides the types listed in the documentation appear:

>>> literal_eval("import os; os.system('rm -rf somepath')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/lib64/python2.6/ast.py", line 37, in parse
    return compile(expr, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    import os; os.system('rm -rf somepath')
         ^
SyntaxError: invalid syntax
like image 151
Andrew Clark Avatar answered Sep 19 '22 09:09

Andrew Clark


For those that may be looking for another easier answer, instead of having to convert the data types yourself, you can use the localconfig module that does the conversion for you. The conversion is done by guessing the data type based on the value (I.e. 123 is an int, 123.4 is a float, true is a bool, and so on).

Here is an example following the OP's:

>>> from localconfig import config
>>> config.read('[one]\nkey = 42\nkey2 = None')
>>> config.one.key, type(config.one.key)
(42, <type 'int'>)
>>> config.one.key2, type(config.one.key2)
(None, <type 'NoneType'>)
>>> config.get('one', 'key'), config.get('one', 'key2')
(42, None)

It is a wrapper on top of ConfigParser, so it is fully compatible.

Check it out at https://pypi.python.org/pypi/localconfig

like image 32
Max Zheng Avatar answered Sep 22 '22 09:09

Max Zheng