[pypy-svn] r15604 - in pypy/dist: lib-python lib-python/modified-2.4.1/test pypy/interpreter pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/array
nik at codespeak.net
nik at codespeak.net
Thu Aug 4 12:06:16 CEST 2005
Author: nik
Date: Thu Aug 4 12:06:12 2005
New Revision: 15604
Added:
pypy/dist/lib-python/modified-2.4.1/test/test_array.py
- copied, changed from r15538, pypy/dist/lib-python/2.4.1/test/test_array.py
pypy/dist/pypy/module/array/
pypy/dist/pypy/module/array/__init__.py (contents, props changed)
pypy/dist/pypy/module/array/app_array.py (contents, props changed)
Modified:
pypy/dist/lib-python/conftest.py
pypy/dist/pypy/interpreter/baseobjspace.py
pypy/dist/pypy/module/__builtin__/app_buffer.py
pypy/dist/pypy/module/__builtin__/test/test_buffer.py
Log:
integrated the array module. this one doesn't break the translation. ;)
in fact i have also been able to translate successfully with _sre enabled -
the problem was the faked array module.
Modified: pypy/dist/lib-python/conftest.py
==============================================================================
--- pypy/dist/lib-python/conftest.py (original)
+++ pypy/dist/lib-python/conftest.py Thu Aug 4 12:06:12 2005
@@ -355,7 +355,7 @@
RegrTest('test_al.py', enabled=False, dumbtest=1),
RegrTest('test_anydbm.py', enabled=True, core=True),
RegrTest('test_applesingle.py', enabled=False),
- RegrTest('test_array.py', enabled=False),
+ RegrTest('test_array.py', enabled=True),
RegrTest('test_asynchat.py', enabled=False),
RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True),
RegrTest('test_audioop.py', enabled=False, dumbtest=1),
Copied: pypy/dist/lib-python/modified-2.4.1/test/test_array.py (from r15538, pypy/dist/lib-python/2.4.1/test/test_array.py)
==============================================================================
--- pypy/dist/lib-python/2.4.1/test/test_array.py (original)
+++ pypy/dist/lib-python/modified-2.4.1/test/test_array.py Thu Aug 4 12:06:12 2005
@@ -5,7 +5,7 @@
import unittest
from test import test_support
-from weakref import proxy
+#from weakref import proxy
import array, cStringIO, math
tests = [] # list to accumulate all tests
@@ -635,7 +635,8 @@
b = buffer(a)
self.assertEqual(b[0], a.tostring()[0])
- def test_weakref(self):
+ def DONOTtest_weakref(self):
+ # XXX disabled until PyPy grows weakref support
s = array.array(self.typecode, self.example)
p = proxy(s)
self.assertEqual(p.tostring(), s.tostring())
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Aug 4 12:06:12 2005
@@ -163,7 +163,8 @@
except AttributeError:
pass
- modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs']
+ modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs',
+ 'array']
if self.options.nofaking:
modules.append('posix')
Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/app_buffer.py (original)
+++ pypy/dist/pypy/module/__builtin__/app_buffer.py Thu Aug 4 12:06:12 2005
@@ -1,5 +1,7 @@
+# NOT_RPYTHON (because of array import)
# Might probably be deprecated in Python at some point.
import sys
+from array import array
from struct import pack, unpack
class buffer(object):
@@ -25,8 +27,9 @@
object = str_object
elif isinstance(object, buffer):
object = object.buf
+ elif isinstance(object, array):
+ object = object.tostring()
else:
- # XXX check for more types
raise TypeError, "buffer object expected"
if offset < 0:
raise ValueError, "offset must be zero or positive"
Modified: pypy/dist/pypy/module/__builtin__/test/test_buffer.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/test/test_buffer.py (original)
+++ pypy/dist/pypy/module/__builtin__/test/test_buffer.py Thu Aug 4 12:06:12 2005
@@ -19,3 +19,9 @@
assert b[0:8] == "\x00\x00\x00a\x00\x00\x00b"
else:
assert b[0:8] == "a\x00\x00\x00b\x00\x00\x00"
+
+ def test_array_buffer(self):
+ import array
+ b = buffer(array.array("B", [1, 2, 3]))
+ assert len(b) == 3
+ assert b[0:3] == "\x01\x02\x03"
Added: pypy/dist/pypy/module/array/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/array/__init__.py Thu Aug 4 12:06:12 2005
@@ -0,0 +1,11 @@
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+ appleveldefs = {
+ '__doc__' : 'app_array.__doc__',
+ '__name__' : 'app_array.__name__',
+ 'array' : 'app_array.array',
+ 'ArrayType' : 'app_array.ArrayType',
+ }
+ interpleveldefs = {
+ }
Added: pypy/dist/pypy/module/array/app_array.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/array/app_array.py Thu Aug 4 12:06:12 2005
@@ -0,0 +1,480 @@
+# NOT_RPYTHON
+"""This module defines an object type which can efficiently represent
+an array of basic values: characters, integers, floating point
+numbers. Arrays are sequence types and behave very much like lists,
+except that the type of objects stored in them is constrained. The
+type is specified at object creation time by using a type code, which
+is a single character. The following type codes are defined:
+
+ Type code C Type Minimum size in bytes
+ 'c' character 1
+ 'b' signed integer 1
+ 'B' unsigned integer 1
+ 'u' Unicode character 2
+ 'h' signed integer 2
+ 'H' unsigned integer 2
+ 'i' signed integer 2
+ 'I' unsigned integer 2
+ 'l' signed integer 4
+ 'L' unsigned integer 4
+ 'f' floating point 4
+ 'd' floating point 8
+
+The constructor is:
+
+array(typecode [, initializer]) -- create a new array
+"""
+import sys
+from struct import pack, unpack
+
+if sys.maxunicode == 65535:
+ UNICODE_SIZE = 2
+ UNICODE_FORMAT = "H"
+else:
+ UNICODE_SIZE = 4
+ UNICODE_FORMAT = "I"
+
+def c_type_check(x):
+ if not isinstance(x, str) or len(x) != 1:
+ raise TypeError("array item must be char")
+ return x
+
+def general_int_type_check(x, lower_bound, upper_bound):
+ if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)):
+ raise TypeError("an integer is required")
+ x_int = int(x)
+ if not (x_int >= lower_bound and x_int <= upper_bound):
+ raise OverflowError("integer is not in the allowed range")
+ return x_int
+
+def b_type_check(x):
+ return general_int_type_check(x, -128, 127)
+
+def BB_type_check(x):
+ return general_int_type_check(x, 0, 255)
+
+def u_type_check(x):
+ if isinstance(x, str):
+ if len(x) / UNICODE_SIZE == 1:
+ # XXX Problem: CPython will gladly accept any unicode codepoint
+ # up to 0xFFFFFFFF in UCS-4 builds here, but unichr which is used
+ # to implement decode for unicode_internal in PyPy will
+ # reject anything above 0x00110000. I don't think there is a
+ # way to replicate CPython behaviour without resorting to C.
+ x_uni = x[:UNICODE_SIZE].decode("unicode_internal")
+ else:
+ raise TypeError("array item must be unicode character")
+ elif isinstance(x, unicode):
+ x_uni = x
+ else:
+ raise TypeError("array item must be unicode character")
+ if len(x_uni) != 1:
+ raise TypeError("array item must be unicode character")
+ return x_uni
+
+def h_type_check(x):
+ return general_int_type_check(x, -32768, 32767)
+
+def HH_type_check(x):
+ return general_int_type_check(x, 0, 65535)
+
+def i_type_check(x):
+ return general_int_type_check(x, -2147483648, 2147483647)
+
+def general_long_type_check(x, lower_bound, upper_bound):
+ if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)):
+ raise TypeError("an integer is required")
+ x_long = long(x)
+ if not (x_long >= lower_bound and x_long <= upper_bound):
+ raise OverflowError("integer/long is not in the allowed range")
+ return x_long
+
+def II_type_check(x):
+ return general_long_type_check(x, 0, 4294967295L)
+
+l_type_check = i_type_check
+
+LL_type_check = II_type_check
+
+def f_type_check(x):
+ if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)):
+ raise TypeError("a float is required")
+ x_float = float(x)
+ # XXX This is not exactly a nice way of checking bounds. Formerly, I tried
+ # this: return unpack("f", pack("f", x_float))[0]
+ # Which works in CPython, but PyPy struct is not currently intelligent
+ # enough to handle this.
+ if x_float > 3.4028e38:
+ x_float = 3.4028e38
+ elif x_float < -3.4028e38:
+ x_float = -3.4028e38
+ return x_float
+
+def d_type_check(x):
+ if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)):
+ raise TypeError("a float is required")
+ return float(x)
+
+def dummy_type_check(x):
+ return x
+
+# XXX Assuming fixed sizes of the different types, independent of platform.
+# These are the same assumptions that struct makes at the moment.
+descriptors = {
+ 'c' : ('char', 1, c_type_check),
+ 'b' : ('signed char', 1, b_type_check),
+ 'B' : ('unsigned char', 1, BB_type_check),
+ 'u' : ('Py_UNICODE', UNICODE_SIZE, u_type_check),
+ 'h' : ('signed short', 2, h_type_check),
+ 'H' : ('unsigned short', 2, HH_type_check),
+ 'i' : ('signed int', 4, i_type_check),
+ 'I' : ('unsigned int', 4, II_type_check),
+ 'l' : ('signed long', 4, l_type_check),
+ 'L' : ('unsigned long', 4, LL_type_check),
+ 'f' : ('float', 4, f_type_check),
+ 'd' : ('double', 8, d_type_check),
+}
+
+class array(object):
+ """array(typecode [, initializer]) -> array
+
+ Return a new array whose items are restricted by typecode, and
+ initialized from the optional initializer value, which must be a list,
+ string. or iterable over elements of the appropriate type.
+
+ Arrays represent basic values and behave very much like lists, except
+ the type of objects stored in them is constrained.
+
+ Methods:
+
+ append() -- append a new item to the end of the array
+ buffer_info() -- return information giving the current memory info
+ byteswap() -- byteswap all the items of the array
+ count() -- return number of occurences of an object
+ extend() -- extend array by appending multiple elements from an iterable
+ fromfile() -- read items from a file object
+ fromlist() -- append items from the list
+ fromstring() -- append items from the string
+ index() -- return index of first occurence of an object
+ insert() -- insert a new item into the array at a provided position
+ pop() -- remove and return item (default last)
+ read() -- DEPRECATED, use fromfile()
+ remove() -- remove first occurence of an object
+ reverse() -- reverse the order of the items in the array
+ tofile() -- write all items to a file object
+ tolist() -- return the array converted to an ordinary list
+ tostring() -- return the array converted to a string
+ write() -- DEPRECATED, use tofile()
+
+ Attributes:
+
+ typecode -- the typecode character used to create the array
+ itemsize -- the length in bytes of one array item
+ """
+ __slots__ = ["typecode", "itemsize", "_data", "_descriptor", "__weakref__"]
+
+ def __new__(cls, typecode, initializer=[]):
+ self = object.__new__(cls)
+ if not isinstance(typecode, str) or len(typecode) != 1:
+ raise TypeError(
+ "array() argument 1 must be char, not %s" % type(typecode))
+ if not descriptors.has_key(typecode):
+ raise ValueError(
+ "bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)")
+ self._descriptor = descriptors[typecode]
+ self._data = []
+ self.typecode = typecode
+ self.itemsize = self._descriptor[1]
+ if isinstance(initializer, list):
+ self.fromlist(initializer)
+ elif isinstance(initializer, str):
+ self.fromstring(initializer)
+ elif isinstance(initializer, unicode) and self.typecode == "u":
+ self.fromunicode(initializer)
+ else:
+ self.extend(initializer)
+ return self
+
+ ##### array-specific operations
+
+ def fromfile(self, f, n):
+ """Read n objects from the file object f and append them to the end of
+ the array. Also called as read."""
+ if not isinstance(f, file):
+ raise TypeError("arg1 must be open file")
+ for i in range(n):
+ item = f.read(self.itemsize)
+ if len(item) < self.itemsize:
+ raise EOFError("not enough items in file")
+ self.fromstring(item)
+
+ def fromlist(self, l):
+ """Append items to array from list."""
+ if not isinstance(l, list):
+ raise TypeError("arg must be list")
+ self._fromiterable(l)
+
+ def fromstring(self, s):
+ """Appends items from the string, interpreting it as an array of machine
+ values, as if it had been read from a file using the fromfile()
+ method)."""
+ if isinstance(s, unicode):
+ s = str(s)
+ if not (isinstance(s, str) or isinstance(s, buffer)):
+ raise TypeError(
+ "fromstring() argument 1 must be string or read-only buffer")
+ if len(s) % self.itemsize != 0:
+ raise ValueError("string length not a multiple of item size")
+ items = []
+ if self.typecode == "u":
+ for i in range(0, len(s), self.itemsize):
+ items.append(u_type_check(s[i:i + self.itemsize]))
+ else:
+ for i in range(0, len(s), self.itemsize):
+ item = unpack(self.typecode, s[i:i + self.itemsize])[0]
+ # the item needn't be type checked if unpack succeeded
+ items.append(item)
+ self._data.extend(items)
+
+ def fromunicode(self, ustr):
+ """Extends this array with data from the unicode string ustr. The array
+ must be a type 'u' array; otherwise a ValueError is raised. Use
+ array.fromstring(ustr.encode(...)) to append Unicode data to an array of
+ some other type."""
+ if not self.typecode == "u":
+ raise ValueError(
+ "fromunicode() may only be called on type 'u' arrays")
+ if isinstance(ustr, unicode):
+ self._fromiterable(ustr)
+ elif isinstance(ustr, str) or isinstance(ustr, buffer):
+ # CPython strangely truncates string arguments at multiples of the
+ # unicode byte size ...
+ trunc_s = ustr[:len(ustr) - (len(ustr) % self.itemsize)]
+ self.fromstring(trunc_s)
+ else:
+ raise TypeError(
+ "fromunicode() argument 1 must be string or read-only buffer")
+
+ def tofile(self, f):
+ """Write all items (as machine values) to the file object f. Also
+ called as write."""
+ if not isinstance(f, file):
+ raise TypeError("arg must be open file")
+ f.write(self.tostring())
+
+ def tolist(self):
+ """Convert array to an ordinary list with the same items."""
+ return self._data[:]
+
+ def tostring(self):
+ """Convert the array to an array of machine values and return the string
+ representation."""
+ if self.typecode == "u":
+ return u"".join(self._data).encode("unicode_internal")
+ else:
+ strings = []
+ for item in self._data:
+ strings.append(pack(self.typecode, item))
+ return "".join(strings)
+
+ def tounicode(self):
+ """Convert the array to a unicode string. The array must be a type 'u'
+ array; otherwise a ValueError is raised. Use array.tostring().decode()
+ to obtain a unicode string from an array of some other type."""
+ if self.typecode != "u":
+ raise ValueError("tounicode() may only be called on type 'u' arrays")
+ return u"".join(self._data)
+
+ def byteswap(self):
+ """Byteswap all items of the array. If the items in the array are not
+ 1, 2, 4, or 8 bytes in size, RuntimeError is raised."""
+ if self.itemsize not in [1, 2, 4, 8]:
+ raise RuntimeError("byteswap not supported for this array")
+ bytes = self.tostring()
+ swapped = []
+ for offset in range(0, len(self._data) * self.itemsize, self.itemsize):
+ l = list(bytes[offset:offset + self.itemsize])
+ l.reverse()
+ swapped += l
+ self._data = []
+ self.fromstring("".join(swapped))
+
+ def buffer_info(self):
+ """Return a tuple (address, length) giving the current memory address
+ and the length in items of the buffer used to hold array's contents. The
+ length should be multiplied by the itemsize attribute to calculate the
+ buffer length in bytes. In PyPy the return values are not really
+ meaningful."""
+ return (0, len(self._data))
+
+ read = fromfile
+
+ write = tofile
+
+ ##### general object protocol
+
+ def __repr__(self):
+ if len(self._data) == 0:
+ return "array('%s')" % self.typecode
+ elif self.typecode == "c":
+ return "array('%s', %s)" % (self.typecode, repr(self.tostring()))
+ elif self.typecode == "u":
+ return "array('%s', %s)" % (self.typecode, repr(self.tounicode()))
+ else:
+ return "array('%s', %s)" % (self.typecode, repr(self.tolist()))
+
+ def __copy__(self):
+ a = array(self.typecode)
+ a._data = self._data[:]
+ return a
+
+ def __eq__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data == other._data
+
+ def __ne__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data != other._data
+
+ def __lt__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data < other._data
+
+ def __gt__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data > other._data
+
+ def __le__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data <= other._data
+
+ def __ge__(self, other):
+ if not isinstance(other, array):
+ return NotImplemented
+ return self._data >= other._data
+
+ ##### list methods
+
+ def append(self, x):
+ """Append new value x to the end of the array."""
+ x_checked = self._type_check(x)
+ self._data.append(x_checked)
+
+ def count(self, x):
+ """Return number of occurences of x in the array."""
+ return self._data.count(x)
+
+ def extend(self, iterable):
+ """Append items to the end of the array."""
+ if isinstance(iterable, array) \
+ and not self.typecode == iterable.typecode:
+ raise TypeError("can only extend with array of same kind")
+ self._fromiterable(iterable)
+
+ def index(self, x):
+ """Return index of first occurence of x in the array."""
+ return self._data.index(x)
+
+ def insert(self, i, x):
+ """Insert a new item x into the array before position i."""
+ x_checked = self._type_check(x)
+ self._data.insert(i, x_checked)
+
+ def pop(self, i=-1):
+ """Return the i-th element and delete it from the array. i defaults to
+ -1."""
+ return self._data.pop(i)
+
+ def remove(self, x):
+ """Remove the first occurence of x in the array."""
+ self._data.remove(x)
+
+ def reverse(self):
+ """Reverse the order of the items in the array."""
+ self._data.reverse()
+
+ ##### list protocol
+
+ def __len__(self):
+ return len(self._data)
+
+ def __add__(self, other):
+ if not isinstance(other, array):
+ raise TypeError("can only append array to array")
+ if self.typecode != other.typecode:
+ raise TypeError("bad argument type for built-in operation")
+ return array(self.typecode, self._data + other._data)
+
+ def __mul__(self, repeat):
+ return array(self.typecode, self._data * repeat)
+
+ __rmul__ = __mul__
+
+ def __getitem__(self, i):
+ if isinstance(i, slice):
+ sliced = array(self.typecode)
+ sliced._data = self._data[i]
+ return sliced
+ return self._data[i]
+
+ def __getslice__(self, i, j):
+ return self.__getitem__(slice(i, j))
+
+ def __setitem__(self, i, x):
+ if isinstance(i, slice):
+ if not isinstance(x, array):
+ raise TypeError("can only assign array to array slice")
+ if x.typecode != self.typecode:
+ raise TypeError("bad argument type for built-in operation")
+ self._data[i] = x._data
+ return
+ if not (isinstance(i, int) or isinstance(i, long)):
+ raise TypeError("list indices must be integers")
+ if i >= len(self._data) or i < -len(self._data):
+ raise IndexError("array assignment index out of range")
+ x_checked = self._type_check(x)
+ self._data[i] = x_checked
+
+ def __setslice__(self, i, j, x):
+ self.__setitem__(slice(i, j), x)
+
+ def __delitem__(self, i):
+ del self._data[i]
+
+ def __delslice__(self, i, j):
+ self.__delitem__(slice(i, j))
+
+ def __contains__(self, item):
+ return item in self._data
+
+ def __iadd__(self, other):
+ if not isinstance(other, array):
+ raise TypeError("can only extend array with array")
+ self.extend(other)
+ return self
+
+ def __imul__(self, repeat):
+ self._data *= repeat
+ return self
+
+ def __iter__(self):
+ return iter(self._data)
+
+ ##### internal methods
+
+ def _type_check(self, x):
+ return self._descriptor[2](x)
+
+ def _fromiterable(self, iterable):
+ items = []
+ for item in iterable:
+ item_checked = self._type_check(item)
+ items.append(item_checked)
+ self._data.extend(items)
+
+ArrayType = array
More information about the Pypy-commit
mailing list