16

How can I parse tags with no value in an ini file with python configparser module?

For example, I have the following ini and I need to parse rb. In some ini files rb has integer values and on some no value at all like the example below. How can I do that with configparser without getting a valueerror? I use the getint function

[section]
person=name
id=000
rb=
mmmmmm
  • 32,227
  • 27
  • 88
  • 117
AKM
  • 6,285
  • 9
  • 31
  • 34

5 Answers5

15

You need to set allow_no_value=True optional argument when creating the parser object.

Santa
  • 11,381
  • 8
  • 51
  • 64
  • I tried to use config = ConfigParser.ConfigParser(allow_no_value=True) config.read(infFile) but i get this error TypeError: __init__() got an unexpected keyword argument 'allow_no_value – AKM Aug 27 '10 at 18:36
  • 3
    Looks like that [argument](http://docs.python.org/library/configparser.html#ConfigParser.RawConfigParser) was only added in Python 2.7. – Santa Aug 27 '10 at 20:10
  • 2
    Then the question stands how to handle empty value with ConfigParser for 2.6. – Exploring Dec 11 '13 at 22:35
  • 4
    `allow_no_value=True` has nothing to do with empty values if `=` is still present and it has even less to do with the ability to use getint with empty values. – panda-34 Mar 05 '16 at 19:41
7

Maybe use a try...except block:

    try:
        value=parser.getint(section,option)
    except ValueError:
        value=parser.get(section,option)

For example:

import ConfigParser

filename='config'
parser=ConfigParser.SafeConfigParser()
parser.read([filename])
print(parser.sections())
# ['section']
for section in parser.sections():
    print(parser.options(section))
    # ['id', 'rb', 'person']
    for option in parser.options(section):
        try:
            value=parser.getint(section,option)
        except ValueError:
            value=parser.get(section,option)
        print(option,value,type(value))
        # ('id', 0, <type 'int'>)
        # ('rb', '', <type 'str'>)
        # ('person', 'name', <type 'str'>) 
print(parser.items('section'))
# [('id', '000'), ('rb', ''), ('person', 'name')]
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
4

Instead of using getint(), use get() to get the option as a string. Then convert to an int yourself:

rb = parser.get("section", "rb")
if rb:
    rb = int(rb)
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
0

Since there is still an unanswered question about python 2.6, the following will work with python 2.7 or 2.6. This replaces the internal regex used to parse the option, separator, and value in ConfigParser.

def rawConfigParserAllowNoValue(config):
    '''This is a hack to support python 2.6. ConfigParser provides the 
    option allow_no_value=True to do this, but python 2.6 doesn't have it.
    '''
    OPTCRE_NV = re.compile(
        r'(?P<option>[^:=\s][^:=]*)'    # match "option" that doesn't start with white space
        r'\s*'                          # match optional white space
        r'(?P<vi>(?:[:=]|\s*(?=$)))\s*' # match separator ("vi") (or white space if followed by end of string)
        r'(?P<value>.*)$'               # match possibly empty "value" and end of string
    )
    config.OPTCRE = OPTCRE_NV
    config._optcre = OPTCRE_NV
    return config

Use as

    fp = open("myFile.conf")
    config = ConfigParser.RawConfigParser()
    config = rawConfigParserAllowNoValue(config)

Side Note

There is a OPTCRE_NV in ConfigParser for Python 2.7, but if we used it in the above function exactly, the regex would return None for vi and value, which causes ConfigParser to fail internally. Using the function above returns a blank string for vi and value and everyone is happy.

Aaron Swan
  • 1,206
  • 1
  • 13
  • 20
0

Why not comment out the rb option like so:

[section]
person=name
id=000
; rb=

and then use this awesome oneliner:

rb = parser.getint('section', 'rb') if parser.has_option('section', 'rb') else None
whitebrow
  • 2,015
  • 21
  • 24