Skip to content

Commit b7707c9

Browse files
authored
Merge pull request #264 from gene1wood/add_support_for_pathlib.Path
Add support for infile being a pathlib.Path object
2 parents 76e3477 + 288d984 commit b7707c9

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

docs/configobj.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,10 @@ ConfigObj takes the following arguments (with the default values shown) :
281281
* Nothing. In which case the ``filename`` attribute of your ConfigObj will be
282282
``None``. You can set a filename at any time.
283283

284-
* A filename. What happens if the file doesn't already exist is determined by
285-
the options ``file_error`` and ``create_empty``. The filename will be
286-
preserved as the ``filename`` attribute. This can be changed at any time.
284+
* A filename or pathlib.Path object. What happens if the file doesn't already
285+
exist is determined by the options ``file_error`` and ``create_empty``. The
286+
filename will be preserved as the ``filename`` attribute. This can be
287+
changed at any time.
287288

288289
* A list of lines. Any trailing newlines will be removed from the lines. The
289290
``filename`` attribute of your ConfigObj will be ``None``.

src/configobj/__init__.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import sys
1919

2020
from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
21+
from pathlib import Path
2122

2223
from ._version import __version__
2324

@@ -1241,7 +1242,20 @@ def _load(self, infile, configspec):
12411242
with open(infile, 'w') as h:
12421243
h.write('')
12431244
content = []
1244-
1245+
1246+
elif isinstance(infile, Path):
1247+
self.filename = str(infile)
1248+
if infile.is_file():
1249+
with infile.open('rb') as h:
1250+
content = h.readlines() or []
1251+
elif self.file_error:
1252+
raise IOError('Config file not found: "%s".' % self.filename)
1253+
else:
1254+
if self.create_empty:
1255+
with infile.open('w') as h:
1256+
h.write('')
1257+
content = []
1258+
12451259
elif isinstance(infile, (list, tuple)):
12461260
content = list(infile)
12471261

@@ -1275,7 +1289,7 @@ def set_section(in_section, this_section):
12751289
# needs splitting into lines - but needs doing *after* decoding
12761290
# in case it's not an 8 bit encoding
12771291
else:
1278-
raise TypeError('infile must be a filename, file like object, or list of lines.')
1292+
raise TypeError('infile must be a filename, file like object, pathlib.Path or list of lines.')
12791293

12801294
if content:
12811295
# don't do it for the empty ConfigObj

src/tests/test_configobj.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55

66
from codecs import BOM_UTF8
7+
from pathlib import Path
78
from warnings import catch_warnings
89
from tempfile import NamedTemporaryFile
910

@@ -1104,6 +1105,24 @@ def test_creating_with_a_dictionary():
11041105
assert dictionary_cfg_content == cfg.dict()
11051106
assert dictionary_cfg_content is not cfg.dict()
11061107

1108+
def test_reading_a_pathlib_path(cfg_contents):
1109+
cfg = cfg_contents("""
1110+
[section]
1111+
foo = bar""")
1112+
c = ConfigObj(Path(cfg))
1113+
assert 'foo' in c['section']
1114+
1115+
def test_creating_a_file_from_pathlib_path(tmp_path):
1116+
infile = tmp_path / 'config.ini'
1117+
assert not Path(tmp_path / 'config.ini').is_file()
1118+
c = ConfigObj(Path(infile), create_empty=True)
1119+
assert Path(tmp_path / 'config.ini').is_file()
1120+
1121+
def test_creating_a_file_from_string(tmp_path):
1122+
infile = str(tmp_path / 'config.ini')
1123+
assert not Path(infile).is_file()
1124+
c = ConfigObj(infile, create_empty=True)
1125+
assert Path(infile).is_file()
11071126

11081127
class TestComments(object):
11091128
@pytest.fixture

0 commit comments

Comments
 (0)