mirror of
				https://github.com/python/cpython.git
				synced 2025-10-28 20:25:04 +00:00 
			
		
		
		
	Issue #18829: csv.Dialect() now checks type for delimiter, escapechar and
quotechar fields. Original patch by Vajrasky Kok.
This commit is contained in:
		
						commit
						cf58fb5e29
					
				
					 3 changed files with 50 additions and 6 deletions
				
			
		|  | @ -756,6 +756,7 @@ class mydialect(csv.Dialect): | ||||||
|             lineterminator = '\r\n' |             lineterminator = '\r\n' | ||||||
|             quoting = csv.QUOTE_NONE |             quoting = csv.QUOTE_NONE | ||||||
|         d = mydialect() |         d = mydialect() | ||||||
|  |         self.assertEqual(d.quoting, csv.QUOTE_NONE) | ||||||
| 
 | 
 | ||||||
|         mydialect.quoting = None |         mydialect.quoting = None | ||||||
|         self.assertRaises(csv.Error, mydialect) |         self.assertRaises(csv.Error, mydialect) | ||||||
|  | @ -764,12 +765,21 @@ class mydialect(csv.Dialect): | ||||||
|         mydialect.quoting = csv.QUOTE_ALL |         mydialect.quoting = csv.QUOTE_ALL | ||||||
|         mydialect.quotechar = '"' |         mydialect.quotechar = '"' | ||||||
|         d = mydialect() |         d = mydialect() | ||||||
|  |         self.assertEqual(d.quoting, csv.QUOTE_ALL) | ||||||
|  |         self.assertEqual(d.quotechar, '"') | ||||||
|  |         self.assertTrue(d.doublequote) | ||||||
| 
 | 
 | ||||||
|         mydialect.quotechar = "''" |         mydialect.quotechar = "''" | ||||||
|         self.assertRaises(csv.Error, mydialect) |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"quotechar" must be an 1-character string') | ||||||
| 
 | 
 | ||||||
|         mydialect.quotechar = 4 |         mydialect.quotechar = 4 | ||||||
|         self.assertRaises(csv.Error, mydialect) |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"quotechar" must be string, not int') | ||||||
| 
 | 
 | ||||||
|     def test_delimiter(self): |     def test_delimiter(self): | ||||||
|         class mydialect(csv.Dialect): |         class mydialect(csv.Dialect): | ||||||
|  | @ -780,12 +790,31 @@ class mydialect(csv.Dialect): | ||||||
|             lineterminator = '\r\n' |             lineterminator = '\r\n' | ||||||
|             quoting = csv.QUOTE_NONE |             quoting = csv.QUOTE_NONE | ||||||
|         d = mydialect() |         d = mydialect() | ||||||
|  |         self.assertEqual(d.delimiter, ";") | ||||||
| 
 | 
 | ||||||
|         mydialect.delimiter = ":::" |         mydialect.delimiter = ":::" | ||||||
|         self.assertRaises(csv.Error, mydialect) |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"delimiter" must be an 1-character string') | ||||||
|  | 
 | ||||||
|  |         mydialect.delimiter = "" | ||||||
|  |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"delimiter" must be an 1-character string') | ||||||
|  | 
 | ||||||
|  |         mydialect.delimiter = b"," | ||||||
|  |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"delimiter" must be string, not bytes') | ||||||
| 
 | 
 | ||||||
|         mydialect.delimiter = 4 |         mydialect.delimiter = 4 | ||||||
|         self.assertRaises(csv.Error, mydialect) |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"delimiter" must be string, not int') | ||||||
| 
 | 
 | ||||||
|     def test_lineterminator(self): |     def test_lineterminator(self): | ||||||
|         class mydialect(csv.Dialect): |         class mydialect(csv.Dialect): | ||||||
|  | @ -796,12 +825,17 @@ class mydialect(csv.Dialect): | ||||||
|             lineterminator = '\r\n' |             lineterminator = '\r\n' | ||||||
|             quoting = csv.QUOTE_NONE |             quoting = csv.QUOTE_NONE | ||||||
|         d = mydialect() |         d = mydialect() | ||||||
|  |         self.assertEqual(d.lineterminator, '\r\n') | ||||||
| 
 | 
 | ||||||
|         mydialect.lineterminator = ":::" |         mydialect.lineterminator = ":::" | ||||||
|         d = mydialect() |         d = mydialect() | ||||||
|  |         self.assertEqual(d.lineterminator, ":::") | ||||||
| 
 | 
 | ||||||
|         mydialect.lineterminator = 4 |         mydialect.lineterminator = 4 | ||||||
|         self.assertRaises(csv.Error, mydialect) |         with self.assertRaises(csv.Error) as cm: | ||||||
|  |             mydialect() | ||||||
|  |         self.assertEqual(str(cm.exception), | ||||||
|  |                          '"lineterminator" must be a string') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestSniffer(unittest.TestCase): | class TestSniffer(unittest.TestCase): | ||||||
|  |  | ||||||
|  | @ -44,6 +44,9 @@ Core and Builtins | ||||||
| Library | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  | - Issue #18829: csv.Dialect() now checks type for delimiter, escapechar and | ||||||
|  |   quotechar fields.  Original patch by Vajrasky Kok. | ||||||
|  | 
 | ||||||
| - Issue #19855: uuid.getnode() on Unix now looks on the PATH for the | - Issue #19855: uuid.getnode() on Unix now looks on the PATH for the | ||||||
|   executables used to find the mac address, with /sbin and /usr/sbin as |   executables used to find the mac address, with /sbin and /usr/sbin as | ||||||
|   fallbacks. |   fallbacks. | ||||||
|  |  | ||||||
|  | @ -239,6 +239,12 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) | ||||||
|         *target = '\0'; |         *target = '\0'; | ||||||
|         if (src != Py_None) { |         if (src != Py_None) { | ||||||
|             Py_ssize_t len; |             Py_ssize_t len; | ||||||
|  |             if (!PyUnicode_Check(src)) { | ||||||
|  |                 PyErr_Format(PyExc_TypeError, | ||||||
|  |                     "\"%s\" must be string, not %.200s", name, | ||||||
|  |                     src->ob_type->tp_name); | ||||||
|  |                 return -1; | ||||||
|  |             } | ||||||
|             len = PyUnicode_GetLength(src); |             len = PyUnicode_GetLength(src); | ||||||
|             if (len > 1) { |             if (len > 1) { | ||||||
|                 PyErr_Format(PyExc_TypeError, |                 PyErr_Format(PyExc_TypeError, | ||||||
|  | @ -425,7 +431,8 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) | ||||||
|     if (dialect_check_quoting(self->quoting)) |     if (dialect_check_quoting(self->quoting)) | ||||||
|         goto err; |         goto err; | ||||||
|     if (self->delimiter == 0) { |     if (self->delimiter == 0) { | ||||||
|         PyErr_SetString(PyExc_TypeError, "delimiter must be set"); |         PyErr_SetString(PyExc_TypeError, | ||||||
|  |                         "\"delimiter\" must be an 1-character string"); | ||||||
|         goto err; |         goto err; | ||||||
|     } |     } | ||||||
|     if (quotechar == Py_None && quoting == NULL) |     if (quotechar == Py_None && quoting == NULL) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka