ConfigParser:
- read() method returns a list of files parsed successfully
- add tests, documentation
(closes SF patch #677651)
diff --git a/Doc/lib/libcfgparser.tex b/Doc/lib/libcfgparser.tex
index d5c9757..bc15655 100644
--- a/Doc/lib/libcfgparser.tex
+++ b/Doc/lib/libcfgparser.tex
@@ -177,7 +177,8 @@
\end{methoddesc}
\begin{methoddesc}{read}{filenames}
-Read and parse a list of filenames. If \var{filenames} is a string or
+Attempt to read and parse a list of filenames, returning a list of filenames
+which were successfully parsed. If \var{filenames} is a string or
Unicode string, it is treated as a single filename.
If a file named in \var{filenames} cannot be opened, that file will be
ignored. This is designed so that you can specify a list of potential
@@ -197,6 +198,7 @@
config.readfp(open('defaults.cfg'))
config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])
\end{verbatim}
+\versionchanged[Returns list of successfully parsed filenames]{2.4}
\end{methoddesc}
\begin{methoddesc}{readfp}{fp\optional{, filename}}
diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py
index fccfcdf..5f80269 100644
--- a/Lib/ConfigParser.py
+++ b/Lib/ConfigParser.py
@@ -45,7 +45,7 @@
read(filenames)
read and parse the list of named configuration files, given by
name. A single filename is also allowed. Non-existing files
- are ignored.
+ are ignored. Return list of successfully read files.
readfp(fp, filename=None)
read and parse one configuration file, given as a file object.
@@ -252,9 +252,12 @@
home directory, systemwide directory), and all existing
configuration files in the list will be read. A single
filename may also be given.
+
+ Return list of successfully read files.
"""
if isinstance(filenames, basestring):
filenames = [filenames]
+ read_ok = []
for filename in filenames:
try:
fp = open(filename)
@@ -262,6 +265,8 @@
continue
self._read(fp, filename)
fp.close()
+ read_ok.append(filename)
+ return read_ok
def readfp(self, fp, filename=None):
"""Like read() but the argument must be a file-like object.
diff --git a/Lib/test/cfgparser.1 b/Lib/test/cfgparser.1
new file mode 100644
index 0000000..3387f52
--- /dev/null
+++ b/Lib/test/cfgparser.1
@@ -0,0 +1,2 @@
+[Foo Bar]
+foo=newbar
diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py
index b40cedf..c799c7d 100644
--- a/Lib/test/test_cfgparser.py
+++ b/Lib/test/test_cfgparser.py
@@ -242,6 +242,27 @@
self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+ def test_read_returns_file_list(self):
+ file1 = test_support.findfile("cfgparser.1")
+ # check when we pass a mix of readable and non-readable files:
+ cf = self.newconfig()
+ parsed_files = cf.read([file1, "nonexistant-file"])
+ self.assertEqual(parsed_files, [file1])
+ self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+ # check when we pass only a filename:
+ cf = self.newconfig()
+ parsed_files = cf.read(file1)
+ self.assertEqual(parsed_files, [file1])
+ self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+ # check when we pass only missing files:
+ cf = self.newconfig()
+ parsed_files = cf.read(["nonexistant-file"])
+ self.assertEqual(parsed_files, [])
+ # check when we pass no files:
+ cf = self.newconfig()
+ parsed_files = cf.read([])
+ self.assertEqual(parsed_files, [])
+
# shared by subclasses
def get_interpolation_config(self):
return self.fromstring(