From b70091a8d5014b1c5d8738c17ae801d79dd5392d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 16 May 2015 17:11:41 +0300 Subject: Issue #20014: array.array() now accepts unicode typecodes. Based on patch by Vajrasky Kok. --- Lib/test/test_array.py | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ Modules/arraymodule.c | 18 +++++++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index b933cbf..7256b94 100644 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -26,7 +26,17 @@ class BadConstructorTest(unittest.TestCase): self.assertRaises(TypeError, array.array) self.assertRaises(TypeError, array.array, spam=42) self.assertRaises(TypeError, array.array, 'xx') + self.assertRaises(TypeError, array.array, '') + self.assertRaises(TypeError, array.array, 1) self.assertRaises(ValueError, array.array, 'x') + self.assertRaises(ValueError, array.array, '\x80') + + @test_support.requires_unicode + def test_unicode_constructor(self): + self.assertRaises(TypeError, array.array, u'xx') + self.assertRaises(TypeError, array.array, u'') + self.assertRaises(ValueError, array.array, u'x') + self.assertRaises(ValueError, array.array, u'\x80') tests.append(BadConstructorTest) @@ -1039,6 +1049,17 @@ class UnsignedLongTest(UnsignedNumberTest): minitemsize = 4 tests.append(UnsignedLongTest) + +@test_support.requires_unicode +class UnicodeTypecodeTest(unittest.TestCase): + def test_unicode_typecode(self): + for typecode in typecodes: + a = array.array(unicode(typecode)) + self.assertEqual(a.typecode, typecode) + self.assertIs(type(a.typecode), str) +tests.append(UnicodeTypecodeTest) + + class FPTest(NumberTest): example = [-42.0, 0, 42, 1e5, -1e10] smallerexample = [-42.0, 0, 42, 1e5, -2e10] diff --git a/Misc/NEWS b/Misc/NEWS index 8a8e8d2..5df7c9b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Core and Builtins Library ------- +- Issue #20014: array.array() now accepts unicode typecodes. Based on patch by + Vajrasky Kok. + - Issue #23637: Showing a warning no longer fails with UnicodeErrror. Formatting unicode warning in the file with the path containing non-ascii characters no longer fails with UnicodeErrror. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 5a92862..c37644d 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1928,16 +1928,28 @@ static PyBufferProcs array_as_buffer = { static PyObject * array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - char c; - PyObject *initial = NULL, *it = NULL; + int c = -1; + PyObject *initial = NULL, *it = NULL, *typecode = NULL; struct arraydescr *descr; if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds)) return NULL; - if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial)) + if (!PyArg_ParseTuple(args, "O|O:array", &typecode, &initial)) return NULL; + if (PyString_Check(typecode) && PyString_GET_SIZE(typecode) == 1) + c = (unsigned char)*PyString_AS_STRING(typecode); + else if (PyUnicode_Check(typecode) && PyUnicode_GET_SIZE(typecode) == 1) + c = *PyUnicode_AS_UNICODE(typecode); + else { + PyErr_Format(PyExc_TypeError, + "array() argument 1 or typecode must be char (string or " + "ascii-unicode with length 1), not %s", + Py_TYPE(typecode)->tp_name); + return NULL; + } + if (!(initial == NULL || PyList_Check(initial) || PyString_Check(initial) || PyTuple_Check(initial) || (c == 'u' && PyUnicode_Check(initial)))) { -- cgit v0.12