From 85b8d01c916b482dac937b93ede1e53b1db0361c Mon Sep 17 00:00:00 2001 From: David Ellis Date: Fri, 3 Mar 2017 17:14:27 +0000 Subject: bpo-29623: Make PathLike objects work with ConfigParser.read() (#242) --- Doc/library/configparser.rst | 20 +++++++++++++------- Lib/configparser.py | 5 ++++- Lib/test/test_configparser.py | 11 +++++++++++ Misc/NEWS | 3 +++ 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 -- cgit v0.12