From abc086fb0df915b702f14fa3d44e79e0a8b8f11f Mon Sep 17 00:00:00 2001
From: Fred Drake <fdrake@acm.org>
Date: Tue, 18 May 2004 03:29:52 +0000
Subject: ConfigParser: - don't allow setting options to non-string values;
 raise TypeError   when the value is set, instead of raising an arbitrary
 exception   later (such as when string interpolation is performed) - add
 tests, documentation (closes SF bug #810843)

---
 Doc/lib/libcfgparser.tex   |  4 +++-
 Lib/ConfigParser.py        |  2 ++
 Lib/test/test_cfgparser.py | 31 +++++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/Doc/lib/libcfgparser.tex b/Doc/lib/libcfgparser.tex
index a64ae53..c67c52d 100644
--- a/Doc/lib/libcfgparser.tex
+++ b/Doc/lib/libcfgparser.tex
@@ -238,7 +238,9 @@ option in the given \var{section}.
 
 \begin{methoddesc}{set}{section, option, value}
 If the given section exists, set the given option to the specified value;
-otherwise raise \exception{NoSectionError}.
+otherwise raise \exception{NoSectionError}.  \var{value} must be a
+string (\class{str} or \class{unicode}); if not, \exception{TypeError}
+is raised.
 \versionadded{1.6}
 \end{methoddesc}
 
diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py
index 73acdd1..fccfcdf 100644
--- a/Lib/ConfigParser.py
+++ b/Lib/ConfigParser.py
@@ -343,6 +343,8 @@ class RawConfigParser:
 
     def set(self, section, option, value):
         """Set an option."""
+        if not isinstance(value, basestring):
+            raise TypeError("option values must be strings")
         if not section or section == DEFAULTSECT:
             sectdict = self._defaults
         else:
diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py
index 28063b5..b40cedf 100644
--- a/Lib/test/test_cfgparser.py
+++ b/Lib/test/test_cfgparser.py
@@ -211,6 +211,37 @@ class TestCaseBase(unittest.TestCase):
             "\n"
             )
 
+    def test_set_string_types(self):
+        cf = self.fromstring("[sect]\n"
+                             "option1=foo\n")
+        # Check that we don't get an exception when setting values in
+        # an existing section using strings:
+        class mystr(str):
+            pass
+        cf.set("sect", "option1", "splat")
+        cf.set("sect", "option1", mystr("splat"))
+        cf.set("sect", "option2", "splat")
+        cf.set("sect", "option2", mystr("splat"))
+        try:
+            unicode
+        except NameError:
+            pass
+        else:
+            cf.set("sect", "option1", unicode("splat"))
+            cf.set("sect", "option2", unicode("splat"))
+
+    def test_set_nonstring_types(self):
+        cf = self.fromstring("[sect]\n"
+                             "option1=foo\n")
+        # Check that we get a TypeError when setting non-string values
+        # in an existing section:
+        self.assertRaises(TypeError, cf.set, "sect", "option1", 1)
+        self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0)
+        self.assertRaises(TypeError, cf.set, "sect", "option1", object())
+        self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
+        self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
+        self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+
     # shared by subclasses
     def get_interpolation_config(self):
         return self.fromstring(
-- 
cgit v0.12

