Skip to content

Commit f9b4eb4

Browse files
committed
Fixed issue python#18260: configparser TypeError on source name specified as bytes
1 parent 36a7e4f commit f9b4eb4

File tree

2 files changed

+65
-13
lines changed

2 files changed

+65
-13
lines changed

Lib/configparser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class DuplicateSectionError(Error):
191191
def __init__(self, section, source=None, lineno=None):
192192
msg = [repr(section), " already exists"]
193193
if source is not None:
194-
message = ["While reading from ", source]
194+
message = ["While reading from ", repr(source)]
195195
if lineno is not None:
196196
message.append(" [line {0:2d}]".format(lineno))
197197
message.append(": section ")
@@ -217,7 +217,7 @@ def __init__(self, section, option, source=None, lineno=None):
217217
msg = [repr(option), " in section ", repr(section),
218218
" already exists"]
219219
if source is not None:
220-
message = ["While reading from ", source]
220+
message = ["While reading from ", repr(source)]
221221
if lineno is not None:
222222
message.append(" [line {0:2d}]".format(lineno))
223223
message.append(": option ")

Lib/test/test_configparser.py

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -626,15 +626,15 @@ def test_weird_errors(self):
626626
oops{equals}this won't
627627
""".format(equals=self.delimiters[0])), source='<foo-bar>')
628628
e = cm.exception
629-
self.assertEqual(str(e), "While reading from <foo-bar> [line 5]: "
630-
"section 'Foo' already exists")
629+
self.assertEqual(str(e), "While reading from '<foo-bar>' "
630+
"[line 5]: section 'Foo' already exists")
631631
self.assertEqual(e.args, ("Foo", '<foo-bar>', 5))
632632

633633
with self.assertRaises(configparser.DuplicateOptionError) as cm:
634634
cf.read_dict({'Bar': {'opt': 'val', 'OPT': 'is really `opt`'}})
635635
e = cm.exception
636-
self.assertEqual(str(e), "While reading from <dict>: option 'opt' "
637-
"in section 'Bar' already exists")
636+
self.assertEqual(str(e), "While reading from '<dict>': option "
637+
"'opt' in section 'Bar' already exists")
638638
self.assertEqual(e.args, ("Bar", "opt", "<dict>", None))
639639

640640
def test_write(self):
@@ -1419,13 +1419,18 @@ def readline_generator(f):
14191419

14201420
class ReadFileTestCase(unittest.TestCase):
14211421
def test_file(self):
1422-
file_path = support.findfile("cfgparser.1")
1423-
parser = configparser.ConfigParser()
1424-
with open(file_path) as f:
1425-
parser.read_file(f)
1426-
self.assertIn("Foo Bar", parser)
1427-
self.assertIn("foo", parser["Foo Bar"])
1428-
self.assertEqual(parser["Foo Bar"]["foo"], "newbar")
1422+
file_paths = [support.findfile("cfgparser.1")]
1423+
try:
1424+
file_paths.append(file_paths[0].encode('utf8'))
1425+
except UnicodeEncodeError:
1426+
pass # unfortunately we can't test bytes on this path
1427+
for file_path in file_paths:
1428+
parser = configparser.ConfigParser()
1429+
with open(file_path) as f:
1430+
parser.read_file(f)
1431+
self.assertIn("Foo Bar", parser)
1432+
self.assertIn("foo", parser["Foo Bar"])
1433+
self.assertEqual(parser["Foo Bar"]["foo"], "newbar")
14291434

14301435
def test_iterable(self):
14311436
lines = textwrap.dedent("""
@@ -1447,6 +1452,53 @@ def test_readline_generator(self):
14471452
self.assertIn("foo", parser["Foo Bar"])
14481453
self.assertEqual(parser["Foo Bar"]["foo"], "newbar")
14491454

1455+
def test_source_as_bytes(self):
1456+
"""Issue #18260."""
1457+
lines = textwrap.dedent("""
1458+
[badbad]
1459+
[badbad]""").strip().split('\n')
1460+
parser = configparser.ConfigParser()
1461+
with self.assertRaises(configparser.DuplicateSectionError) as dse:
1462+
parser.read_file(lines, source=b"badbad")
1463+
self.assertEqual(
1464+
str(dse.exception),
1465+
"While reading from b'badbad' [line 2]: section 'badbad' "
1466+
"already exists"
1467+
)
1468+
lines = textwrap.dedent("""
1469+
[badbad]
1470+
bad = bad
1471+
bad = bad""").strip().split('\n')
1472+
parser = configparser.ConfigParser()
1473+
with self.assertRaises(configparser.DuplicateOptionError) as dse:
1474+
parser.read_file(lines, source=b"badbad")
1475+
self.assertEqual(
1476+
str(dse.exception),
1477+
"While reading from b'badbad' [line 3]: option 'bad' in section "
1478+
"'badbad' already exists"
1479+
)
1480+
lines = textwrap.dedent("""
1481+
[badbad]
1482+
= bad""").strip().split('\n')
1483+
parser = configparser.ConfigParser()
1484+
with self.assertRaises(configparser.ParsingError) as dse:
1485+
parser.read_file(lines, source=b"badbad")
1486+
self.assertEqual(
1487+
str(dse.exception),
1488+
"Source contains parsing errors: b'badbad'\n\t[line 2]: '= bad'"
1489+
)
1490+
lines = textwrap.dedent("""
1491+
[badbad
1492+
bad = bad""").strip().split('\n')
1493+
parser = configparser.ConfigParser()
1494+
with self.assertRaises(configparser.MissingSectionHeaderError) as dse:
1495+
parser.read_file(lines, source=b"badbad")
1496+
self.assertEqual(
1497+
str(dse.exception),
1498+
"File contains no section headers.\nfile: b'badbad', line: 1\n"
1499+
"'[badbad'"
1500+
)
1501+
14501502

14511503
class CoverageOneHundredTestCase(unittest.TestCase):
14521504
"""Covers edge cases in the codebase."""

0 commit comments

Comments
 (0)