From 2fd4f37f11420ab2a010cb057ffb15d37a9504cb Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 29 Nov 2007 18:43:05 +0000 Subject: Merged revisions 59212-59225 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r59218 | georg.brandl | 2007-11-29 09:01:20 -0800 (Thu, 29 Nov 2007) | 2 lines Fix reference target. ........ r59219 | georg.brandl | 2007-11-29 09:02:34 -0800 (Thu, 29 Nov 2007) | 4 lines Add examples to the ConfigParser documentation. Credits go to Thomas Lamb, who wrote this as a task in the GHOP contest. ........ r59223 | guido.van.rossum | 2007-11-29 10:25:12 -0800 (Thu, 29 Nov 2007) | 2 lines Fix bug #1517, a segfault in lookdict(). ........ r59224 | georg.brandl | 2007-11-29 10:33:01 -0800 (Thu, 29 Nov 2007) | 2 lines Spaces vs. Tabs. ........ --- Doc/ACKS.txt | 1 + Doc/library/configparser.rst | 87 ++++++++++++++++++++++++++++++++++++++++++++ Objects/dictobject.c | 4 ++ 3 files changed, 92 insertions(+) diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt index f093341..1e2c4ec 100644 --- a/Doc/ACKS.txt +++ b/Doc/ACKS.txt @@ -101,6 +101,7 @@ docs@python.org), and we'll be glad to correct the problem. * Andrew M. Kuchling * Dave Kuhlman * Erno Kuusela +* Thomas Lamb * Detlef Lannert * Piers Lauder * Glyph Lefkowitz diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index b4c89e8..6185aa0 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -333,3 +333,90 @@ The :class:`SafeConfigParser` class implements the same extended interface as otherwise raise :exc:`NoSectionError`. *value* must be a string (:class:`str` or :class:`unicode`); if not, :exc:`TypeError` is raised. + +Examples +-------- + +An example of writing to a configuration file:: + + import ConfigParser + + config = ConfigParser.RawConfigParser() + + # When adding sections or items, add them in the reverse order of + # how you want them to be displayed in the actual file. + # In addition, please note that using RawConfigParser's and the raw + # mode of ConfigParser's respective set functions, you can assign + # non-string values to keys internally, but will receive an error + # when attempting to write to a file or when you get it in non-raw + # mode. SafeConfigParser does not allow such assignments to take place. + config.add_section('Section1') + config.set('Section1', 'int', '15') + config.set('Section1', 'bool', 'true') + config.set('Section1', 'float', '3.1415') + config.set('Section1', 'baz', 'fun') + config.set('Section1', 'bar', 'Python') + config.set('Section1', 'foo', '%(bar)s is %(baz)s!') + + # Writing our configuration file to 'example.cfg' + with open('example.cfg', 'wb') as configfile: + config.write(configfile) + +An example of reading the configuration file again:: + + import ConfigParser + + config = ConfigParser.RawConfigParser() + config.read('example.cfg') + + # getfloat() raises an exception if the value is not a float + # getint() and getboolean() also do this for their respective types + float = config.getfloat('Section1', 'float') + int = config.getint('Section1', 'int') + print float + int + + # Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'. + # This is because we are using a RawConfigParser(). + if config.getboolean('Section1', 'bool'): + print config.get('Section1', 'foo') + +To get interpolation, you will need to use a :class:`ConfigParser` or +:class:`SafeConfigParser`:: + + import ConfigParser + + config = ConfigParser.ConfigParser() + config.read('example.cfg') + + # Set the third, optional argument of get to 1 if you wish to use raw mode. + print config.get('Section1', 'foo', 0) # -> "Python is fun!" + print config.get('Section1', 'foo', 1) # -> "%(bar)s is %(baz)s!" + + # The optional fourth argument is a dict with members that will take + # precedence in interpolation. + print config.get('Section1', 'foo', 0, {'bar': 'Documentation', + 'baz': 'evil'}) + +Defaults are available in all three types of ConfigParsers. They are used in +interpolation if an option used is not defined elsewhere. :: + + import ConfigParser + + # New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each + config = ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'}) + config.read('example.cfg') + + print config.get('Section1', 'foo') # -> "Python is fun!" + config.remove_option('Section1', 'bar') + config.remove_option('Section1', 'baz') + print config.get('Section1', 'foo') # -> "Life is hard!" + +The function ``opt_move`` below can be used to move options between sections:: + + def opt_move(config, section1, section2, option): + try: + config.set(section2, option, config.get(section1, option, 1)) + except ConfigParser.NoSectionError: + # Create non-existent section + config.add_section(section2) + opt_move(config, section1, section2, option) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index b849f57..d1ebf1f 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -270,7 +270,9 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash) else { if (ep->me_hash == hash) { startkey = ep->me_key; + Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); if (cmp < 0) return NULL; if (ep0 == mp->ma_table && ep->me_key == startkey) { @@ -300,7 +302,9 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash) return ep; if (ep->me_hash == hash && ep->me_key != dummy) { startkey = ep->me_key; + Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); if (cmp < 0) return NULL; if (ep0 == mp->ma_table && ep->me_key == startkey) { -- cgit v0.12