summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ellis <ducksual@gmail.com>2017-03-03 17:14:27 (GMT)
committerBerker Peksag <berker.peksag@gmail.com>2017-03-03 17:14:27 (GMT)
commit85b8d01c916b482dac937b93ede1e53b1db0361c (patch)
treebfa366f638fdd8276bfca76ffaf252ee1e3fa5f7
parent677ab995cede784f5dafa64d54c92e98c8b81dd7 (diff)
downloadcpython-85b8d01c916b482dac937b93ede1e53b1db0361c.zip
cpython-85b8d01c916b482dac937b93ede1e53b1db0361c.tar.gz
cpython-85b8d01c916b482dac937b93ede1e53b1db0361c.tar.bz2
bpo-29623: Make PathLike objects work with ConfigParser.read() (#242)
-rw-r--r--Doc/library/configparser.rst20
-rw-r--r--Lib/configparser.py5
-rw-r--r--Lib/test/test_configparser.py11
-rw-r--r--Misc/NEWS3
4 files changed, 31 insertions, 8 deletions
diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst
index c0ffded..7f6ed14 100644
--- a/Doc/library/configparser.rst
+++ b/Doc/library/configparser.rst
@@ -988,13 +988,16 @@ ConfigParser Objects
.. method:: read(filenames, encoding=None)
Attempt to read and parse a list of filenames, returning a list of
- filenames which were successfully parsed. If *filenames* is a string, it
- is treated as a single filename. If a file named in *filenames* cannot
- be opened, that file will be ignored. This is designed so that you can
- specify a list of potential configuration file locations (for example,
- the current directory, the user's home directory, and some system-wide
- directory), and all existing configuration files in the list will be
- read. If none of the named files exist, the :class:`ConfigParser`
+ filenames which were successfully parsed.
+
+ If *filenames* is a string or :term:`path-like object`, it is treated as
+ a single filename. If a file named in *filenames* cannot be opened, that
+ file will be ignored. This is designed so that you can specify a list of
+ potential configuration file locations (for example, the current
+ directory, the user's home directory, and some system-wide directory),
+ and all existing configuration files in the list will be read.
+
+ If none of the named files exist, the :class:`ConfigParser`
instance will contain an empty dataset. An application which requires
initial values to be loaded from a file should load the required file or
files using :meth:`read_file` before calling :meth:`read` for any
@@ -1011,6 +1014,9 @@ ConfigParser Objects
The *encoding* parameter. Previously, all files were read using the
default encoding for :func:`open`.
+ .. versionadded:: 3.6.1
+ The *filenames* parameter accepts a :term:`path-like object`.
+
.. method:: read_file(f, source=None)
diff --git a/Lib/configparser.py b/Lib/configparser.py
index af5aca1..230ab2b 100644
--- a/Lib/configparser.py
+++ b/Lib/configparser.py
@@ -143,6 +143,7 @@ from collections import OrderedDict as _default_dict, ChainMap as _ChainMap
import functools
import io
import itertools
+import os
import re
import sys
import warnings
@@ -687,7 +688,7 @@ class RawConfigParser(MutableMapping):
Return list of successfully read files.
"""
- if isinstance(filenames, str):
+ if isinstance(filenames, (str, os.PathLike)):
filenames = [filenames]
read_ok = []
for filename in filenames:
@@ -696,6 +697,8 @@ class RawConfigParser(MutableMapping):
self._read(fp, filename)
except OSError:
continue
+ if isinstance(filename, os.PathLike):
+ filename = os.fspath(filename)
read_ok.append(filename)
return read_ok
diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py
index 696f642..72c3f19 100644
--- a/Lib/test/test_configparser.py
+++ b/Lib/test/test_configparser.py
@@ -2,6 +2,7 @@ import collections
import configparser
import io
import os
+import pathlib
import textwrap
import unittest
import warnings
@@ -720,6 +721,16 @@ boolean {0[0]} NO
parsed_files = cf.read(file1)
self.assertEqual(parsed_files, [file1])
self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+ # check when we pass only a Path object:
+ cf = self.newconfig()
+ parsed_files = cf.read(pathlib.Path(file1))
+ self.assertEqual(parsed_files, [file1])
+ self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
+ # check when we passed both a filename and a Path object:
+ cf = self.newconfig()
+ parsed_files = cf.read([pathlib.Path(file1), file1])
+ self.assertEqual(parsed_files, [file1, file1])
+ self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
# check when we pass only missing files:
cf = self.newconfig()
parsed_files = cf.read(["nonexistent-file"])
diff --git a/Misc/NEWS b/Misc/NEWS
index e515e6a..3421cbd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -259,6 +259,9 @@ Extension Modules
Library
-------
+- bpo-29623: Allow use of path-like object as a single argument in
+ ConfigParser.read(). Patch by David Ellis.
+
- bpo-9303: Migrate sqlite3 module to _v2 API. Patch by Aviv Palivoda.
- bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback