diff -r eea32b421d4c -r 79cb9fc14932 ConfigParser.py
--- a/ConfigParser.py	Sat May 08 07:15:52 2010 -0500
+++ b/ConfigParser.py	Sat May 08 07:55:48 2010 -0500
@@ -304,21 +304,30 @@
                 filename = '<???>'
         self._read(fp, filename)
 
-    def get(self, section, option):
+    def get(self, section, option, default=None):
         opt = self.optionxform(option)
         if section not in self._sections:
             if section != DEFAULTSECT:
-                raise NoSectionError(section)
+                if default is None:
+                    raise NoSectionError(section)
+                else:
+                    return default
             if opt in self._defaults:
                 return self._defaults[opt]
             else:
-                raise NoOptionError(option, section)
+                if default is None:
+                    raise NoOptionError(option, section)
+                else:
+                    return default
         elif opt in self._sections[section]:
             return self._sections[section][opt]
         elif opt in self._defaults:
             return self._defaults[opt]
         else:
-            raise NoOptionError(option, section)
+            if default is None:
+                raise NoOptionError(option, section)
+            else:
+                return default
 
     def items(self, section):
         try:
@@ -333,22 +342,44 @@
             del d["__name__"]
         return d.items()
 
-    def _get(self, section, conv, option):
-        return conv(self.get(section, option))
+    def _get(self, section, conv, option, default=None, raise_on_bad=False):
+        v = self.get(section, option, default=default)
+        try:
+            return conv(v)
+        except ValueError:
+            if raise_on_bad:
+                raise
+            else:
+                return default
 
-    def getint(self, section, option):
-        return self._get(section, int, option)
+    def getint(self, section, option,
+            default=None,
+            raise_on_bad=False
+            ):
+        return self._get(section, int, option,
+            default=default,
+            raise_on_bad=raise_on_bad
+            )
 
-    def getfloat(self, section, option):
-        return self._get(section, float, option)
+    def getfloat(self, section, option,
+            default=None,
+            raise_on_bad=False
+            ):
+        return self._get(section, float, option,
+            default=default,
+            raise_on_bad=raise_on_bad
+            )
 
     _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
                        '0': False, 'no': False, 'false': False, 'off': False}
 
-    def getboolean(self, section, option):
-        v = self.get(section, option)
+    def getboolean(self, section, option, default=None, raise_on_bad=False):
+        v = self.get(section, option, default=default)
         if v.lower() not in self._boolean_states:
-            raise ValueError, 'Not a boolean: %s' % v
+            if default is None or raise_on_bad:
+                raise ValueError, 'Not a boolean: %s' % v
+            else:
+                return default
         return self._boolean_states[v.lower()]
 
     def optionxform(self, optionstr):
@@ -512,7 +543,7 @@
 
 class ConfigParser(RawConfigParser):
 
-    def get(self, section, option, raw=False, vars=None):
+    def get(self, section, option, raw=False, vars=None, default=None):
         """Get an option value for a given section.
 
         All % interpolations are expanded in the return values, based on the
@@ -528,7 +559,10 @@
             d.update(self._sections[section])
         except KeyError:
             if section != DEFAULTSECT:
-                raise NoSectionError(section)
+                if default is None:
+                    raise NoSectionError(section)
+                else:
+                    return default
         # Update with the entry specific variables
         if vars:
             for key, value in vars.items():
@@ -537,14 +571,17 @@
         try:
             value = d[option]
         except KeyError:
-            raise NoOptionError(option, section)
+            if default is None:
+                raise NoOptionError(option, section)
+            else:
+                return default
 
         if raw:
             return value
         else:
-            return self._interpolate(section, option, value, d)
+            return self._interpolate(section, option, value, d, default=default)
 
-    def items(self, section, raw=False, vars=None):
+    def items(self, section, raw=False, vars=None, default=None):
         """Return a list of tuples with (name, value) for each option
         in the section.
 
@@ -573,10 +610,11 @@
             return [(option, d[option])
                     for option in options]
         else:
-            return [(option, self._interpolate(section, option, d[option], d))
+            return [(option, self._interpolate(section, option, d[option], d,
+                        default=default))
                     for option in options]
 
-    def _interpolate(self, section, option, rawval, vars):
+    def _interpolate(self, section, option, rawval, vars, default=None):
         # do the string interpolation
         value = rawval
         depth = MAX_INTERPOLATION_DEPTH
@@ -587,8 +625,12 @@
                 try:
                     value = value % vars
                 except KeyError, e:
-                    raise InterpolationMissingOptionError(
-                        option, section, rawval, e.args[0])
+                    if default is None:
+                        raise InterpolationMissingOptionError(
+                            option, section, rawval, e.args[0])
+                    else:
+                        return default
+
             else:
                 break
         if "%(" in value:
@@ -607,15 +649,17 @@
 
 class SafeConfigParser(ConfigParser):
 
-    def _interpolate(self, section, option, rawval, vars):
+    def _interpolate(self, section, option, rawval, vars, default=None):
         # do the string interpolation
         L = []
-        self._interpolate_some(option, L, rawval, section, vars, 1)
+        self._interpolate_some(option, L, rawval, section, vars, 1,
+            default=default)
         return ''.join(L)
 
     _interpvar_re = re.compile(r"%\(([^)]+)\)s")
 
-    def _interpolate_some(self, option, accum, rest, section, map, depth):
+    def _interpolate_some(self, option, accum, rest, section, map, depth,
+            default=None):
         if depth > MAX_INTERPOLATION_DEPTH:
             raise InterpolationDepthError(option, section, rest)
         while rest:
@@ -641,11 +685,15 @@
                 try:
                     v = map[var]
                 except KeyError:
-                    raise InterpolationMissingOptionError(
-                        option, section, rest, var)
+                    if default is None:
+                        raise InterpolationMissingOptionError(
+                            option, section, rest, var)
+                    else:
+                        return default
                 if "%" in v:
                     self._interpolate_some(option, accum, v,
-                                           section, map, depth + 1)
+                                           section, map, depth + 1,
+                                           default=default)
                 else:
                     accum.append(v)
             else:
