Kaydet (Commit) 21ce65aa authored tarafından Berker Peksag's avatar Berker Peksag Kaydeden (comit) GitHub

[3.6] bpo-29623: Make PathLike objects work with ConfigParser.read() (#242) (#432)

(cherry picked from commit 85b8d01c)

Conflicts:

	Lib/test/test_configparser.py
üst c7ff163a
...@@ -983,13 +983,16 @@ ConfigParser Objects ...@@ -983,13 +983,16 @@ ConfigParser Objects
.. method:: read(filenames, encoding=None) .. method:: read(filenames, encoding=None)
Attempt to read and parse a list of filenames, returning a list of Attempt to read and parse a list of filenames, returning a list of
filenames which were successfully parsed. If *filenames* is a string, it filenames which were successfully parsed.
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 If *filenames* is a string or :term:`path-like object`, it is treated as
specify a list of potential configuration file locations (for example, a single filename. If a file named in *filenames* cannot be opened, that
the current directory, the user's home directory, and some system-wide file will be ignored. This is designed so that you can specify a list of
directory), and all existing configuration files in the list will be potential configuration file locations (for example, the current
read. If none of the named files exist, the :class:`ConfigParser` 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 instance will contain an empty dataset. An application which requires
initial values to be loaded from a file should load the required file or 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 files using :meth:`read_file` before calling :meth:`read` for any
...@@ -1006,6 +1009,9 @@ ConfigParser Objects ...@@ -1006,6 +1009,9 @@ ConfigParser Objects
The *encoding* parameter. Previously, all files were read using the The *encoding* parameter. Previously, all files were read using the
default encoding for :func:`open`. default encoding for :func:`open`.
.. versionadded:: 3.6.1
The *filenames* parameter accepts a :term:`path-like object`.
.. method:: read_file(f, source=None) .. method:: read_file(f, source=None)
......
...@@ -143,6 +143,7 @@ from collections import OrderedDict as _default_dict, ChainMap as _ChainMap ...@@ -143,6 +143,7 @@ from collections import OrderedDict as _default_dict, ChainMap as _ChainMap
import functools import functools
import io import io
import itertools import itertools
import os
import re import re
import sys import sys
import warnings import warnings
...@@ -687,7 +688,7 @@ class RawConfigParser(MutableMapping): ...@@ -687,7 +688,7 @@ class RawConfigParser(MutableMapping):
Return list of successfully read files. Return list of successfully read files.
""" """
if isinstance(filenames, str): if isinstance(filenames, (str, os.PathLike)):
filenames = [filenames] filenames = [filenames]
read_ok = [] read_ok = []
for filename in filenames: for filename in filenames:
...@@ -696,6 +697,8 @@ class RawConfigParser(MutableMapping): ...@@ -696,6 +697,8 @@ class RawConfigParser(MutableMapping):
self._read(fp, filename) self._read(fp, filename)
except OSError: except OSError:
continue continue
if isinstance(filename, os.PathLike):
filename = os.fspath(filename)
read_ok.append(filename) read_ok.append(filename)
return read_ok return read_ok
......
...@@ -2,7 +2,7 @@ import collections ...@@ -2,7 +2,7 @@ import collections
import configparser import configparser
import io import io
import os import os
import sys import pathlib
import textwrap import textwrap
import unittest import unittest
import warnings import warnings
...@@ -721,6 +721,16 @@ boolean {0[0]} NO ...@@ -721,6 +721,16 @@ boolean {0[0]} NO
parsed_files = cf.read(file1) parsed_files = cf.read(file1)
self.assertEqual(parsed_files, [file1]) self.assertEqual(parsed_files, [file1])
self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") 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: # check when we pass only missing files:
cf = self.newconfig() cf = self.newconfig()
parsed_files = cf.read(["nonexistent-file"]) parsed_files = cf.read(["nonexistent-file"])
......
...@@ -82,6 +82,9 @@ Extension Modules ...@@ -82,6 +82,9 @@ Extension Modules
Library Library
------- -------
- bpo-29623: Allow use of path-like object as a single argument in
ConfigParser.read(). Patch by David Ellis.
- bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback - bpo-28963: Fix out of bound iteration in asyncio.Future.remove_done_callback
implemented in C. implemented in C.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment