Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9986633

Browse files
committed
Patch 520694: arraymodule.c improvements:
- make array.array a type - add Py_UNICODE arrays - support +=, *=
1 parent 272cb40 commit 9986633

4 files changed

Lines changed: 491 additions & 122 deletions

File tree

Doc/lib/libarray.tex

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ \section{\module{array} ---
55
\modulesynopsis{Efficient arrays of uniformly typed numeric values.}
66

77

8-
This module defines a new object type which can efficiently represent
8+
This module defines an object type which can efficiently represent
99
an array of basic values: characters, integers, floating point
1010
numbers. Arrays\index{arrays} are sequence types and behave very much
1111
like lists, except that the type of objects stored in them is
@@ -17,6 +17,7 @@ \section{\module{array} ---
1717
\lineiii{'c'}{character}{1}
1818
\lineiii{'b'}{signed int}{1}
1919
\lineiii{'B'}{unsigned int}{1}
20+
\lineiii{'u'}{Unicode character}{2}
2021
\lineiii{'h'}{signed int}{2}
2122
\lineiii{'H'}{unsigned int}{2}
2223
\lineiii{'i'}{signed int}{2}
@@ -35,23 +36,25 @@ \section{\module{array} ---
3536
type cannot represent the full range of C's unsigned (long) integers.
3637

3738

38-
The module defines the following function and type object:
39+
The module defines the following type:
3940

4041
\begin{funcdesc}{array}{typecode\optional{, initializer}}
41-
Return a new array whose items are restricted by \var{typecode}, and
42-
initialized from the optional \var{initializer} value, which must be a
43-
list or a string. The list or string is passed to the new array's
44-
\method{fromlist()} or \method{fromstring()} method (see below) to add
45-
initial items to the array.
42+
Return a new array whose items are restricted by \var{typecode},
43+
and initialized from the optional \var{initializer} value, which
44+
must be a list or a string. The list or string is passed to the
45+
new array's \method{fromlist()}, \method{fromstring()}, or
46+
\method{fromunicode()} method (see below) to add initial items to
47+
the array.
4648
\end{funcdesc}
4749

4850
\begin{datadesc}{ArrayType}
49-
Type object corresponding to the objects returned by
50-
\function{array()}.
51+
Obsolete alias for \function{array}.
5152
\end{datadesc}
5253

5354

54-
Array objects support the following data items and methods:
55+
Array objects support the ordinary sequence operations of
56+
indexing, slicing, concatenation, and multiplication. The
57+
following data items and methods are also supported:
5558

5659
\begin{memberdesc}[array]{typecode}
5760
The typecode character used to create the array.
@@ -121,6 +124,13 @@ \section{\module{array} ---
121124
file using the \method{fromfile()} method).
122125
\end{methoddesc}
123126

127+
\begin{methoddesc}[array]{fromunicode}{s}
128+
Extends this array with data from the given unicode string.
129+
The array must be a type 'u' array; otherwise a ValueError
130+
is raised. Use \samp{array.fromstring(ustr.decode(enc))} to
131+
append Unicode data to an array of some other type.
132+
\end{methoddesc}
133+
124134
\begin{methoddesc}[array]{index}{x}
125135
Return the smallest \var{i} such that \var{i} is the index of
126136
the first occurence of \var{x} in the array.
@@ -134,7 +144,7 @@ \section{\module{array} ---
134144
\begin{methoddesc}[array]{pop}{\optional{i}}
135145
Removes the item with the index \var{i} from the array and returns
136146
it. The optional argument defaults to \code{-1}, so that by default
137-
the last item is removed and returned.
147+
the last item is removed and returned.
138148
\end{methoddesc}
139149

140150
\begin{methoddesc}[array]{read}{f, n}
@@ -170,6 +180,13 @@ \section{\module{array} ---
170180
be written to a file by the \method{tofile()} method.)
171181
\end{methoddesc}
172182

183+
\begin{methoddesc}[array]{tounicode}{}
184+
Convert the array to a unicode string. The array must be
185+
a type 'u' array; otherwise a ValueError is raised. Use
186+
array.tostring().decode(enc) to obtain a unicode string
187+
from an array of some other type.
188+
\end{methoddesc}
189+
173190
\begin{methoddesc}[array]{write}{f}
174191
\deprecated {1.5.1}
175192
{Use the \method{tofile()} method.}
@@ -188,6 +205,7 @@ \section{\module{array} ---
188205
\begin{verbatim}
189206
array('l')
190207
array('c', 'hello world')
208+
array('u', u'hello \textbackslash u2641')
191209
array('l', [1, 2, 3, 4, 5])
192210
array('d', [1.0, 2.0, 3.14])
193211
\end{verbatim}

Lib/test/test_array.py

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,87 @@
66
from test_support import verbose, TESTFN, unlink, TestFailed
77

88
def main():
9-
109
testtype('c', 'c')
11-
10+
testtype('u', u'\u263a')
1211
for type in (['b', 'h', 'i', 'l', 'f', 'd']):
1312
testtype(type, 1)
14-
13+
testunicode()
14+
testsubclassing()
1515
unlink(TESTFN)
1616

17+
def testunicode():
18+
try:
19+
array.array('b', u'foo')
20+
except TypeError:
21+
pass
22+
else:
23+
raise TestFailed("creating a non-unicode array from "
24+
"a Unicode string should fail")
25+
26+
x = array.array('u', u'\xa0\xc2\u1234')
27+
x.fromunicode(u' ')
28+
x.fromunicode(u'')
29+
x.fromunicode(u'')
30+
x.fromunicode(u'\x11abc\xff\u1234')
31+
s = x.tounicode()
32+
if s != u'\xa0\xc2\u1234 \x11abc\xff\u1234':
33+
raise TestFailed("fromunicode()/tounicode()")
34+
35+
s = u'\x00="\'a\\b\x80\xff\u0000\u0001\u1234'
36+
a = array.array('u', s)
37+
if verbose:
38+
print "repr of type 'u' array:", repr(a)
39+
print " expected: array('u', %r)" % s
40+
41+
def testsubclassing():
42+
class EditableString(array.array):
43+
def __new__(cls, s, *args, **kwargs):
44+
return array.array.__new__(cls, 'c', s)
45+
46+
def __init__(self, s, color='blue'):
47+
array.array.__init__(self, 'c', s)
48+
self.color = color
49+
50+
def strip(self):
51+
self[:] = array.array('c', self.tostring().strip())
52+
53+
def __repr__(self):
54+
return 'EditableString(%r)' % self.tostring()
55+
56+
s = EditableString("\ttest\r\n")
57+
s.strip()
58+
if s.tostring() != 'test':
59+
raise TestFailed, "subclassing array.array failed somewhere"
60+
if s.color != 'blue':
61+
raise TestFailed, "assigning attributes to instance of array subclass"
62+
s.color = 'red'
63+
if s.color != 'red':
64+
raise TestFailed, "assigning attributes to instance of array subclass"
65+
if s.__dict__.keys() != ['color']:
66+
raise TestFailed, "array subclass __dict__"
67+
68+
class ExaggeratingArray(array.array):
69+
__slots__ = ['offset']
70+
71+
def __new__(cls, typecode, data, offset):
72+
return array.array.__new__(cls, typecode, data)
73+
74+
def __init__(self, typecode, data, offset):
75+
self.offset = offset
76+
77+
def __getitem__(self, i):
78+
return array.array.__getitem__(self, i) + self.offset
79+
80+
a = ExaggeratingArray('i', [3, 6, 7, 11], 4)
81+
if a[0] != 7:
82+
raise TestFailed, "array subclass overriding __getitem__"
83+
try:
84+
a.color = 'blue'
85+
except AttributeError:
86+
pass
87+
else:
88+
raise TestFailed, "array subclass __slots__ was ignored"
89+
1790

1891
def testoverflow(type, lowerLimit, upperLimit):
1992
# should not overflow assigning lower limit
@@ -54,7 +127,6 @@ def testoverflow(type, lowerLimit, upperLimit):
54127

55128

56129
def testtype(type, example):
57-
58130
a = array.array(type)
59131
a.append(example)
60132
if verbose:
@@ -97,6 +169,33 @@ def testtype(type, example):
97169
print 'array of %s converted to a string: ' \
98170
% a.typecode, `a.tostring()`
99171

172+
# Try out inplace addition and multiplication
173+
a = array.array(type, [example])
174+
b = a
175+
a += array.array(type, [example]*2)
176+
if a is not b:
177+
raise TestFailed, "array(%s) inplace addition" % `type`
178+
if a != array.array(type, [example] * 3):
179+
raise TestFailed, "array(%s) inplace addition" % `type`
180+
181+
a *= 5
182+
if a is not b:
183+
raise TestFailed, "array(%s) inplace multiplication" % `type`
184+
if a != array.array(type, [example] * 15):
185+
raise TestFailed, "array(%s) inplace multiplication" % `type`
186+
187+
a *= 0
188+
if a is not b:
189+
raise TestFailed, "array(%s) inplace multiplication by 0" % `type`
190+
if a != array.array(type, []):
191+
raise TestFailed, "array(%s) inplace multiplication by 0" % `type`
192+
193+
a *= 1000
194+
if a is not b:
195+
raise TestFailed, "empty array(%s) inplace multiplication" % `type`
196+
if a != array.array(type, []):
197+
raise TestFailed, "empty array(%s) inplace multiplication" % `type`
198+
100199
if type == 'c':
101200
a = array.array(type, "abcde")
102201
a[:-1] = a
@@ -135,6 +234,44 @@ def testtype(type, example):
135234
a.reverse()
136235
if a != array.array(type, "dca"):
137236
raise TestFailed, "array(%s) reverse-test" % `type`
237+
elif type == 'u':
238+
a = array.array(type, u"abcde")
239+
a[:-1] = a
240+
if a != array.array(type, u"abcdee"):
241+
raise TestFailed, "array(%s) self-slice-assign (head)" % `type`
242+
a = array.array(type, u"abcde")
243+
a[1:] = a
244+
if a != array.array(type, u"aabcde"):
245+
raise TestFailed, "array(%s) self-slice-assign (tail)" % `type`
246+
a = array.array(type, u"abcde")
247+
a[1:-1] = a
248+
if a != array.array(type, u"aabcdee"):
249+
raise TestFailed, "array(%s) self-slice-assign (cntr)" % `type`
250+
if a.index(u"e") != 5:
251+
raise TestFailed, "array(%s) index-test" % `type`
252+
if a.count(u"a") != 2:
253+
raise TestFailed, "array(%s) count-test" % `type`
254+
a.remove(u"e")
255+
if a != array.array(type, u"aabcde"):
256+
raise TestFailed, "array(%s) remove-test" % `type`
257+
if a.pop(0) != u"a":
258+
raise TestFailed, "array(%s) pop-test" % `type`
259+
if a.pop(1) != u"b":
260+
raise TestFailed, "array(%s) pop-test" % `type`
261+
a.extend(array.array(type, u"xyz"))
262+
if a != array.array(type, u"acdexyz"):
263+
raise TestFailed, "array(%s) extend-test" % `type`
264+
a.pop()
265+
a.pop()
266+
a.pop()
267+
x = a.pop()
268+
if x != u'e':
269+
raise TestFailed, "array(%s) pop-test" % `type`
270+
if a != array.array(type, u"acd"):
271+
raise TestFailed, "array(%s) pop-test" % `type`
272+
a.reverse()
273+
if a != array.array(type, u"dca"):
274+
raise TestFailed, "array(%s) reverse-test" % `type`
138275
else:
139276
a = array.array(type, [1, 2, 3, 4, 5])
140277
a[:-1] = a

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ Core and builtins
1717

1818
Extension modules
1919

20+
- array.array is now a type object. A new format character
21+
'u' indicates Py_UNICODE arrays. For those, .tounicode and
22+
.fromunicode methods are available. Arrays now support __iadd__
23+
and __imul__.
24+
2025
- dl now builds on every system that has dlfcn.h. Failure in case
2126
of sizeof(int)!=sizeof(long)!=sizeof(void*) is delayed until dl.open
2227
is called.

0 commit comments

Comments
 (0)