[prev in list] [next in list] [prev in thread] [next in thread]
List: pypy-svn
Subject: [pypy-commit] pypy ppc-vsx-support: merge default
From: plan_rich <pypy.commits () gmail ! com>
Date: 2016-10-31 6:25:25
Message-ID: 5816e3d5.031f1c0a.81841.ba6b () mx ! google ! com
[Download RAW message or body]
Author: Richard Plangger <planrichi@gmail.com>
Branch: ppc-vsx-support
Changeset: r87998:57b804b140a5
Date: 2016-10-31 08:24 +0200
http://bitbucket.org/pypy/pypy/changeset/57b804b140a5/
Log: merge default
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -29,7 +29,7 @@
class deque(object):
def __new__(cls, iterable=(), *args, **kw):
- self = super(deque, cls).__new__(cls, *args, **kw)
+ self = super(deque, cls).__new__(cls)
self.clear()
return self
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -229,7 +229,7 @@
__metaclass__ = StructOrUnionMeta
def __new__(cls, *args, **kwds):
- self = super(_CData, cls).__new__(cls, *args, **kwds)
+ self = super(_CData, cls).__new__(cls)
if '_abstract_' in cls.__dict__:
raise TypeError("abstract class")
if hasattr(cls, '_ffistruct_'):
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -334,6 +334,8 @@
realtype, quals = self._get_type_and_quals(
decl.type, name=decl.name, partial_length_ok=True)
self._declare('typedef ' + decl.name, realtype, quals=quals)
+ elif decl.__class__.__name__ == 'Pragma':
+ pass # skip pragma, only in pycparser 2.15
else:
raise api.CDefError("unrecognized construct", decl)
except api.FFIError as e:
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -519,10 +519,18 @@
smallest_value = min(self.enumvalues)
largest_value = max(self.enumvalues)
else:
- raise api.CDefError("%r has no values explicitly defined: "
- "refusing to guess which integer type it is "
- "meant to be (unsigned/signed, int/long)"
- % self._get_c_name())
+ import warnings
+ try:
+ # XXX! The goal is to ensure that the warnings.warn()
+ # will not suppress the warning. We want to get it
+ # several times if we reach this point several times.
+ __warningregistry__.clear()
+ except NameError:
+ pass
+ warnings.warn("%r has no values explicitly defined; "
+ "guessing that it is equivalent to 'unsigned int'"
+ % self._get_c_name())
+ smallest_value = largest_value = 0
if smallest_value < 0: # needs a signed type
sign = 1
candidate1 = PrimitiveType("int")
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -1,4 +1,5 @@
import os
+import sys
try:
basestring
@@ -74,8 +75,13 @@
Add py_limited_api to kwds if setuptools >= 26 is in use.
Do not alter the setting if it already exists.
Setuptools takes care of ignoring the flag on Python 2 and PyPy.
+
+ CPython itself should ignore the flag in a debugging version
+ (by not listing .abi3.so in the extensions it supports), but
+ it doesn't so far, creating troubles. That's why we check
+ for "not sys.flags.debug". (http://bugs.python.org/issue28401)
"""
- if 'py_limited_api' not in kwds:
+ if 'py_limited_api' not in kwds and not sys.flags.debug:
import setuptools
try:
setuptools_major_version = int(setuptools.__version__.partition('.')[0])
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -397,3 +397,13 @@
in auto-generated C code, and at least some knowledge about the
various components involved, from PyPy's own RPython source code to
the GC and possibly the JIT.
+
+
+Why doesn't PyPy move to GitHub, Gitlab, ...?
+----------------------------------------------
+
+We've been quite happy with bitbucket.org. Moving version control systems and
+hosting is a lot of hard work: On the one hand, PyPy's mercurial history is
+long and gnarly. On the other hand, all our infrastructure (buildbots,
+benchmarking, etc) would have to be adapted. So unless somebody steps up and
+volunteers to do all that work, it will likely not happen.
diff --git a/pypy/doc/install.rst b/pypy/doc/install.rst
--- a/pypy/doc/install.rst
+++ b/pypy/doc/install.rst
@@ -1,8 +1,17 @@
Downloading and Installing PyPy
===============================
+Using a packaged PyPy
+~~~~~~~~~~~~~~~~~~~~~
+
+Some Linux distributions provide a pypy package. Note that in order to
+install additional modules that require compilation, you may need to install
+additional packages such as pypy-dev. This will manifest as an error about
+"missing Python.h". Distributions do not as of yet supply many pypy-ready
+packages, if you require additional modules we recommend creating a virtualenv
+and using pip.
+
.. _prebuilt-pypy:
-
Download a pre-built PyPy
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -38,6 +47,9 @@
and not move the binary there, else PyPy would not be able to find its
library.
+Installing more modules
+~~~~~~~~~~~~~~~~~~~~~~~
+
If you want to install 3rd party libraries, the most convenient way is
to install pip_ using ensurepip_ (unless you want to install virtualenv as
explained below; then you can directly use pip inside virtualenvs):
diff --git a/pypy/doc/release-pypy2.7-v5.6.0.rst \
b/pypy/doc/release-pypy2.7-v5.6.0.rst new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-pypy2.7-v5.6.0.rst
@@ -0,0 +1,142 @@
+============
+PyPy2.7 v5.6
+============
+
+We have released PyPy2.7 v5.6, about two months after PyPy2.7 v5.4.
+This new PyPy2.7 release includes the upstream stdlib version 2.7.12.
+
+We continue to make incremental improvements to our C-API
+compatability layer (cpyext). We pass all but a few of the tests in the
+upstream numpy `test suite`_.
+
+Work proceeds at a good pace on the PyPy3.5
+version due to a grant_ from the Mozilla Foundation, and some of those
+changes have been backported to PyPy2.7 where relevant
+
+We changed ``timeit`` to now report average +- standard deviation, which is
+better than the misleading minimum value reported in CPython.
+
+XXX
+
+As always, this release fixed many issues and bugs raised by the
+growing community of PyPy users. We strongly recommend updating.
+
+You can download the PyPy2.7 v5.6 release here:
+
+ http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project.
+
+We would also like to thank our contributors and
+encourage new people to join the project. PyPy has many
+layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation
+improvements, tweaking popular `modules`_ to run on pypy, or general `help`_
+with making RPython's JIT even better.
+
+.. _`test suite`: https://bitbucket.org/pypy/pypy/wiki/Adventures%20in%20cpyext%20compatibility
+.. _cffi: https://cffi.readthedocs.org
+.. _grant: https://morepypy.blogspot.com/2016/08/pypy-gets-funding-from-mozilla-for.html
+.. _`PyPy`: http://doc.pypy.org
+.. _`RPython`: https://rpython.readthedocs.org
+.. _`modules`: http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly
+.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`PyPy and CPython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+We also welcome developers of other `dynamic languages`_ to see what RPython
+can do for them.
+
+This release supports:
+
+ * **x86** machines on most common operating systems
+ (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD)
+
+ * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux,
+
+ * big- and little-endian variants of **PPC64** running Linux,
+
+ * **s390x** running Linux
+
+.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://pypyjs.org
+
+Other Highlights (since 5.4 released Aug 31, 2016)
+=========================================================
+
+* New features
+ * Allow tests run with `-A` to find `libm.so` even if it is a script not a
+ dynamically loadable file
+ * Backport fixes to rposix on windows from py2.5
+ * Allow user-defined ``__getitem__`` on subclasses of ``str`` and ``unicode``
+ * Add ``inode`` to ``scandir()`` on posix systems
+ * Support more attributes on ``super``
+ * Issue #2386: non-latin1 unicode keys were ignored in ``unicode.format(**d)``
+ * Restore the ability to translate with CPython
+ * Update to CFFI 1.8.4
+ * Support the new buffer protocol in cpyext and numpypy
+ * Add ``rposix.sync()``
+ * Support full-precision nanosecond times in os.stat()
+ * Add documentation about the assembler backends to RPYthon
+ * Search for the stdlibs from the libpypy shared object rather than the pypy-c \
exe, + changes downstream packaging requirments
+ * Add ``try_inline``, like ``always_inline`` and ``dont_inline`` to RPython
+ * Reject ``'a'.strip(buffer(' '))`` like cpython (the argument to strip must
+ be ``str`` or ``unicode``)
+ * Allow ``warning.warn(('something', 1), Warning)`` like on CPython
+ * Refactor ``rclock`` and add some more ``CLOCK_xxx`` constants on
+ relevant platforms
+ * Backport the ``'faulthandler`` module from py3.5
+ * Improve the error message when trying to call a method where the ``self``
+ parameter is missing in the definition
+ * Implement ``rposix.cpu_count``
+ * Support translation on FreeBSD running on PowerPC
+ * Implement ``__rmod__`` on ``str`` and ``unicode`` types
+ * Issue warnings for stricter handling of ``__new__``, ``__init__`` args
+
+* Bug Fixes
+ * Tweak a float comparison with 0 in `backendopt.inline` to avoid rounding errors
+ * Fix translation of the sandbox
+ * Fix for an issue where `unicode.decode('utf8', 'custom_replace')` messed up
+ the last byte of a unicode string sometimes
+ * fix some calls to functions through window's COM interface
+ * fix minor leak when the C call to socketpair() fails
+ * make sure (-1.0 + 0j).__hash__(), (-1.0).__hash__() returns -2
+ * Fix for an issue where PyBytesResize was called on a fresh pyobj
+ * Fix bug in codewriter about passing the ``exitswitch`` variable to a call
+ * Don't crash in ``merge_if_blocks`` if the values are symbolics
+ * Issue #2325/2361: __class__ assignment between two classes with the same
+ slots
+ * Issue #2409: don't leak the file descriptor when doing ``open('some-dir')``
+ * Windows fixes around vmprof
+ * Don't use ``sprintf()`` from inside a signal handler
+ * Test and fix bug from the ``guard_not_forced_2`` branch, which didn't
+ save the floating-point register
+ * ``_numpypy.add.reduce`` returns a scalar now
+
+* Performance improvements:
+ * Improve method calls on oldstyle classes
+ * Clean and refactor code for testing cpyext to allow sharing with py3.5
+ * Refactor a building the map of reflected ops in ``_numpypy``
+ * Improve merging of virtual states in the JIT in order to avoid jumping to the
+ preamble
+ * In JIT residual calls, if the called function starts with a fast-path like
+ ``if x.foo != 0: return x.foo``, then inline the check before doing the
+ ``CALL``.
+ * Ensure ``make_inputargs`` fails properly when given arguments with type
+ information
+ * Makes ``optimiseopt`` iterative instead of recursive so it can be reasoned
+ about more easily and debugging is faster
+ * Refactor and remove dead code from ``optimizeopt``, ``resume``
+
+
+.. _resolved: http://doc.pypy.org/en/latest/whatsnew-5.6.0.html
+
+Please update, and continue to help us make PyPy better.
+
+Cheers
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -73,11 +73,8 @@
exc_value = str(w_value)
else:
w = space.wrap
- if space.is_w(space.type(self.w_type), space.w_str):
- exc_typename = space.str_w(self.w_type)
- else:
- exc_typename = space.str_w(
- space.getattr(self.w_type, w('__name__')))
+ exc_typename = space.str_w(
+ space.getattr(self.w_type, w('__name__')))
if space.is_w(w_value, space.w_None):
exc_value = ""
else:
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -611,7 +611,7 @@
class StaticMethod(W_Root):
"""The staticmethod objects."""
- _immutable_fields_ = ['w_function']
+ _immutable_fields_ = ['w_function?']
def __init__(self, w_function):
self.w_function = w_function
@@ -622,13 +622,16 @@
def descr_staticmethod__new__(space, w_subtype, w_function):
instance = space.allocate_instance(StaticMethod, w_subtype)
- instance.__init__(w_function)
- return space.wrap(instance)
+ instance.__init__(space.w_None)
+ return instance
+
+ def descr_init(self, space, w_function):
+ self.w_function = w_function
class ClassMethod(W_Root):
"""The classmethod objects."""
- _immutable_fields_ = ['w_function']
+ _immutable_fields_ = ['w_function?']
def __init__(self, w_function):
self.w_function = w_function
@@ -641,8 +644,11 @@
def descr_classmethod__new__(space, w_subtype, w_function):
instance = space.allocate_instance(ClassMethod, w_subtype)
- instance.__init__(w_function)
- return space.wrap(instance)
+ instance.__init__(space.w_None)
+ return instance
+
+ def descr_init(self, space, w_function):
+ self.w_function = w_function
class FunctionWithFixedCode(Function):
can_change_code = False
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -686,15 +686,17 @@
(e.g. C().f()). The instance is ignored except for its class.""",
__get__ = interp2app(StaticMethod.descr_staticmethod_get),
__new__ = interp2app(StaticMethod.descr_staticmethod__new__.im_func),
+ __init__=interp2app(StaticMethod.descr_init),
__func__= interp_attrproperty_w('w_function', cls=StaticMethod),
)
ClassMethod.typedef = TypeDef(
'classmethod',
- __new__ = interp2app(ClassMethod.descr_classmethod__new__.im_func),
- __get__ = interp2app(ClassMethod.descr_classmethod_get),
- __func__= interp_attrproperty_w('w_function', cls=ClassMethod),
- __doc__ = """classmethod(function) -> class method
+ __new__=interp2app(ClassMethod.descr_classmethod__new__.im_func),
+ __init__=interp2app(ClassMethod.descr_init),
+ __get__=interp2app(ClassMethod.descr_classmethod_get),
+ __func__=interp_attrproperty_w('w_function', cls=ClassMethod),
+ __doc__="""classmethod(function) -> class method
Convert a function to be a class method.
diff --git a/pypy/module/__builtin__/test/test_descriptor.py \
b/pypy/module/__builtin__/test/test_descriptor.py
--- a/pypy/module/__builtin__/test/test_descriptor.py
+++ b/pypy/module/__builtin__/test/test_descriptor.py
@@ -20,6 +20,12 @@
x = Static(1)
assert isinstance(x, Static)
+ class C(Static):
+ def __init__(self, callable):
+ super(C, self).__init__(callable)
+ y = C(1)
+ assert isinstance(y, C)
+
def test_classmethod(self):
class C(object):
def f(cls, stuff):
@@ -41,8 +47,14 @@
x = Classm(1)
assert isinstance(x, Classm)
+ class C(Classm):
+ def __init__(self, callable):
+ super(C, self).__init__(callable)
+ y = C(1)
+ assert isinstance(y, C)
+
def test_property_simple(self):
-
+
class a(object):
def _get(self): return 42
def _set(self, value): raise AttributeError
@@ -98,7 +110,7 @@
assert message.startswith('super(type, obj): obj must be an instance or \
subtype of type')
def test_super_various(self):
-
+
class A(object):
def meth(self, a):
return "A(%r)" % a
@@ -352,10 +364,10 @@
def test_property_subclass_with_init(self):
l = []
-
+
def x(self):
l.append('x')
-
+
class P(property):
def __init__(self):
property.__init__(self, x)
diff --git a/pypy/module/_cffi_backend/cbuffer.py \
b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -2,6 +2,7 @@
from pypy.interpreter.gateway import unwrap_spec, interp2app
from pypy.interpreter.typedef import TypeDef, make_weakref_descr
from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
+from pypy.module._cffi_backend import ctypestruct
from pypy.objspace.std.bufferobject import W_Buffer
from rpython.rlib.buffer import Buffer
@@ -71,7 +72,12 @@
ctype = w_cdata.ctype
if isinstance(ctype, ctypeptr.W_CTypePointer):
if size < 0:
- size = ctype.ctitem.size
+ structobj = w_cdata.get_structobj()
+ if (structobj is not None and
+ isinstance(structobj.ctype, ctypestruct.W_CTypeStructOrUnion)):
+ size = structobj._sizeof()
+ if size < 0:
+ size = ctype.ctitem.size
elif isinstance(ctype, ctypearray.W_CTypeArray):
if size < 0:
size = w_cdata._sizeof()
diff --git a/pypy/module/_cffi_backend/cdataobj.py \
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -329,7 +329,7 @@
def getattr(self, w_attr):
cfield = self.getcfield(w_attr)
with self as ptr:
- w_res = cfield.read(ptr)
+ w_res = cfield.read(ptr, self)
return w_res
def setattr(self, w_attr, w_value):
@@ -432,6 +432,9 @@
lst = ct.cdata_dir()
return space.newlist([space.wrap(s) for s in lst])
+ def get_structobj(self):
+ return None
+
class W_CDataMem(W_CData):
"""This is used only by the results of cffi.cast('int', x)
@@ -453,28 +456,36 @@
by newp(). They create and free their own memory according to an
allocator."""
- # the 'length' is either >= 0 for arrays, or -1 for pointers.
- _attrs_ = ['length']
- _immutable_fields_ = ['length']
+ # the 'allocated_length' is >= 0 for arrays; for var-sized
+ # structures it is the total size in bytes; otherwise it is -1.
+ _attrs_ = ['allocated_length']
+ _immutable_fields_ = ['allocated_length']
def __init__(self, space, cdata, ctype, length=-1):
W_CData.__init__(self, space, cdata, ctype)
- self.length = length
+ self.allocated_length = length
def _repr_extra(self):
return self._repr_extra_owning()
def _sizeof(self):
ctype = self.ctype
- if self.length >= 0:
+ if self.allocated_length >= 0:
from pypy.module._cffi_backend import ctypearray
- assert isinstance(ctype, ctypearray.W_CTypeArray)
- return self.length * ctype.ctitem.size
+ if isinstance(ctype, ctypearray.W_CTypeArray):
+ return self.allocated_length * ctype.ctitem.size
+ else:
+ return self.allocated_length # var-sized struct size
else:
return ctype.size
def get_array_length(self):
- return self.length
+ from pypy.module._cffi_backend import ctypearray
+ assert isinstance(self.ctype, ctypearray.W_CTypeArray)
+ return self.allocated_length
+
+ def get_structobj(self):
+ return self
class W_CDataNewStd(W_CDataNewOwning):
@@ -508,12 +519,19 @@
self.structobj = structobj
def _repr_extra(self):
- return self._repr_extra_owning()
+ return self.structobj._repr_extra_owning()
def _do_getitem(self, ctype, i):
assert i == 0
return self.structobj
+ def get_structobj(self):
+ structobj = self.structobj
+ if isinstance(structobj, W_CDataNewOwning):
+ return structobj
+ else:
+ return None
+
class W_CDataSliced(W_CData):
"""Subclass with an explicit length, for slices."""
diff --git a/pypy/module/_cffi_backend/ctypeptr.py \
b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -211,13 +211,16 @@
# a W_CDataPtrToStruct object which has a strong reference
# to a W_CDataNewOwning that really contains the structure.
#
- if not space.is_w(w_init, space.w_None):
- ctitem.force_lazy_struct()
- if ctitem._with_var_array:
+ varsize_length = -1
+ ctitem.force_lazy_struct()
+ if ctitem._with_var_array:
+ if not space.is_w(w_init, space.w_None):
datasize = ctitem.convert_struct_from_object(
lltype.nullptr(rffi.CCHARP.TO), w_init, datasize)
+ varsize_length = datasize
#
- cdatastruct = allocator.allocate(space, datasize, ctitem)
+ cdatastruct = allocator.allocate(space, datasize, ctitem,
+ length=varsize_length)
ptr = cdatastruct.unsafe_escaping_ptr()
cdata = cdataobj.W_CDataPtrToStructOrUnion(space, ptr,
self, cdatastruct)
diff --git a/pypy/module/_cffi_backend/ctypestruct.py \
b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -210,7 +210,7 @@
return W_CField(self.ctype, offset + self.offset,
self.bitshift, self.bitsize, self.flags | fflags)
- def read(self, cdata):
+ def read(self, cdata, w_cdata):
cdata = rffi.ptradd(cdata, self.offset)
if self.bitshift == self.BS_REGULAR:
return self.ctype.convert_to_object(cdata)
@@ -218,6 +218,14 @@
from pypy.module._cffi_backend import ctypearray
ctype = self.ctype
assert isinstance(ctype, ctypearray.W_CTypeArray)
+ structobj = w_cdata.get_structobj()
+ if structobj is not None:
+ # variable-length array
+ size = structobj.allocated_length - self.offset
+ if size >= 0:
+ arraylen = size // ctype.ctitem.size
+ return cdataobj.W_CDataSliced(ctype.space, cdata, ctype,
+ arraylen)
return cdataobj.W_CData(ctype.space, cdata, ctype.ctptr)
else:
return self.convert_bitfield_to_object(cdata)
diff --git a/pypy/module/_cffi_backend/newtype.py \
b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -353,7 +353,7 @@
if fbitsize < 0:
# not a bitfield: common case
- if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0:
+ if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length<=0:
bs_flag = ctypestruct.W_CField.BS_EMPTY_ARRAY
else:
bs_flag = ctypestruct.W_CField.BS_REGULAR
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py \
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -3161,17 +3161,19 @@
assert d[1][0] == 'y'
assert d[1][1].type is BArray
assert d[1][1].offset == size_of_int()
- assert d[1][1].bitshift == -1
+ assert d[1][1].bitshift == -2
assert d[1][1].bitsize == -1
#
p = newp(new_pointer_type(BStruct))
p.x = 42
assert p.x == 42
- assert typeof(p.y) is BIntP
+ assert typeof(p.y) is BArray
+ assert len(p.y) == 0
assert p.y == cast(BIntP, p) + 1
#
p = newp(new_pointer_type(BStruct), [100])
assert p.x == 100
+ assert len(p.y) == 0
#
# Tests for
# ffi.new("struct_with_var_array *", [field.., [the_array_items..]])
@@ -3186,6 +3188,10 @@
p.y[0] = 200
assert p.y[2] == 0
p.y[2] = 400
+ assert len(p.y) == 3
+ assert len(p[0].y) == 3
+ assert len(buffer(p)) == sizeof(BInt) * 4
+ assert sizeof(p[0]) == sizeof(BInt) * 4
plist.append(p)
for i in range(20):
p = plist[i]
@@ -3193,13 +3199,31 @@
assert p.y[0] == 200
assert p.y[1] == i
assert p.y[2] == 400
- assert list(p.y[0:3]) == [200, i, 400]
+ assert list(p.y) == [200, i, 400]
#
# the following assignment works, as it normally would, for any array field
- p.y = [500, 600]
- assert list(p.y[0:3]) == [500, 600, 400]
+ p.y = [501, 601]
+ assert list(p.y) == [501, 601, 400]
+ p[0].y = [500, 600]
+ assert list(p[0].y) == [500, 600, 400]
+ assert repr(p) == "<cdata 'foo *' owning %d bytes>" % (
+ sizeof(BStruct) + 3 * sizeof(BInt),)
+ assert repr(p[0]) == "<cdata 'foo' owning %d bytes>" % (
+ sizeof(BStruct) + 3 * sizeof(BInt),)
+ assert sizeof(p[0]) == sizeof(BStruct) + 3 * sizeof(BInt)
+ #
+ # from a non-owning pointer, we can't get the length
+ q = cast(new_pointer_type(BStruct), p)
+ assert q.y[0] == 500
+ assert q[0].y[0] == 500
+ py.test.raises(TypeError, len, q.y)
+ py.test.raises(TypeError, len, q[0].y)
+ assert typeof(q.y) is BIntP
+ assert typeof(q[0].y) is BIntP
+ assert sizeof(q[0]) == sizeof(BStruct)
#
# error cases
+ py.test.raises(IndexError, "p.y[4]")
py.test.raises(TypeError, "p.y = cast(BIntP, 0)")
py.test.raises(TypeError, "p.y = 15")
py.test.raises(TypeError, "p.y = None")
@@ -3264,6 +3288,33 @@
assert p.x[5] == 60
assert p.x[6] == 70
+def test_struct_array_not_aligned():
+ # struct a { int x; char y; char z[]; };
+ # ends up of size 8, but 'z' is at offset 5
+ BChar = new_primitive_type("char")
+ BInt = new_primitive_type("int")
+ BCharP = new_pointer_type(BChar)
+ BArray = new_array_type(BCharP, None)
+ BStruct = new_struct_type("foo")
+ complete_struct_or_union(BStruct, [('x', BInt),
+ ('y', BChar),
+ ('z', BArray)])
+ assert sizeof(BStruct) == 2 * size_of_int()
+ def offsetof(BType, fieldname):
+ return typeoffsetof(BType, fieldname)[1]
+ base = offsetof(BStruct, 'z')
+ assert base == size_of_int() + 1
+ #
+ p = newp(new_pointer_type(BStruct), {'z': 3})
+ assert sizeof(p[0]) == base + 3
+ q = newp(new_pointer_type(BStruct), {'z': size_of_int()})
+ assert sizeof(q) == size_of_ptr()
+ assert sizeof(q[0]) == base + size_of_int()
+ assert len(p.z) == 3
+ assert len(p[0].z) == 3
+ assert len(q.z) == size_of_int()
+ assert len(q[0].z) == size_of_int()
+
def test_ass_slice():
BChar = new_primitive_type("char")
BArray = new_array_type(new_pointer_type(BChar), None)
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py \
b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -408,11 +408,14 @@
'test_misdeclared_field_1',
"struct foo_s { int a[6]; };")
assert ffi.sizeof("struct foo_s") == 24 # found by the actual C code
- p = ffi.new("struct foo_s *")
- # lazily build the fields and boom:
- e = raises(ffi.error, getattr, p, "a")
- assert str(e.value).startswith("struct foo_s: wrong size for field 'a' "
- "(cdef says 20, but C compiler says 24)")
+ try:
+ # lazily build the fields and boom:
+ p = ffi.new("struct foo_s *")
+ p.a
+ assert False, "should have raised"
+ except ffi.error as e:
+ assert str(e).startswith("struct foo_s: wrong size for field 'a' "
+ "(cdef says 20, but C compiler says 24)")
def test_open_array_in_struct(self):
ffi, lib = self.prepare(
@@ -420,8 +423,10 @@
'test_open_array_in_struct',
"struct foo_s { int b; int a[]; };")
assert ffi.sizeof("struct foo_s") == 4
- p = ffi.new("struct foo_s *", [5, [10, 20, 30]])
+ p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]])
assert p.a[2] == 30
+ assert ffi.sizeof(p) == ffi.sizeof("void *")
+ assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int")
def test_math_sin_type(self):
ffi, lib = self.prepare(
@@ -954,6 +959,7 @@
"struct foo_s { int x; int a[5][8]; int y; };")
assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int')
s = ffi.new("struct foo_s *")
+ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
assert s.a[4][7] == 0
raises(IndexError, 's.a[4][8]')
@@ -961,6 +967,18 @@
assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]")
+ def test_struct_array_guess_length_3(self):
+ ffi, lib = self.prepare(
+ "struct foo_s { int a[][...]; };",
+ 'test_struct_array_guess_length_3',
+ "struct foo_s { int x; int a[5][7]; int y; };")
+ assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
+ s = ffi.new("struct foo_s *")
+ assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
+ assert s.a[4][6] == 0
+ raises(IndexError, 's.a[4][7]')
+ assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
+
def test_global_var_array_2(self):
ffi, lib = self.prepare(
"int a[...][...];",
diff --git a/pypy/module/array/test/test_array.py \
b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -2,7 +2,18 @@
import pytest
-class BaseArrayTests:
+class AppTestArray(object):
+ spaceconfig = {'usemodules': ['array', 'struct', '_rawffi', 'binascii']}
+
+ def setup_class(cls):
+ cls.w_array = cls.space.appexec([], """():
+ import array
+ return array.array
+ """)
+ cls.w_tempfile = cls.space.wrap(
+ str(pytest.ensuretemp('array').join('tmpfile')))
+ cls.w_maxint = cls.space.wrap(sys.maxint)
+
def test_ctor(self):
assert len(self.array('c')) == 0
assert len(self.array('i')) == 0
@@ -22,8 +33,8 @@
a = self.array('u')
raises(TypeError, a.append, 7)
raises(TypeError, a.append, u'hi')
- a.append(unicode('h'))
- assert a[0] == unicode('h')
+ a.append(u'h')
+ assert a[0] == u'h'
assert type(a[0]) is unicode
assert len(a) == 1
@@ -67,7 +78,7 @@
('H', ( 0, 56783, 65535), int),
('i', (-32768, 30535, 32767), int),
('I', ( 0, 56783, 65535), long),
- ('l', (-2 ** 32 / 2, 34, 2 ** 32 / 2 - 1), int),
+ ('l', (-2 ** 32 // 2, 34, 2 ** 32 // 2 - 1), int),
('L', (0, 3523532, 2 ** 32 - 1), long),
):
a = self.array(tc, ok)
@@ -105,7 +116,7 @@
assert a.tolist() == vals
a = self.array(tc.lower())
- vals = [-1 * (2 ** itembits) / 2, (2 ** itembits) / 2 - 1]
+ vals = [-1 * (2 ** itembits) // 2, (2 ** itembits) // 2 - 1]
a.fromlist(vals)
assert a.tolist() == vals
@@ -137,11 +148,11 @@
for t in inttypes:
a = self.array(t, [1, 2, 3])
b = a.itemsize
- for v in (-2 ** (8 * b) / 2, 2 ** (8 * b) / 2 - 1):
+ for v in (-2 ** (8 * b) // 2, 2 ** (8 * b) // 2 - 1):
a[1] = v
assert a[0] == 1 and a[1] == v and a[2] == 3
- raises(OverflowError, a.append, -2 ** (8 * b) / 2 - 1)
- raises(OverflowError, a.append, 2 ** (8 * b) / 2)
+ raises(OverflowError, a.append, -2 ** (8 * b) // 2 - 1)
+ raises(OverflowError, a.append, 2 ** (8 * b) // 2)
a = self.array(t.upper(), [1, 2, 3])
b = a.itemsize
@@ -175,42 +186,35 @@
raises(ValueError, a.fromstring, '\x00' * (a.itemsize + 1))
raises(ValueError, a.fromstring, '\x00' * (2 * a.itemsize - 1))
raises(ValueError, a.fromstring, '\x00' * (2 * a.itemsize + 1))
- b = self.array(t, '\x00' * a.itemsize * 2)
+ b = self.array(t, b'\x00' * a.itemsize * 2)
assert len(b) == 2 and b[0] == 0 and b[1] == 0
if sys.version_info >= (2, 7, 11):
raises(ValueError, a.fromstring, a)
def test_fromfile(self):
-
- ## class myfile(object):
- ## def __init__(self, c, s):
- ## self.c = c
- ## self.s = s
- ## def read(self,n):
- ## return self.c*min(n,self.s)
def myfile(c, s):
- f = open(self.tempfile, 'w')
+ f = open(self.tempfile, 'wb')
f.write(c * s)
f.close()
- return open(self.tempfile, 'r')
+ return open(self.tempfile, 'rb')
- f = myfile('\x00', 100)
+ f = myfile(b'\x00', 100)
for t in 'bBhHiIlLfd':
a = self.array(t)
a.fromfile(f, 2)
assert len(a) == 2 and a[0] == 0 and a[1] == 0
a = self.array('b')
- a.fromfile(myfile('\x01', 20), 2)
+ a.fromfile(myfile(b'\x01', 20), 2)
assert len(a) == 2 and a[0] == 1 and a[1] == 1
a = self.array('h')
- a.fromfile(myfile('\x01', 20), 2)
+ a.fromfile(myfile(b'\x01', 20), 2)
assert len(a) == 2 and a[0] == 257 and a[1] == 257
for i in (0, 1):
a = self.array('h')
- raises(EOFError, a.fromfile, myfile('\x01', 2 + i), 2)
+ raises(EOFError, a.fromfile, myfile(b'\x01', 2 + i), 2)
assert len(a) == 1 and a[0] == 257
def test_fromlist(self):
@@ -250,12 +254,12 @@
assert repr(a) == "array('b', [1, 2, 1, 2])"
def test_fromunicode(self):
- raises(ValueError, self.array('i').fromunicode, unicode('hi'))
+ raises(ValueError, self.array('i').fromunicode, u'hi')
a = self.array('u')
- a.fromunicode(unicode('hi'))
+ a.fromunicode(u'hi')
assert len(a) == 2 and a[0] == 'h' and a[1] == 'i'
- b = self.array('u', unicode('hi'))
+ b = self.array('u', u'hi')
assert len(b) == 2 and b[0] == 'h' and b[1] == 'i'
def test_sequence(self):
@@ -357,23 +361,6 @@
except ValueError:
assert not ok
- def test_reversingslice_pre26(self):
- import sys
- if sys.version_info >= (2, 6):
- skip('arrays can handle more slice ops than lists in 2.6')
-
- for a in range(-4, 5):
- for b in range(-4, 5):
- for c in [-4, -3, -2, -1, 1, 2, 3, 4]:
- lst = [1, 2, 3]
- arr = self.array('i', lst)
- for vals in ([4, 5], [6], []):
- try:
- lst[a:b:c] = vals
- except ValueError:
- raises(ValueError,
- "arr[a:b:c]=self.array('i', vals)")
-
def test_toxxx(self):
a = self.array('i', [1, 2, 3])
l = a.tolist()
@@ -405,7 +392,7 @@
('BHILfd', (127, 0, 1, 7, 255, 169)),
('hilHILfd', (32760, 30123, 3422, 23244))):
for tc in tcodes:
- values += ((2 ** self.array(tc).itemsize) / 2 - 1, )
+ values += ((2 ** self.array(tc).itemsize) // 2 - 1, )
s = self.array(tc, values).tostring()
a = unpack(tc * len(values), s)
assert a == values
@@ -420,8 +407,7 @@
assert repr(a) == "array('c', 'hi')"
raises(ValueError, self.array('i').tounicode)
- assert self.array('u', unicode('hello')).tounicode() == \
- unicode('hello')
+ assert self.array('u', u'hello').tounicode() == u'hello'
def test_empty_tostring(self):
a = self.array('l')
@@ -493,14 +479,14 @@
def test_compare(self):
class comparable(object):
- def __cmp__(self, other):
- return 0
+ def __eq__(self, other):
+ return True
class incomparable(object):
pass
for v1, v2, tt in (([1, 2, 3], [1, 3, 2], 'bhilBHIL'),
('abc', 'acb', 'c'),
- (unicode('abc'), unicode('acb'), 'u')):
+ (u'abc', u'acb', 'u')):
for t in tt:
a = self.array(t, v1)
b = self.array(t, v1)
@@ -767,16 +753,16 @@
self.height = height
return self
- def _index(self, (x,y)):
+ def _index(self, x, y):
x = min(max(x, 0), self.width-1)
y = min(max(y, 0), self.height-1)
return y * self.width + x
def __getitem__(self, i):
- return array.__getitem__(self, self._index(i))
+ return array.__getitem__(self, self._index(*i))
def __setitem__(self, i, val):
- return array.__setitem__(self, self._index(i), val)
+ return array.__setitem__(self, self._index(*i), val)
img = Image(5, 10, 'B')
for y in range(10):
@@ -844,8 +830,8 @@
assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])"
def test_unicode_outofrange(self):
- a = self.array('u', unicode(r'\x01\u263a\x00\ufeff', 'unicode-escape'))
- b = self.array('u', unicode(r'\x01\u263a\x00\ufeff', 'unicode-escape'))
+ a = self.array('u', u'\x01\u263a\x00\ufeff')
+ b = self.array('u', u'\x01\u263a\x00\ufeff')
b.byteswap()
assert a != b
@@ -853,7 +839,7 @@
import sys
if sys.maxunicode == 0xffff:
skip("test for 32-bit unicodes")
- a = self.array('u', '\xff\xff\xff\xff')
+ a = self.array('u', b'\xff\xff\xff\xff')
assert len(a) == 1
assert repr(a[0]) == "u'\Uffffffff'"
if sys.maxint == 2147483647:
@@ -954,28 +940,6 @@
assert a[0] == u'b'
-class TestCPythonsOwnArray(BaseArrayTests):
- def setup_class(cls):
- import array
- cls.array = array.array
- import struct
- cls.struct = struct
- cls.tempfile = str(pytest.ensuretemp('array').join('tmpfile'))
- cls.maxint = sys.maxint
-
-
-class AppTestArray(BaseArrayTests):
- spaceconfig = {'usemodules': ['array', 'struct', '_rawffi', 'binascii']}
-
- def setup_class(cls):
- cls.w_array = cls.space.appexec([], """():
- import array
- return array.array
- """)
- cls.w_tempfile = cls.space.wrap(
- str(pytest.ensuretemp('array').join('tmpfile')))
- cls.w_maxint = cls.space.wrap(sys.maxint)
-
def test_buffer_info(self):
a = self.array('c', 'Hi!')
bi = a.buffer_info()
diff --git a/pypy/module/array/test/test_array_old.py \
b/pypy/module/array/test/test_array_old.py deleted file mode 100644
--- a/pypy/module/array/test/test_array_old.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# minimal tests. See also lib-python/modified-2.4.1/test/test_array.
-
-import py
-from py.test import raises
-import struct
-
-
-class BaseArrayTests:
- # XXX very incomplete
-
- native_sizes = {'l': struct.calcsize('l')}
-
- def test_attributes(self):
- a = self.array.array('c')
- assert a.typecode == 'c'
- assert a.itemsize == 1
- a = self.array.array('l')
- assert a.typecode == 'l'
- assert a.itemsize == self.native_sizes['l']
-
- def test_imul(self):
- a = self.array.array('i', [12, 34])
- a *= 3
- assert a.tolist() == [12, 34] * 3
-
- def test_unicode(self):
- a = self.array.array('u')
- a.fromunicode(unichr(9999))
- assert len(a) == 1
- assert a.tolist() == [unichr(9999)]
-
- def test_pickle(self):
- import sys
- if sys.version_info < (2, 5):
- py.test.skip("array.array not picklable before python 2.5")
- import pickle
-
- for content in [[56, -12, 34], []]:
- a = self.array.array('i', content)
- a2 = pickle.loads(pickle.dumps(a))
- assert type(a2) is self.array.array
- assert list(a2) == content
-
- def test_init_vs_new(self):
- import sys
- if sys.version_info < (2, 5):
- py.test.skip("array.array constructor changed in 2.5")
- class A(self.array.array):
- def __init__(self, *args, **kwds):
- self.args = args
- self.kwds = kwds
-
- a = A('c', foo='bar')
- assert a.args == ('c',)
- assert a.kwds == {'foo': 'bar'}
- a = A('i', range(10), some=42)
- assert a.args == ('i', range(10))
- assert a.kwds == {'some': 42}
- raises(TypeError, A)
- raises(TypeError, A, 42)
- raises(TypeError, A, 'i', [], [])
- raises(TypeError, self.array.array, 'i', [], foo='bar')
-
-
-class TestCPythonsOwnArray(BaseArrayTests):
-
- def setup_class(cls):
- import array
- cls.array = array
-
-
-## class TestArrayOnTopOfCPython(BaseArrayTests):
-
-## def setup_class(cls):
-## from pypy.tool.lib_pypy import LIB_PYPY
-## if not hasattr(struct, 'pack_into'):
-## py.test.skip("requires CPython >= 2.5")
-## import new
-## path = LIB_PYPY.join('array.py')
-## myarraymodule = new.module('array')
-## execfile(str(path), myarraymodule.__dict__)
-## cls.array = myarraymodule
-
-## def test_unicode(self):
-## py.test.skip("no 'u' type code in CPython's struct module")
-
-## def test_pickle(self):
-## py.test.skip("pickle getting confused by the hack in setup_class()")
-
-
-class AppTestArray(BaseArrayTests):
- spaceconfig = {'usemodules': ['struct', 'array', 'binascii']}
-
- def setup_class(cls):
- """Import the array module and make it available as self.array."""
- cls.w_array = cls.space.getbuiltinmodule('array')
- cls.w_native_sizes = cls.space.wrap(cls.native_sizes)
-
-
-## class AppTestArrayWithRawFFI(AppTestArray):
-## """
-## The same as the base class, but with a space that also includes the
-## _rawffi module. The array module internally uses it in this case.
-## """
-## spaceconfig = dict(usemodules=['struct', '_rawffi'])
-
-## def test_buffer_info(self):
-## a = self.array.array('l', [123, 456])
-## assert a.itemsize == self.native_sizes['l']
-## address, length = a.buffer_info()
-## assert length == 2 # and not 2 * self.native_sizes['l']
-## assert address != 0
-## # should check the address via some unsafe peeking, but it's
-## # not easy on top of py.py
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -79,11 +79,16 @@
CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
hints={'nolength': True}),
use_cache=False)
+CONST_STRINGP = lltype.Ptr(lltype.Array(rffi.CCHARP,
+ hints={'nolength': True}),
+ use_cache=False)
CONST_WSTRING = lltype.Ptr(lltype.Array(lltype.UniChar,
hints={'nolength': True}),
use_cache=False)
assert CONST_STRING is not rffi.CCHARP
assert CONST_STRING == rffi.CCHARP
+assert CONST_STRINGP is not rffi.CCHARPP
+assert CONST_STRINGP == rffi.CCHARPP
assert CONST_WSTRING is not rffi.CWCHARP
assert CONST_WSTRING == rffi.CWCHARP
@@ -1004,6 +1009,8 @@
for i, argtype in enumerate(func.argtypes):
if argtype is CONST_STRING:
arg = 'const char *@'
+ elif argtype is CONST_STRINGP:
+ arg = 'const char **@'
elif argtype is CONST_WSTRING:
arg = 'const wchar_t *@'
else:
diff --git a/pypy/module/cpyext/memoryobject.py b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -1,6 +1,6 @@
from pypy.module.cpyext.api import (cpython_api, Py_buffer, CANNOT_FAIL,
Py_MAX_FMT, Py_MAX_NDIMS, build_type_checkers, Py_ssize_tP)
-from pypy.module.cpyext.pyobject import PyObject, make_ref, incref
+from pypy.module.cpyext.pyobject import PyObject, make_ref, incref, from_ref
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.rarithmetic import widen
from pypy.objspace.std.memoryobject import W_MemoryView
@@ -132,11 +132,22 @@
def PyMemoryView_FromObject(space, w_obj):
return space.call_method(space.builtin, "memoryview", w_obj)
+@cpython_api([lltype.Ptr(Py_buffer)], PyObject)
+def PyMemoryView_FromBuffer(space, view):
+ """Create a memoryview object wrapping the given buffer-info structure view.
+ The memoryview object then owns the buffer, which means you shouldn't
+ try to release it yourself: it will be released on deallocation of the
+ memoryview object."""
+ w_obj = from_ref(space, view.c_obj)
+ if isinstance(w_obj, W_MemoryView):
+ return w_obj
+ return space.call_method(space.builtin, "memoryview", w_obj)
+
@cpython_api([PyObject], PyObject)
def PyMemoryView_GET_BASE(space, w_obj):
# return the obj field of the Py_buffer created by PyMemoryView_GET_BUFFER
# XXX needed for numpy on py3k
- raise NotImplementedError('PyMemoryView_GET_BUFFER')
+ raise NotImplementedError('PyMemoryView_GET_BASE')
@cpython_api([PyObject], lltype.Ptr(Py_buffer), error=CANNOT_FAIL)
def PyMemoryView_GET_BUFFER(space, w_obj):
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -311,7 +311,7 @@
def PyClassMethod_New(space, w_func):
return space.wrap(ClassMethod(w_func))
-@cpython_api([PyObject, lltype.Ptr(PyMethodDef)], PyObject)
+@cpython_api([PyTypeObjectPtr, lltype.Ptr(PyMethodDef)], PyObject)
def PyDescr_NewMethod(space, w_type, method):
return space.wrap(W_PyCMethodObject(space, method, w_type))
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -3,7 +3,7 @@
cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
PyVarObject, Py_buffer, size_t,
Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
- Py_GE, CONST_STRING, FILEP, fwrite)
+ Py_GE, CONST_STRING, CONST_STRINGP, FILEP, fwrite)
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
get_typedescr, _Py_NewReference)
@@ -429,7 +429,7 @@
is active then NULL is returned but PyErr_Occurred() will return false."""
return space.call_function(space.builtin.get('dir'), w_o)
-@cpython_api([PyObject, rffi.CCHARPP, Py_ssize_tP], rffi.INT_real, error=-1)
+@cpython_api([PyObject, CONST_STRINGP, Py_ssize_tP], rffi.INT_real, error=-1)
def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
"""Returns a pointer to a read-only memory location usable as
character-based input. The obj argument must support the single-segment
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -41,14 +41,6 @@
given shape with the given number of bytes per element."""
raise NotImplementedError
-@cpython_api([Py_buffer], PyObject)
-def PyMemoryView_FromBuffer(space, view):
- """Create a memoryview object wrapping the given buffer-info structure view.
- The memoryview object then owns the buffer, which means you shouldn't
- try to release it yourself: it will be released on deallocation of the
- memoryview object."""
- raise NotImplementedError
-
@cpython_api([PyObject, rffi.INT_real, lltype.Char], PyObject)
def PyMemoryView_GetContiguous(space, obj, buffertype, order):
"""Create a memoryview object to a contiguous chunk of memory (in either
diff --git a/pypy/module/cpyext/test/test_abstract.py \
b/pypy/module/cpyext/test/test_abstract.py
--- a/pypy/module/cpyext/test/test_abstract.py
+++ b/pypy/module/cpyext/test/test_abstract.py
@@ -10,7 +10,7 @@
"""
char *ptr;
Py_ssize_t size;
- if (PyObject_AsCharBuffer(args, &ptr, &size) < 0)
+ if (PyObject_AsCharBuffer(args, (const char **)&ptr, &size) < 0)
return NULL;
return PyString_FromStringAndSize(ptr, size);
"""),
diff --git a/pypy/module/cpyext/test/test_bufferobject.py \
b/pypy/module/cpyext/test/test_bufferobject.py
--- a/pypy/module/cpyext/test/test_bufferobject.py
+++ b/pypy/module/cpyext/test/test_bufferobject.py
@@ -25,7 +25,7 @@
"""
char *ptr;
Py_ssize_t size;
- if (PyObject_AsCharBuffer(args, &ptr, &size) < 0)
+ if (PyObject_AsCharBuffer(args, (const char **)&ptr, &size) < 0)
return NULL;
return PyString_FromStringAndSize(ptr, size);
""")
diff --git a/pypy/module/cpyext/test/test_memoryobject.py \
b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -29,6 +29,12 @@
assert w_view.c_len == 5
o = rffi.charp2str(w_view.c_buf)
assert o == 'hello'
+ w_mv = api.PyMemoryView_FromBuffer(w_view)
+ for f in ('format', 'itemsize', 'ndim', 'readonly',
+ 'shape', 'strides', 'suboffsets'):
+ w_f = space.wrap(f)
+ assert space.eq_w(space.getattr(w_mv, w_f),
+ space.getattr(w_memoryview, w_f))
class AppTestBufferProtocol(AppTestCpythonExtensionBase):
def test_buffer_protocol(self):
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -274,7 +274,7 @@
if len(slot_names) == 1:
if not getattr(pto, slot_names[0]):
setattr(pto, slot_names[0], slot_func_helper)
- elif (w_type.getname(space) in ('list', 'tuple') and
+ elif ((w_type is space.w_list or w_type is space.w_tuple) and
slot_names[0] == 'c_tp_as_number'):
# XXX hack - hwo can we generalize this? The problem is method
# names like __mul__ map to more than one slot, and we have no
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1356,15 +1356,15 @@
assert ffi.getctype("e1*") == 'e1 *'
def test_opaque_enum(self):
+ import warnings
ffi = FFI(backend=self.Backend())
ffi.cdef("enum foo;")
- from cffi import __version_info__
- if __version_info__ < (1, 8):
- py.test.skip("re-enable me in version 1.8")
- e = py.test.raises(CDefError, ffi.cast, "enum foo", -1)
- assert str(e.value) == (
- "'enum foo' has no values explicitly defined: refusing to guess "
- "which integer type it is meant to be (unsigned/signed, int/long)")
+ with warnings.catch_warnings(record=True) as log:
+ n = ffi.cast("enum foo", -1)
+ assert int(n) == 0xffffffff
+ assert str(log[0].message) == (
+ "'enum foo' has no values explicitly defined; "
+ "guessing that it is equivalent to 'unsigned int'")
def test_new_ctype(self):
ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
@@ -283,10 +283,20 @@
ffi.cdef("struct foo_s { int x; int a[]; };")
p = ffi.new("struct foo_s *", [100, [200, 300, 400]])
assert p.x == 100
- assert ffi.typeof(p.a) is ffi.typeof("int *") # no length available
+ assert ffi.typeof(p.a) is ffi.typeof("int[]")
+ assert len(p.a) == 3 # length recorded
assert p.a[0] == 200
assert p.a[1] == 300
assert p.a[2] == 400
+ assert list(p.a) == [200, 300, 400]
+ q = ffi.cast("struct foo_s *", p)
+ assert q.x == 100
+ assert ffi.typeof(q.a) is ffi.typeof("int *") # no length recorded
+ py.test.raises(TypeError, len, q.a)
+ assert q.a[0] == 200
+ assert q.a[1] == 300
+ assert q.a[2] == 400
+ py.test.raises(TypeError, list, q.a)
@pytest.mark.skipif("sys.platform != 'win32'")
def test_getwinerror(self):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_verify.py
@@ -562,7 +562,8 @@
"int bar(struct foo_s *f) { return f->a[14]; }\n")
assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
s = ffi.new("struct foo_s *")
- assert ffi.typeof(s.a) is ffi.typeof('int *') # because no length
+ assert ffi.typeof(s.a) is ffi.typeof('int[]') # implicit max length
+ assert len(s.a) == 18 # max length, computed from the size and start offset
s.a[14] = 4242
assert lib.bar(s) == 4242
# with no declared length, out-of-bound accesses are not detected
@@ -592,10 +593,15 @@
ffi.verify("struct foo_s { int x; int a[]; };")
assert ffi.sizeof('struct foo_s') == 1 * ffi.sizeof('int')
s = ffi.new("struct foo_s *", [424242, 4])
- assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int') # the same in C
+ assert ffi.sizeof(ffi.typeof(s[0])) == 1 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
+ # ^^^ explanation: if you write in C: "char x[5];", then
+ # "sizeof(x)" will evaluate to 5. The behavior above is
+ # a generalization of that to "struct foo_s[len(a)=5] x;"
+ # if you could do that in C.
assert s.a[3] == 0
s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
- assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
assert s.a[3] == -10
s = ffi.new("struct foo_s *")
assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
@@ -610,10 +616,10 @@
ffi.verify("struct foo_s { int x, y; int a[]; };")
assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int')
s = ffi.new("struct foo_s *", [424242, 4])
- assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
assert s.a[3] == 0
s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
- assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
assert s.a[3] == -10
s = ffi.new("struct foo_s *")
assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
@@ -1634,10 +1634,19 @@
# struct array_no_length { int x; int a[]; };
p = ffi.new("struct array_no_length *", [100, [200, 300, 400]])
assert p.x == 100
- assert ffi.typeof(p.a) is ffi.typeof("int *") # no length available
+ assert ffi.typeof(p.a) is ffi.typeof("int[]") # length available
assert p.a[0] == 200
assert p.a[1] == 300
assert p.a[2] == 400
+ assert len(p.a) == 3
+ assert list(p.a) == [200, 300, 400]
+ q = ffi.cast("struct array_no_length *", p)
+ assert ffi.typeof(q.a) is ffi.typeof("int *") # no length available
+ assert q.a[0] == 200
+ assert q.a[1] == 300
+ assert q.a[2] == 400
+ py.test.raises(TypeError, len, q.a)
+ py.test.raises(TypeError, list, q.a)
def test_from_buffer(self):
import array
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -400,11 +400,14 @@
pass # ok, fail during compilation already (e.g. C++)
else:
assert ffi.sizeof("struct foo_s") == 24 # found by the actual C code
- p = ffi.new("struct foo_s *")
- # lazily build the fields and boom:
- e = py.test.raises(ffi.error, "p.a")
- assert str(e.value).startswith("struct foo_s: wrong size for field 'a' "
- "(cdef says 20, but C compiler says 24)")
+ try:
+ # lazily build the fields and boom:
+ p = ffi.new("struct foo_s *")
+ p.a
+ assert False, "should have raised"
+ except ffi.error as e:
+ assert str(e).startswith("struct foo_s: wrong size for field 'a' "
+ "(cdef says 20, but C compiler says 24)")
def test_open_array_in_struct():
ffi = FFI()
@@ -412,8 +415,10 @@
verify(ffi, 'test_open_array_in_struct',
"struct foo_s { int b; int a[]; };")
assert ffi.sizeof("struct foo_s") == 4
- p = ffi.new("struct foo_s *", [5, [10, 20, 30]])
+ p = ffi.new("struct foo_s *", [5, [10, 20, 30, 40]])
assert p.a[2] == 30
+ assert ffi.sizeof(p) == ffi.sizeof("void *")
+ assert ffi.sizeof(p[0]) == 5 * ffi.sizeof("int")
def test_math_sin_type():
ffi = FFI()
@@ -999,6 +1004,7 @@
"struct foo_s { int x; int a[5][8]; int y; };")
assert ffi.sizeof('struct foo_s') == 42 * ffi.sizeof('int')
s = ffi.new("struct foo_s *")
+ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int')
assert s.a[4][7] == 0
py.test.raises(IndexError, 's.a[4][8]')
@@ -1013,7 +1019,7 @@
"struct foo_s { int x; int a[5][7]; int y; };")
assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
s = ffi.new("struct foo_s *")
- assert ffi.typeof(s.a) == ffi.typeof("int(*)[7]")
+ assert ffi.typeof(s.a) == ffi.typeof("int[][7]")
assert s.a[4][6] == 0
py.test.raises(IndexError, 's.a[4][7]')
assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py \
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_verify1.py
@@ -547,7 +547,8 @@
"int bar(struct foo_s *f) { return f->a[14]; }\n")
assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
s = ffi.new("struct foo_s *")
- assert ffi.typeof(s.a) is ffi.typeof('int *') # because no length
+ assert ffi.typeof(s.a) is ffi.typeof('int[]') # implicit max length
+ assert len(s.a) == 18 # max length, computed from the size and start offset
s.a[14] = 4242
assert lib.bar(s) == 4242
# with no declared length, out-of-bound accesses are not detected
@@ -577,10 +578,15 @@
ffi.verify("struct foo_s { int x; int a[]; };")
assert ffi.sizeof('struct foo_s') == 1 * ffi.sizeof('int')
s = ffi.new("struct foo_s *", [424242, 4])
- assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int') # the same in C
+ assert ffi.sizeof(ffi.typeof(s[0])) == 1 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
+ # ^^^ explanation: if you write in C: "char x[5];", then
+ # "sizeof(x)" will evaluate to 5. The behavior above is
+ # a generalization of that to "struct foo_s[len(a)=5] x;"
+ # if you could do that in C.
assert s.a[3] == 0
s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
- assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 5 * ffi.sizeof('int')
assert s.a[3] == -10
s = ffi.new("struct foo_s *")
assert ffi.sizeof(s[0]) == 1 * ffi.sizeof('int')
@@ -595,10 +601,10 @@
ffi.verify("struct foo_s { int x, y; int a[]; };")
assert ffi.sizeof('struct foo_s') == 2 * ffi.sizeof('int')
s = ffi.new("struct foo_s *", [424242, 4])
- assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
assert s.a[3] == 0
s = ffi.new("struct foo_s *", [424242, [-40, -30, -20, -10]])
- assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
+ assert ffi.sizeof(s[0]) == 6 * ffi.sizeof('int')
assert s.a[3] == -10
s = ffi.new("struct foo_s *")
assert ffi.sizeof(s[0]) == 2 * ffi.sizeof('int')
diff --git a/pypy/objspace/std/objectobject.py b/pypy/objspace/std/objectobject.py
--- a/pypy/objspace/std/objectobject.py
+++ b/pypy/objspace/std/objectobject.py
@@ -91,11 +91,17 @@
from pypy.objspace.std.typeobject import _precheck_for_new
w_type = _precheck_for_new(space, w_type)
- # don't allow arguments if the default object.__init__() is about
- # to be called
if _excess_args(__args__):
+ w_parent_new, _ = space.lookup_in_type_where(w_type, '__new__')
w_parent_init, _ = space.lookup_in_type_where(w_type, '__init__')
- if w_parent_init is space.w_object:
+ if (w_parent_new is not space.w_object and
+ w_parent_init is not space.w_object):
+ # 2.7: warn about excess arguments when both methods are
+ # overridden
+ space.warn(space.wrap("object() takes no parameters"),
+ space.w_DeprecationWarning, 1)
+ elif (w_parent_new is not space.w_object or
+ w_parent_init is space.w_object):
raise oefmt(space.w_TypeError,
"object() takes no parameters")
if w_type.is_abstract():
@@ -108,11 +114,18 @@
def descr__init__(space, w_obj, __args__):
- # don't allow arguments unless __new__ is overridden
if _excess_args(__args__):
w_type = space.type(w_obj)
+ w_parent_init, _ = space.lookup_in_type_where(w_type, '__init__')
w_parent_new, _ = space.lookup_in_type_where(w_type, '__new__')
- if w_parent_new is space.w_object:
+ if (w_parent_init is not space.w_object and
+ w_parent_new is not space.w_object):
+ # 2.7: warn about excess arguments when both methods are
+ # overridden
+ space.warn(space.wrap("object.__init__() takes no parameters"),
+ space.w_DeprecationWarning, 1)
+ elif (w_parent_init is not space.w_object or
+ w_parent_new is space.w_object):
raise oefmt(space.w_TypeError,
"object.__init__() takes no parameters")
diff --git a/rpython/jit/backend/test/runner_test.py \
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2662,7 +2662,8 @@
""", namespace=locals())
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- deadframe = self.cpu.execute_token(looptoken, 20.25)
+ x = longlong.getfloatstorage(20.25)
+ deadframe = self.cpu.execute_token(looptoken, x)
fail = self.cpu.get_latest_descr(deadframe)
assert fail.identifier == 0
frame = self.cpu.get_ref_value(deadframe, 0)
@@ -2671,7 +2672,8 @@
if not getattr(self.cpu, 'is_llgraph', False):
assert frame == deadframe
deadframe2 = self.cpu.force(frame)
- assert self.cpu.get_float_value(deadframe2, 0) == 22.75
+ x = self.cpu.get_float_value(deadframe2, 0)
+ assert longlong.getrealfloat(x) == 22.75
def test_call_to_c_function(self):
from rpython.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -249,6 +249,7 @@
SEEK_SET = rffi_platform.DefinedConstantInteger('SEEK_SET')
SEEK_CUR = rffi_platform.DefinedConstantInteger('SEEK_CUR')
SEEK_END = rffi_platform.DefinedConstantInteger('SEEK_END')
+ O_NONBLOCK = rffi_platform.DefinedConstantInteger('O_NONBLOCK')
OFF_T_SIZE = rffi_platform.SizeOf('off_t')
HAVE_UTIMES = rffi_platform.Has('utimes')
@@ -2353,3 +2354,42 @@
def cpu_count():
return rffi.cast(lltype.Signed, _cpu_count())
+
+if not _WIN32:
+ eci_status_flags = \
eci.merge(ExternalCompilationInfo(separate_module_sources=[""" + RPY_EXTERN
+ int rpy_get_status_flags(int fd)
+ {
+ int flags;
+ flags = fcntl(fd, F_GETFL, 0);
+ return flags;
+ }
+
+ RPY_EXTERN
+ int rpy_set_status_flags(int fd, int flags)
+ {
+ int res;
+ res = fcntl(fd, F_SETFL, flags);
+ return res;
+ }
+ """], post_include_bits=[
+ "RPY_EXTERN int rpy_get_status_flags(int);\n"
+ "RPY_EXTERN int rpy_set_status_flags(int, int);"]
+ ))
+
+
+ c_get_status_flags = external('rpy_get_status_flags', [rffi.INT],
+ rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO,
+ compilation_info=eci_status_flags)
+ c_set_status_flags = external('rpy_set_status_flags', [rffi.INT, rffi.INT],
+ rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO,
+ compilation_info=eci_status_flags)
+
+ def get_status_flags(fd):
+ res = c_get_status_flags(fd)
+ res = handle_posix_error('get_status_flags', res)
+ return res
+
+ def set_status_flags(fd, flags):
+ res = c_set_status_flags(fd, flags)
+ handle_posix_error('set_status_flags', res)
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -612,3 +612,15 @@
def test_cpu_count():
cc = rposix.cpu_count()
assert cc >= 1
+
+@rposix_requires('set_status_flags')
+def test_set_status_flags():
+ fd1, fd2 = os.pipe()
+ try:
+ flags = rposix.get_status_flags(fd1)
+ assert flags & rposix.O_NONBLOCK == 0
+ rposix.set_status_flags(fd1, flags | rposix.O_NONBLOCK)
+ assert rposix.get_status_flags(fd1) & rposix.O_NONBLOCK != 0
+ finally:
+ os.close(fd1)
+ os.close(fd2)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic