Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
99866336
Commit
99866336
authored
Mar 01, 2002
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch 520694: arraymodule.c improvements:
- make array.array a type - add Py_UNICODE arrays - support +=, *=
parent
272cb40e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
491 additions
and
122 deletions
+491
-122
Doc/lib/libarray.tex
Doc/lib/libarray.tex
+29
-11
Lib/test/test_array.py
Lib/test/test_array.py
+141
-4
Misc/NEWS
Misc/NEWS
+5
-0
Modules/arraymodule.c
Modules/arraymodule.c
+316
-107
No files found.
Doc/lib/libarray.tex
View file @
99866336
...
...
@@ -5,7 +5,7 @@
\modulesynopsis
{
Efficient arrays of uniformly typed numeric values.
}
This module defines a
new
object type which can efficiently represent
This module defines a
n
object type which can efficiently represent
an array of basic values: characters, integers, floating point
numbers. Arrays
\index
{
arrays
}
are sequence types and behave very much
like lists, except that the type of objects stored in them is
...
...
@@ -17,6 +17,7 @@ codes are defined:
\lineiii
{
'c'
}{
character
}{
1
}
\lineiii
{
'b'
}{
signed int
}{
1
}
\lineiii
{
'B'
}{
unsigned int
}{
1
}
\lineiii
{
'u'
}{
Unicode character
}{
2
}
\lineiii
{
'h'
}{
signed int
}{
2
}
\lineiii
{
'H'
}{
unsigned int
}{
2
}
\lineiii
{
'i'
}{
signed int
}{
2
}
...
...
@@ -35,23 +36,25 @@ Python long integers when retrieved, because Python's plain integer
type cannot represent the full range of C's unsigned (long) integers.
The module defines the following
function and type object
:
The module defines the following
type
:
\begin{funcdesc}
{
array
}{
typecode
\optional
{
, initializer
}}
Return a new array whose items are restricted by
\var
{
typecode
}
, and
initialized from the optional
\var
{
initializer
}
value, which must be a
list or a string. The list or string is passed to the new array's
\method
{
fromlist()
}
or
\method
{
fromstring()
}
method (see below) to add
initial items to the array.
Return a new array whose items are restricted by
\var
{
typecode
}
,
and initialized from the optional
\var
{
initializer
}
value, which
must be a list or a string. The list or string is passed to the
new array's
\method
{
fromlist()
}
,
\method
{
fromstring()
}
, or
\method
{
fromunicode()
}
method (see below) to add initial items to
the array.
\end{funcdesc}
\begin{datadesc}
{
ArrayType
}
Type object corresponding to the objects returned by
\function
{
array()
}
.
Obsolete alias for
\function
{
array
}
.
\end{datadesc}
Array objects support the following data items and methods:
Array objects support the ordinary sequence operations of
indexing, slicing, concatenation, and multiplication. The
following data items and methods are also supported:
\begin{memberdesc}
[array]
{
typecode
}
The typecode character used to create the array.
...
...
@@ -121,6 +124,13 @@ array of machine values (as if it had been read from a
file using the
\method
{
fromfile()
}
method).
\end{methoddesc}
\begin{methoddesc}
[array]
{
fromunicode
}{
s
}
Extends this array with data from the given unicode string.
The array must be a type 'u' array; otherwise a ValueError
is raised. Use
\samp
{
array.fromstring(ustr.decode(enc))
}
to
append Unicode data to an array of some other type.
\end{methoddesc}
\begin{methoddesc}
[array]
{
index
}{
x
}
Return the smallest
\var
{
i
}
such that
\var
{
i
}
is the index of
the first occurence of
\var
{
x
}
in the array.
...
...
@@ -134,7 +144,7 @@ Insert a new item with value \var{x} in the array before position
\begin{methoddesc}
[array]
{
pop
}{
\optional
{
i
}}
Removes the item with the index
\var
{
i
}
from the array and returns
it. The optional argument defaults to
\code
{
-1
}
, so that by default
the last item is removed and returned.
the last item is removed and returned.
\end{methoddesc}
\begin{methoddesc}
[array]
{
read
}{
f, n
}
...
...
@@ -170,6 +180,13 @@ string representation (the same sequence of bytes that would
be written to a file by the
\method
{
tofile()
}
method.)
\end{methoddesc}
\begin{methoddesc}
[array]
{
tounicode
}{}
Convert the array to a unicode string. The array must be
a type 'u' array; otherwise a ValueError is raised. Use
array.tostring().decode(enc) to obtain a unicode string
from an array of some other type.
\end{methoddesc}
\begin{methoddesc}
[array]
{
write
}{
f
}
\deprecated
{
1.5.1
}
{
Use the
\method
{
tofile()
}
method.
}
...
...
@@ -188,6 +205,7 @@ imported using \code{from array import array}. Examples:
\begin{verbatim}
array('l')
array('c', 'hello world')
array('u', u'hello
\textbackslash
u2641')
array('l', [1, 2, 3, 4, 5])
array('d', [1.0, 2.0, 3.14])
\end{verbatim}
...
...
Lib/test/test_array.py
View file @
99866336
...
...
@@ -6,14 +6,87 @@ import array
from
test_support
import
verbose
,
TESTFN
,
unlink
,
TestFailed
def
main
():
testtype
(
'c'
,
'c'
)
testtype
(
'u'
,
u'
\
u263a
'
)
for
type
in
([
'b'
,
'h'
,
'i'
,
'l'
,
'f'
,
'd'
]):
testtype
(
type
,
1
)
testunicode
()
testsubclassing
()
unlink
(
TESTFN
)
def
testunicode
():
try
:
array
.
array
(
'b'
,
u'foo'
)
except
TypeError
:
pass
else
:
raise
TestFailed
(
"creating a non-unicode array from "
"a Unicode string should fail"
)
x
=
array
.
array
(
'u'
,
u'
\
xa0
\
xc2
\
u1234
'
)
x
.
fromunicode
(
u' '
)
x
.
fromunicode
(
u''
)
x
.
fromunicode
(
u''
)
x
.
fromunicode
(
u'
\
x11
abc
\
xff
\
u1234
'
)
s
=
x
.
tounicode
()
if
s
!=
u'
\
xa0
\
xc2
\
u1234
\
x11
abc
\
xff
\
u1234
'
:
raise
TestFailed
(
"fromunicode()/tounicode()"
)
s
=
u'
\
x00
="
\
'
a
\
\
b
\
x80
\
xff
\
u0000
\
u0001
\
u1234
'
a
=
array
.
array
(
'u'
,
s
)
if
verbose
:
print
"repr of type 'u' array:"
,
repr
(
a
)
print
" expected: array('u', %r)"
%
s
def
testsubclassing
():
class
EditableString
(
array
.
array
):
def
__new__
(
cls
,
s
,
*
args
,
**
kwargs
):
return
array
.
array
.
__new__
(
cls
,
'c'
,
s
)
def
__init__
(
self
,
s
,
color
=
'blue'
):
array
.
array
.
__init__
(
self
,
'c'
,
s
)
self
.
color
=
color
def
strip
(
self
):
self
[:]
=
array
.
array
(
'c'
,
self
.
tostring
().
strip
())
def
__repr__
(
self
):
return
'EditableString(%r)'
%
self
.
tostring
()
s
=
EditableString
(
"
\
t
test
\
r
\
n
"
)
s
.
strip
()
if
s
.
tostring
()
!=
'test'
:
raise
TestFailed
,
"subclassing array.array failed somewhere"
if
s
.
color
!=
'blue'
:
raise
TestFailed
,
"assigning attributes to instance of array subclass"
s
.
color
=
'red'
if
s
.
color
!=
'red'
:
raise
TestFailed
,
"assigning attributes to instance of array subclass"
if
s
.
__dict__
.
keys
()
!=
[
'color'
]:
raise
TestFailed
,
"array subclass __dict__"
class
ExaggeratingArray
(
array
.
array
):
__slots__
=
[
'offset'
]
def
__new__
(
cls
,
typecode
,
data
,
offset
):
return
array
.
array
.
__new__
(
cls
,
typecode
,
data
)
def
__init__
(
self
,
typecode
,
data
,
offset
):
self
.
offset
=
offset
def
__getitem__
(
self
,
i
):
return
array
.
array
.
__getitem__
(
self
,
i
)
+
self
.
offset
a
=
ExaggeratingArray
(
'i'
,
[
3
,
6
,
7
,
11
],
4
)
if
a
[
0
]
!=
7
:
raise
TestFailed
,
"array subclass overriding __getitem__"
try
:
a
.
color
=
'blue'
except
AttributeError
:
pass
else
:
raise
TestFailed
,
"array subclass __slots__ was ignored"
def
testoverflow
(
type
,
lowerLimit
,
upperLimit
):
# should not overflow assigning lower limit
...
...
@@ -54,7 +127,6 @@ def testoverflow(type, lowerLimit, upperLimit):
def
testtype
(
type
,
example
):
a
=
array
.
array
(
type
)
a
.
append
(
example
)
if
verbose
:
...
...
@@ -97,6 +169,33 @@ def testtype(type, example):
print
'array of %s converted to a string: '
\
%
a
.
typecode
,
`a.tostring()`
# Try out inplace addition and multiplication
a
=
array
.
array
(
type
,
[
example
])
b
=
a
a
+=
array
.
array
(
type
,
[
example
]
*
2
)
if
a
is
not
b
:
raise
TestFailed
,
"array(%s) inplace addition"
%
`type`
if
a
!=
array
.
array
(
type
,
[
example
]
*
3
):
raise
TestFailed
,
"array(%s) inplace addition"
%
`type`
a
*=
5
if
a
is
not
b
:
raise
TestFailed
,
"array(%s) inplace multiplication"
%
`type`
if
a
!=
array
.
array
(
type
,
[
example
]
*
15
):
raise
TestFailed
,
"array(%s) inplace multiplication"
%
`type`
a
*=
0
if
a
is
not
b
:
raise
TestFailed
,
"array(%s) inplace multiplication by 0"
%
`type`
if
a
!=
array
.
array
(
type
,
[]):
raise
TestFailed
,
"array(%s) inplace multiplication by 0"
%
`type`
a
*=
1000
if
a
is
not
b
:
raise
TestFailed
,
"empty array(%s) inplace multiplication"
%
`type`
if
a
!=
array
.
array
(
type
,
[]):
raise
TestFailed
,
"empty array(%s) inplace multiplication"
%
`type`
if
type
==
'c'
:
a
=
array
.
array
(
type
,
"abcde"
)
a
[:
-
1
]
=
a
...
...
@@ -135,6 +234,44 @@ def testtype(type, example):
a
.
reverse
()
if
a
!=
array
.
array
(
type
,
"dca"
):
raise
TestFailed
,
"array(%s) reverse-test"
%
`type`
elif
type
==
'u'
:
a
=
array
.
array
(
type
,
u"abcde"
)
a
[:
-
1
]
=
a
if
a
!=
array
.
array
(
type
,
u"abcdee"
):
raise
TestFailed
,
"array(%s) self-slice-assign (head)"
%
`type`
a
=
array
.
array
(
type
,
u"abcde"
)
a
[
1
:]
=
a
if
a
!=
array
.
array
(
type
,
u"aabcde"
):
raise
TestFailed
,
"array(%s) self-slice-assign (tail)"
%
`type`
a
=
array
.
array
(
type
,
u"abcde"
)
a
[
1
:
-
1
]
=
a
if
a
!=
array
.
array
(
type
,
u"aabcdee"
):
raise
TestFailed
,
"array(%s) self-slice-assign (cntr)"
%
`type`
if
a
.
index
(
u"e"
)
!=
5
:
raise
TestFailed
,
"array(%s) index-test"
%
`type`
if
a
.
count
(
u"a"
)
!=
2
:
raise
TestFailed
,
"array(%s) count-test"
%
`type`
a
.
remove
(
u"e"
)
if
a
!=
array
.
array
(
type
,
u"aabcde"
):
raise
TestFailed
,
"array(%s) remove-test"
%
`type`
if
a
.
pop
(
0
)
!=
u"a"
:
raise
TestFailed
,
"array(%s) pop-test"
%
`type`
if
a
.
pop
(
1
)
!=
u"b"
:
raise
TestFailed
,
"array(%s) pop-test"
%
`type`
a
.
extend
(
array
.
array
(
type
,
u"xyz"
))
if
a
!=
array
.
array
(
type
,
u"acdexyz"
):
raise
TestFailed
,
"array(%s) extend-test"
%
`type`
a
.
pop
()
a
.
pop
()
a
.
pop
()
x
=
a
.
pop
()
if
x
!=
u'e'
:
raise
TestFailed
,
"array(%s) pop-test"
%
`type`
if
a
!=
array
.
array
(
type
,
u"acd"
):
raise
TestFailed
,
"array(%s) pop-test"
%
`type`
a
.
reverse
()
if
a
!=
array
.
array
(
type
,
u"dca"
):
raise
TestFailed
,
"array(%s) reverse-test"
%
`type`
else
:
a
=
array
.
array
(
type
,
[
1
,
2
,
3
,
4
,
5
])
a
[:
-
1
]
=
a
...
...
Misc/NEWS
View file @
99866336
...
...
@@ -17,6 +17,11 @@ Core and builtins
Extension modules
- array.array is now a type object. A new format character
'u' indicates Py_UNICODE arrays. For those, .tounicode and
.fromunicode methods are available. Arrays now support __iadd__
and __imul__.
- dl now builds on every system that has dlfcn.h. Failure in case
of sizeof(int)!=sizeof(long)!=sizeof(void*) is delayed until dl.open
is called.
...
...
Modules/arraymodule.c
View file @
99866336
...
...
@@ -27,14 +27,16 @@ struct arraydescr {
};
typedef
struct
arrayobject
{
PyObject_VAR_HEAD
PyObject_HEAD
int
ob_size
;
char
*
ob_item
;
struct
arraydescr
*
ob_descr
;
}
arrayobject
;
staticforward
PyTypeObject
Arraytype
;
#define is_arrayobject(op) ((op)->ob_type == &Arraytype)
#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
#define array_CheckExact(op) ((op)->ob_type == &Arraytype)
/****************************************************************************
Get and Set functions for each type.
...
...
@@ -61,7 +63,7 @@ c_setitem(arrayobject *ap, int i, PyObject *v)
if
(
!
PyArg_Parse
(
v
,
"c;array item must be char"
,
&
x
))
return
-
1
;
if
(
i
>=
0
)
((
char
*
)
ap
->
ob_item
)[
i
]
=
x
;
((
char
*
)
ap
->
ob_item
)[
i
]
=
x
;
return
0
;
}
...
...
@@ -113,10 +115,35 @@ BB_setitem(arrayobject *ap, int i, PyObject *v)
if
(
!
PyArg_Parse
(
v
,
"b;array item must be integer"
,
&
x
))
return
-
1
;
if
(
i
>=
0
)
((
char
*
)
ap
->
ob_item
)[
i
]
=
x
;
((
char
*
)
ap
->
ob_item
)[
i
]
=
x
;
return
0
;
}
#ifdef Py_USING_UNICODE
static
PyObject
*
u_getitem
(
arrayobject
*
ap
,
int
i
)
{
return
PyUnicode_FromUnicode
(
&
((
Py_UNICODE
*
)
ap
->
ob_item
)[
i
],
1
);
}
static
int
u_setitem
(
arrayobject
*
ap
,
int
i
,
PyObject
*
v
)
{
Py_UNICODE
*
p
;
int
len
;
if
(
!
PyArg_Parse
(
v
,
"u#;array item must be unicode character"
,
&
p
,
&
len
))
return
-
1
;
if
(
len
!=
1
)
{
PyErr_SetString
(
PyExc_TypeError
,
"array item must be unicode character"
);
return
-
1
;
}
if
(
i
>=
0
)
((
Py_UNICODE
*
)
ap
->
ob_item
)[
i
]
=
p
[
0
];
return
0
;
}
#endif
static
PyObject
*
h_getitem
(
arrayobject
*
ap
,
int
i
)
{
...
...
@@ -315,6 +342,9 @@ static struct arraydescr descriptors[] = {
{
'c'
,
sizeof
(
char
),
c_getitem
,
c_setitem
},
{
'b'
,
sizeof
(
char
),
b_getitem
,
b_setitem
},
{
'B'
,
sizeof
(
char
),
BB_getitem
,
BB_setitem
},
#ifdef Py_USING_UNICODE
{
'u'
,
sizeof
(
Py_UNICODE
),
u_getitem
,
u_setitem
},
#endif
{
'h'
,
sizeof
(
short
),
h_getitem
,
h_setitem
},
{
'H'
,
sizeof
(
short
),
HH_getitem
,
HH_setitem
},
{
'i'
,
sizeof
(
int
),
i_getitem
,
i_setitem
},
...
...
@@ -331,23 +361,26 @@ Implementations of array object methods.
****************************************************************************/
static
PyObject
*
newarrayobject
(
int
size
,
struct
arraydescr
*
descr
)
newarrayobject
(
PyTypeObject
*
type
,
int
size
,
struct
arraydescr
*
descr
)
{
arrayobject
*
op
;
size_t
nbytes
;
if
(
size
<
0
)
{
PyErr_BadInternalCall
();
return
NULL
;
}
nbytes
=
size
*
descr
->
itemsize
;
/* Check for overflow */
if
(
nbytes
/
descr
->
itemsize
!=
(
size_t
)
size
)
{
return
PyErr_NoMemory
();
}
op
=
PyObject_NewVar
(
arrayobject
,
&
Arraytype
,
size
);
op
=
(
arrayobject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
op
==
NULL
)
{
return
PyErr_NoMemory
()
;
return
NULL
;
}
op
->
ob_size
=
size
;
if
(
size
<=
0
)
{
op
->
ob_item
=
NULL
;
}
...
...
@@ -366,7 +399,7 @@ static PyObject *
getarrayitem
(
PyObject
*
op
,
int
i
)
{
register
arrayobject
*
ap
;
assert
(
is_arrayobject
(
op
));
assert
(
array_Check
(
op
));
ap
=
(
arrayobject
*
)
op
;
if
(
i
<
0
||
i
>=
ap
->
ob_size
)
{
PyErr_SetString
(
PyExc_IndexError
,
"array index out of range"
);
...
...
@@ -411,7 +444,7 @@ array_dealloc(arrayobject *op)
{
if
(
op
->
ob_item
!=
NULL
)
PyMem_DEL
(
op
->
ob_item
);
PyObject_Del
(
op
);
op
->
ob_type
->
tp_free
((
PyObject
*
)
op
);
}
static
PyObject
*
...
...
@@ -423,7 +456,7 @@ array_richcompare(PyObject *v, PyObject *w, int op)
int
i
,
k
;
PyObject
*
res
;
if
(
!
is_arrayobject
(
v
)
||
!
is_arrayobject
(
w
))
{
if
(
!
array_Check
(
v
)
||
!
array_Check
(
w
))
{
Py_INCREF
(
Py_NotImplemented
);
return
Py_NotImplemented
;
}
...
...
@@ -530,7 +563,7 @@ array_slice(arrayobject *a, int ilow, int ihigh)
ihigh
=
ilow
;
else
if
(
ihigh
>
a
->
ob_size
)
ihigh
=
a
->
ob_size
;
np
=
(
arrayobject
*
)
newarrayobject
(
ihigh
-
ilow
,
a
->
ob_descr
);
np
=
(
arrayobject
*
)
newarrayobject
(
&
Arraytype
,
ihigh
-
ilow
,
a
->
ob_descr
);
if
(
np
==
NULL
)
return
NULL
;
memcpy
(
np
->
ob_item
,
a
->
ob_item
+
ilow
*
a
->
ob_descr
->
itemsize
,
...
...
@@ -543,7 +576,7 @@ array_concat(arrayobject *a, PyObject *bb)
{
int
size
;
arrayobject
*
np
;
if
(
!
is_arrayobject
(
bb
))
{
if
(
!
array_Check
(
bb
))
{
PyErr_Format
(
PyExc_TypeError
,
"can only append array (not
\"
%.200s
\"
) to array"
,
bb
->
ob_type
->
tp_name
);
...
...
@@ -555,7 +588,7 @@ array_concat(arrayobject *a, PyObject *bb)
return
NULL
;
}
size
=
a
->
ob_size
+
b
->
ob_size
;
np
=
(
arrayobject
*
)
newarrayobject
(
size
,
a
->
ob_descr
);
np
=
(
arrayobject
*
)
newarrayobject
(
&
Arraytype
,
size
,
a
->
ob_descr
);
if
(
np
==
NULL
)
{
return
NULL
;
}
...
...
@@ -577,7 +610,7 @@ array_repeat(arrayobject *a, int n)
if
(
n
<
0
)
n
=
0
;
size
=
a
->
ob_size
*
n
;
np
=
(
arrayobject
*
)
newarrayobject
(
size
,
a
->
ob_descr
);
np
=
(
arrayobject
*
)
newarrayobject
(
&
Arraytype
,
size
,
a
->
ob_descr
);
if
(
np
==
NULL
)
return
NULL
;
p
=
np
->
ob_item
;
...
...
@@ -598,7 +631,7 @@ array_ass_slice(arrayobject *a, int ilow, int ihigh, PyObject *v)
#define b ((arrayobject *)v)
if
(
v
==
NULL
)
n
=
0
;
else
if
(
is_arrayobject
(
v
))
{
else
if
(
array_Check
(
v
))
{
n
=
b
->
ob_size
;
if
(
a
==
b
)
{
/* Special case "a[i:j] = a" -- copy b first */
...
...
@@ -676,10 +709,85 @@ array_ass_item(arrayobject *a, int i, PyObject *v)
static
int
setarrayitem
(
PyObject
*
a
,
int
i
,
PyObject
*
v
)
{
assert
(
is_arrayobject
(
a
));
assert
(
array_Check
(
a
));
return
array_ass_item
((
arrayobject
*
)
a
,
i
,
v
);
}
static
int
array_do_extend
(
arrayobject
*
self
,
PyObject
*
bb
)
{
int
size
;
if
(
!
array_Check
(
bb
))
{
PyErr_Format
(
PyExc_TypeError
,
"can only extend array with array (not
\"
%.200s
\"
)"
,
bb
->
ob_type
->
tp_name
);
return
-
1
;
}
#define b ((arrayobject *)bb)
if
(
self
->
ob_descr
!=
b
->
ob_descr
)
{
PyErr_SetString
(
PyExc_TypeError
,
"can only extend with array of same kind"
);
return
-
1
;
}
size
=
self
->
ob_size
+
b
->
ob_size
;
PyMem_RESIZE
(
self
->
ob_item
,
char
,
size
*
self
->
ob_descr
->
itemsize
);
if
(
self
->
ob_item
==
NULL
)
{
PyObject_Del
(
self
);
PyErr_NoMemory
();
return
-
1
;
}
memcpy
(
self
->
ob_item
+
self
->
ob_size
*
self
->
ob_descr
->
itemsize
,
b
->
ob_item
,
b
->
ob_size
*
b
->
ob_descr
->
itemsize
);
self
->
ob_size
=
size
;
return
0
;
#undef b
}
static
PyObject
*
array_inplace_concat
(
arrayobject
*
self
,
PyObject
*
bb
)
{
if
(
array_do_extend
(
self
,
bb
)
==
-
1
)
return
NULL
;
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
static
PyObject
*
array_inplace_repeat
(
arrayobject
*
self
,
int
n
)
{
char
*
items
,
*
p
;
int
size
,
i
;
if
(
self
->
ob_size
>
0
)
{
if
(
n
<
0
)
n
=
0
;
items
=
self
->
ob_item
;
size
=
self
->
ob_size
*
self
->
ob_descr
->
itemsize
;
if
(
n
==
0
)
{
PyMem_FREE
(
items
);
self
->
ob_item
=
NULL
;
self
->
ob_size
=
0
;
}
else
{
PyMem_Resize
(
items
,
char
,
n
*
size
);
if
(
items
==
NULL
)
return
PyErr_NoMemory
();
p
=
items
;
for
(
i
=
1
;
i
<
n
;
i
++
)
{
p
+=
size
;
memcpy
(
p
,
items
,
size
);
}
self
->
ob_item
=
items
;
self
->
ob_size
*=
n
;
}
}
Py_INCREF
(
self
);
return
(
PyObject
*
)
self
;
}
static
PyObject
*
ins
(
arrayobject
*
self
,
int
where
,
PyObject
*
v
)
{
...
...
@@ -807,36 +915,14 @@ Return the i-th element and delete it from the array. i defaults to -1.";
static
PyObject
*
array_extend
(
arrayobject
*
self
,
PyObject
*
args
)
{
int
size
;
PyObject
*
bb
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:extend"
,
&
bb
))
return
NULL
;
if
(
!
is_arrayobject
(
bb
))
{
PyErr_Format
(
PyExc_TypeError
,
"can only extend array with array (not
\"
%.200s
\"
)"
,
bb
->
ob_type
->
tp_name
);
return
NULL
;
}
#define b ((arrayobject *)bb)
if
(
self
->
ob_descr
!=
b
->
ob_descr
)
{
PyErr_SetString
(
PyExc_TypeError
,
"can only extend with array of same kind"
);
if
(
array_do_extend
(
self
,
bb
)
==
-
1
)
return
NULL
;
}
size
=
self
->
ob_size
+
b
->
ob_size
;
PyMem_RESIZE
(
self
->
ob_item
,
char
,
size
*
self
->
ob_descr
->
itemsize
);
if
(
self
->
ob_item
==
NULL
)
{
PyObject_Del
(
self
);
return
PyErr_NoMemory
();
}
memcpy
(
self
->
ob_item
+
self
->
ob_size
*
self
->
ob_descr
->
itemsize
,
b
->
ob_item
,
b
->
ob_size
*
b
->
ob_descr
->
itemsize
);
self
->
ob_size
=
size
;
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
#undef b
}
static
char
extend_doc
[]
=
...
...
@@ -1203,6 +1289,94 @@ static char tostring_doc [] =
Convert the array to an array of machine values and return the string
\n
\
representation."
;
#ifdef Py_USING_UNICODE
static
PyObject
*
array_fromunicode
(
arrayobject
*
self
,
PyObject
*
args
)
{
Py_UNICODE
*
ustr
;
int
n
;
if
(
!
PyArg_ParseTuple
(
args
,
"u#:fromunicode"
,
&
ustr
,
&
n
))
return
NULL
;
if
(
self
->
ob_descr
->
typecode
!=
'u'
)
{
PyErr_SetString
(
PyExc_ValueError
,
"fromunicode() may only be called on "
"type 'u' arrays"
);
return
NULL
;
}
if
(
n
>
0
)
{
Py_UNICODE
*
item
=
(
Py_UNICODE
*
)
self
->
ob_item
;
PyMem_RESIZE
(
item
,
Py_UNICODE
,
self
->
ob_size
+
n
);
if
(
item
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
self
->
ob_item
=
(
char
*
)
item
;
self
->
ob_size
+=
n
;
memcpy
(
item
+
self
->
ob_size
-
n
,
ustr
,
n
*
sizeof
(
Py_UNICODE
));
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
fromunicode_doc
[]
=
"fromunicode(ustr)
\n
\
\n
\
Extends this array with data from the unicode string ustr.
\n
\
The array must be a type 'u' array; otherwise a ValueError
\n
\
is raised. Use array.fromstring(ustr.decode(...)) to
\n
\
append Unicode data to an array of some other type."
;
static
PyObject
*
array_tounicode
(
arrayobject
*
self
,
PyObject
*
args
)
{
if
(
!
PyArg_ParseTuple
(
args
,
":tounicode"
))
return
NULL
;
if
(
self
->
ob_descr
->
typecode
!=
'u'
)
{
PyErr_SetString
(
PyExc_ValueError
,
"tounicode() may only be called on type 'u' arrays"
);
return
NULL
;
}
return
PyUnicode_FromUnicode
((
Py_UNICODE
*
)
self
->
ob_item
,
self
->
ob_size
);
}
static
char
tounicode_doc
[]
=
"tounicode() -> unicode
\n
\
\n
\
Convert the array to a unicode string. The array must be
\n
\
a type 'u' array; otherwise a ValueError is raised. Use
\n
\
array.tostring().decode() to obtain a unicode string from
\n
\
an array of some other type."
;
#endif
/* Py_USING_UNICODE */
static
PyObject
*
array_get_typecode
(
arrayobject
*
a
,
void
*
closure
)
{
char
tc
=
a
->
ob_descr
->
typecode
;
return
PyString_FromStringAndSize
(
&
tc
,
1
);
}
static
PyObject
*
array_get_itemsize
(
arrayobject
*
a
,
void
*
closure
)
{
return
PyInt_FromLong
((
long
)
a
->
ob_descr
->
itemsize
);
}
static
PyGetSetDef
array_getsets
[]
=
{
{
"typecode"
,
(
getter
)
array_get_typecode
,
NULL
,
"the typecode character used to create the array"
},
{
"itemsize"
,
(
getter
)
array_get_itemsize
,
NULL
,
"the size, in bytes, of one array item"
},
{
NULL
}
};
PyMethodDef
array_methods
[]
=
{
{
"append"
,
(
PyCFunction
)
array_append
,
METH_VARARGS
,
append_doc
},
...
...
@@ -1220,6 +1394,10 @@ PyMethodDef array_methods[] = {
fromlist_doc
},
{
"fromstring"
,
(
PyCFunction
)
array_fromstring
,
METH_VARARGS
,
fromstring_doc
},
#ifdef Py_USING_UNICODE
{
"fromunicode"
,
(
PyCFunction
)
array_fromunicode
,
METH_VARARGS
,
fromunicode_doc
},
#endif
{
"index"
,
(
PyCFunction
)
array_index
,
METH_VARARGS
,
index_doc
},
{
"insert"
,
(
PyCFunction
)
array_insert
,
METH_VARARGS
,
...
...
@@ -1240,38 +1418,15 @@ PyMethodDef array_methods[] = {
tolist_doc
},
{
"tostring"
,
(
PyCFunction
)
array_tostring
,
METH_VARARGS
,
tostring_doc
},
#ifdef Py_USING_UNICODE
{
"tounicode"
,
(
PyCFunction
)
array_tounicode
,
METH_VARARGS
,
tounicode_doc
},
#endif
{
"write"
,
(
PyCFunction
)
array_tofile
,
METH_VARARGS
,
tofile_doc
},
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
array_getattr
(
arrayobject
*
a
,
char
*
name
)
{
if
(
strcmp
(
name
,
"typecode"
)
==
0
)
{
char
tc
=
a
->
ob_descr
->
typecode
;
return
PyString_FromStringAndSize
(
&
tc
,
1
);
}
if
(
strcmp
(
name
,
"itemsize"
)
==
0
)
{
return
PyInt_FromLong
((
long
)
a
->
ob_descr
->
itemsize
);
}
if
(
strcmp
(
name
,
"__members__"
)
==
0
)
{
PyObject
*
list
=
PyList_New
(
2
);
if
(
list
)
{
PyList_SetItem
(
list
,
0
,
PyString_FromString
(
"typecode"
));
PyList_SetItem
(
list
,
1
,
PyString_FromString
(
"itemsize"
));
if
(
PyErr_Occurred
())
{
Py_DECREF
(
list
);
list
=
NULL
;
}
}
return
list
;
}
return
Py_FindMethod
(
array_methods
,
(
PyObject
*
)
a
,
name
);
}
static
int
array_print
(
arrayobject
*
a
,
FILE
*
fp
,
int
flags
)
{
...
...
@@ -1308,20 +1463,25 @@ array_print(arrayobject *a, FILE *fp, int flags)
static
PyObject
*
array_repr
(
arrayobject
*
a
)
{
char
buf
[
256
];
char
buf
[
256
]
,
typecode
;
PyObject
*
s
,
*
t
,
*
comma
,
*
v
;
int
i
,
len
;
len
=
a
->
ob_size
;
typecode
=
a
->
ob_descr
->
typecode
;
if
(
len
==
0
)
{
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('%c')"
,
a
->
ob_descr
->
typecode
);
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('%c')"
,
typecode
);
return
PyString_FromString
(
buf
);
}
if
(
a
->
ob_descr
->
typecode
==
'c'
)
{
if
(
typecode
==
'c'
||
typecode
==
'u'
)
{
PyObject
*
t_empty
=
PyTuple_New
(
0
);
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('
c', "
);
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('
%c', "
,
typecode
);
s
=
PyString_FromString
(
buf
);
v
=
array_tostring
(
a
,
t_empty
);
if
(
typecode
==
'c'
)
v
=
array_tostring
(
a
,
t_empty
);
else
v
=
array_tounicode
(
a
,
t_empty
);
Py_DECREF
(
t_empty
);
t
=
PyObject_Repr
(
v
);
Py_XDECREF
(
v
);
...
...
@@ -1329,7 +1489,7 @@ array_repr(arrayobject *a)
PyString_ConcatAndDel
(
&
s
,
PyString_FromString
(
")"
));
return
s
;
}
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('%c', ["
,
a
->
ob_descr
->
typecode
);
PyOS_snprintf
(
buf
,
sizeof
(
buf
),
"array('%c', ["
,
typecode
);
s
=
PyString_FromString
(
buf
);
comma
=
PyString_FromString
(
", "
);
for
(
i
=
0
;
i
<
len
&&
!
PyErr_Occurred
();
i
++
)
{
...
...
@@ -1385,6 +1545,9 @@ static PySequenceMethods array_as_sequence = {
(
intintargfunc
)
array_slice
,
/*sq_slice*/
(
intobjargproc
)
array_ass_item
,
/*sq_ass_item*/
(
intintobjargproc
)
array_ass_slice
,
/*sq_ass_slice*/
NULL
,
/*sq_contains*/
(
binaryfunc
)
array_inplace_concat
,
/*sq_inplace_concat*/
(
intargfunc
)
array_inplace_repeat
/*sq_inplace_repeat*/
};
static
PyBufferProcs
array_as_buffer
=
{
...
...
@@ -1394,21 +1557,34 @@ static PyBufferProcs array_as_buffer = {
};
static
PyObject
*
a
_array
(
PyObject
*
self
,
PyObject
*
arg
s
)
a
rray_new
(
PyTypeObject
*
type
,
PyObject
*
args
,
PyObject
*
kwd
s
)
{
char
c
;
PyObject
*
initial
=
NULL
;
struct
arraydescr
*
descr
;
if
(
!
PyArg_ParseTuple
(
args
,
"c:array"
,
&
c
))
{
PyErr_Clear
();
if
(
!
PyArg_ParseTuple
(
args
,
"cO:array"
,
&
c
,
&
initial
))
if
(
kwds
!=
NULL
)
{
int
i
=
PyObject_Length
(
kwds
);
if
(
i
<
0
)
return
NULL
;
if
(
!
PyList_Check
(
initial
)
&&
!
PyString_Check
(
initial
)
)
{
else
if
(
i
>
0
)
{
PyErr_SetString
(
PyExc_TypeError
,
"array initializer must be list or string"
);
"array.array constructor takes "
"no keyword arguments"
);
return
NULL
;
}
}
if
(
!
PyArg_ParseTuple
(
args
,
"c|O:array"
,
&
c
,
&
initial
))
return
NULL
;
if
(
!
(
initial
==
NULL
||
PyList_Check
(
initial
)
||
PyString_Check
(
initial
)
||
(
c
==
'u'
&&
PyUnicode_Check
(
initial
))))
{
PyErr_SetString
(
PyExc_TypeError
,
"array initializer must be list or string"
);
return
NULL
;
}
for
(
descr
=
descriptors
;
descr
->
typecode
!=
'\0'
;
descr
++
)
{
if
(
descr
->
typecode
==
c
)
{
PyObject
*
a
;
...
...
@@ -1417,14 +1593,16 @@ a_array(PyObject *self, PyObject *args)
len
=
0
;
else
len
=
PyList_Size
(
initial
);
a
=
newarrayobject
(
len
,
descr
);
a
=
newarrayobject
(
type
,
len
,
descr
);
if
(
a
==
NULL
)
return
NULL
;
if
(
len
>
0
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
PyObject
*
v
=
PyList_GetItem
(
initial
,
i
);
PyList_GetItem
(
initial
,
i
);
if
(
setarrayitem
(
a
,
i
,
v
)
!=
0
)
{
Py_DECREF
(
a
);
return
NULL
;
...
...
@@ -1437,35 +1615,41 @@ a_array(PyObject *self, PyObject *args)
PyObject
*
v
=
array_fromstring
((
arrayobject
*
)
a
,
t_initial
);
Py_DECREF
(
t_initial
);
Py_DECREF
(
t_initial
);
if
(
v
==
NULL
)
{
Py_DECREF
(
a
);
return
NULL
;
}
Py_DECREF
(
v
);
#ifdef Py_USING_UNICODE
}
else
if
(
initial
!=
NULL
&&
PyUnicode_Check
(
initial
))
{
int
n
=
PyUnicode_GET_DATA_SIZE
(
initial
);
if
(
n
>
0
)
{
arrayobject
*
self
=
(
arrayobject
*
)
a
;
char
*
item
=
self
->
ob_item
;
item
=
PyMem_Realloc
(
item
,
n
);
if
(
item
==
NULL
)
{
PyErr_NoMemory
();
Py_DECREF
(
a
);
return
NULL
;
}
self
->
ob_item
=
item
;
self
->
ob_size
=
n
/
sizeof
(
Py_UNICODE
);
memcpy
(
item
,
PyUnicode_AS_DATA
(
initial
),
n
);
}
#endif
}
return
a
;
}
}
PyErr_SetString
(
PyExc_ValueError
,
"bad typecode (must be c, b, B, h, H, i, I, l, L, f or d)"
);
"bad typecode (must be c, b, B,
u,
h, H, i, I, l, L, f or d)"
);
return
NULL
;
}
static
char
a_array_doc
[]
=
"array(typecode [, initializer]) -> array
\n
\
\n
\
Return a new array whose items are restricted by typecode, and
\n
\
initialized from the optional initializer value, which must be a list
\n
\
or a string."
;
static
PyMethodDef
a_methods
[]
=
{
{
"array"
,
a_array
,
METH_VARARGS
,
a_array_doc
},
{
NULL
,
NULL
}
/* sentinel */
};
static
char
module_doc
[]
=
"This module defines a
new
object type which can efficiently represent
\n
\
"This module defines a
n
object type which can efficiently represent
\n
\
an array of basic values: characters, integers, floating point
\n
\
numbers. Arrays are sequence types and behave very much like lists,
\n
\
except that the type of objects stored in them is constrained. The
\n
\
...
...
@@ -1476,6 +1660,7 @@ is a single character. The following type codes are defined:\n\
'c' character 1
\n
\
'b' signed integer 1
\n
\
'B' unsigned integer 1
\n
\
'u' Unicode character 2
\n
\
'h' signed integer 2
\n
\
'H' unsigned integer 2
\n
\
'i' signed integer 2
\n
\
...
...
@@ -1485,17 +1670,19 @@ is a single character. The following type codes are defined:\n\
'f' floating point 4
\n
\
'd' floating point 8
\n
\
\n
\
Function
s:
\n
\
The constructor i
s:
\n
\
\n
\
array(typecode [, initializer]) -- create a new array
\n
\
\n
\
Special Objects:
\n
\
\n
\
ArrayType -- type object for array objects
\n
\
"
;
static
char
arraytype_doc
[]
=
"An array represents basic values and behave very much like lists, except
\n
\
"array(typecode [, initializer]) -> array
\n
\
\n
\
Return a new array whose items are restricted by typecode, and
\n
\
initialized from the optional initializer value, which must be a list
\n
\
or a string.
\n
\
\n
\
Arrays represent basic values and behave very much like lists, except
\n
\
the type of objects stored in them is constrained.
\n
\
\n
\
Methods:
\n
\
...
...
@@ -1519,7 +1706,7 @@ tolist() -- return the array converted to an ordinary list\n\
tostring() -- return the array converted to a string
\n
\
write() -- DEPRECATED, use tofile()
\n
\
\n
\
Variabl
es:
\n
\
Attribut
es:
\n
\
\n
\
typecode -- the typecode character used to create the array
\n
\
itemsize -- the length in bytes of one array item
\n
\
...
...
@@ -1533,7 +1720,7 @@ statichere PyTypeObject Arraytype = {
0
,
(
destructor
)
array_dealloc
,
/* tp_dealloc */
(
printfunc
)
array_print
,
/* tp_print */
(
getattrfunc
)
array_getattr
,
/* tp_getattr */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
(
reprfunc
)
array_repr
,
/* tp_repr */
...
...
@@ -1543,24 +1730,46 @@ statichere PyTypeObject Arraytype = {
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
0
,
/* tp_getattro */
PyObject_GenericGetAttr
,
/* tp_getattro */
0
,
/* tp_setattro */
&
array_as_buffer
,
/* tp_as_buffer*/
Py_TPFLAGS_DEFAULT
,
/* tp_flags */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
arraytype_doc
,
/* tp_doc */
0
,
/* tp_traverse */
0
,
/* tp_clear */
array_richcompare
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_iter */
0
,
/* tp_iternext */
array_methods
,
/* tp_methods */
0
,
/* tp_members */
array_getsets
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
0
,
/* tp_dictoffset */
0
,
/* tp_init */
PyType_GenericAlloc
,
/* tp_alloc */
array_new
,
/* tp_new */
_PyObject_Del
,
/* tp_free */
};
/* No functions in array module. */
static
PyMethodDef
a_methods
[]
=
{
{
NULL
,
NULL
,
0
,
NULL
}
/* Sentinel */
};
DL_EXPORT
(
void
)
initarray
(
void
)
{
PyObject
*
m
,
*
d
;
Arraytype
.
ob_type
=
&
PyType_Type
;
Arraytype
.
ob_type
=
&
PyType_Type
;
m
=
Py_InitModule3
(
"array"
,
a_methods
,
module_doc
);
d
=
PyModule_GetDict
(
m
);
PyDict_SetItemString
(
d
,
"ArrayType"
,
(
PyObject
*
)
&
Arraytype
);
PyDict_SetItemString
(
d
,
"array"
,
(
PyObject
*
)
&
Arraytype
);
/* No need to check the error here, the caller will do that */
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment