gh-132813: Improve error messages for incorrect types and values of csv.Dialog attributes (GH-133241)

Make them similar to PyArg_Parse error messages, mention None as
a possible value, show a wrong type and the string length.
This commit is contained in:
Serhiy Storchaka 2025-06-02 23:35:41 +03:00 committed by GitHub
parent e814f43f2c
commit df98a47a61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 54 deletions

View file

@ -1122,19 +1122,22 @@ class TestDialectValidity(unittest.TestCase):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"quotechar" must be a 1-character string')
'"quotechar" must be a unicode character or None, '
'not a string of length 0')
mydialect.quotechar = "''"
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"quotechar" must be a 1-character string')
'"quotechar" must be a unicode character or None, '
'not a string of length 2')
mydialect.quotechar = 4
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"quotechar" must be string or None, not int')
'"quotechar" must be a unicode character or None, '
'not int')
def test_delimiter(self):
class mydialect(csv.Dialect):
@ -1151,31 +1154,32 @@ class TestDialectValidity(unittest.TestCase):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be a 1-character string')
'"delimiter" must be a unicode character, '
'not a string of length 3')
mydialect.delimiter = ""
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be a 1-character string')
'"delimiter" must be a unicode character, not a string of length 0')
mydialect.delimiter = b","
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be string, not bytes')
'"delimiter" must be a unicode character, not bytes')
mydialect.delimiter = 4
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be string, not int')
'"delimiter" must be a unicode character, not int')
mydialect.delimiter = None
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be string, not NoneType')
'"delimiter" must be a unicode character, not NoneType')
def test_escapechar(self):
class mydialect(csv.Dialect):
@ -1189,20 +1193,32 @@ class TestDialectValidity(unittest.TestCase):
self.assertEqual(d.escapechar, "\\")
mydialect.escapechar = ""
with self.assertRaisesRegex(csv.Error, '"escapechar" must be a 1-character string'):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"escapechar" must be a unicode character or None, '
'not a string of length 0')
mydialect.escapechar = "**"
with self.assertRaisesRegex(csv.Error, '"escapechar" must be a 1-character string'):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"escapechar" must be a unicode character or None, '
'not a string of length 2')
mydialect.escapechar = b"*"
with self.assertRaisesRegex(csv.Error, '"escapechar" must be string or None, not bytes'):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"escapechar" must be a unicode character or None, '
'not bytes')
mydialect.escapechar = 4
with self.assertRaisesRegex(csv.Error, '"escapechar" must be string or None, not int'):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"escapechar" must be a unicode character or None, '
'not int')
def test_lineterminator(self):
class mydialect(csv.Dialect):
@ -1223,7 +1239,13 @@ class TestDialectValidity(unittest.TestCase):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"lineterminator" must be a string')
'"lineterminator" must be a string, not int')
mydialect.lineterminator = None
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"lineterminator" must be a string, not NoneType')
def test_invalid_chars(self):
def create_invalid(field_name, value, **kwargs):