Author: mattip <matti.pi...@gmail.com> Branch: numpy_broadcast Changeset: r83713:000e3811ce8f Date: 2016-04-17 16:36 +0300 http://bitbucket.org/pypy/pypy/changeset/000e3811ce8f/
Log: merge default into branch diff too long, truncating to 2000 out of 8346 lines diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-5.1.0.rst release-5.0.1.rst release-5.0.0.rst release-4.0.1.rst diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-5.1.0.rst whatsnew-5.0.0.rst whatsnew-4.0.1.rst whatsnew-4.0.0.rst diff --git a/pypy/doc/release-5.1.0.rst b/pypy/doc/release-5.1.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-5.1.0.rst @@ -0,0 +1,136 @@ +======== +PyPy 5.1 +======== + +We have released PyPy 5.1, about a month after PyPy 5.0. +We encourage all users of PyPy to update to this version. Apart from the usual +bug fixes, there is an ongoing effort to improve the warmup time and memory +usage of JIT-related metadata, and we now fully support the IBM s390x +architecture. + +You can download the PyPy 5.1 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. + +.. _`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 +.. _`numpy`: https://bitbucket.org/pypy/numpy + +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, Mac OS X 64, Windows 32, OpenBSD, FreeBSD), + + * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, + + * big- and little-endian variants of **PPC64** running Linux, + + * **s960x** running Linux + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://pypyjs.org + +Other Highlights (since 5.0 released in March 2015) +========================================================= + +* New features: + + * A new jit backend for the IBM s390x, which was a large effort over the past + few months. + + * Add better support for PyUnicodeObject in the C-API compatibility layer + + * Support GNU/kFreeBSD Debian ports in vmprof + + * Add __pypy__._promote + + * Make attrgetter a single type for CPython compatibility + +* Bug Fixes + + * Catch exceptions raised in an exit function + + * Fix a corner case in the JIT + + * Fix edge cases in the cpyext refcounting-compatible semantics + + * Try harder to not emit NEON instructions on ARM processors without NEON + support + + * Support glibc < 2.16 on ARM + + * Improve the rpython posix module system interaction function calls + + * Detect a missing class function implementation instead of calling a random + function + + * Check that PyTupleObjects do not contain any NULLs at the + point of conversion to W_TupleObjects + + * In ctypes, fix _anonymous_ fields of instances + + * Fix JIT issue with unpack() on a Trace which contains half-written operations + + * Issues reported with our previous release were resolved_ after reports from users on + our issue tracker at https://bitbucket.org/pypy/pypy/issues or on IRC at + #pypy + +* Numpy: + + * Implemented numpy.where for a single argument + + * Indexing by a numpy scalar now returns a scalar + + * Fix transpose(arg) when arg is a sequence + + * Refactor include file handling, now all numpy ndarray, ufunc, and umath + functions exported from libpypy.so are declared in pypy_numpy.h, which is + included only when building our fork of numpy + +* Performance improvements: + + * Improve str.endswith([tuple]) and str.startswith([tuple]) to allow JITting + + * Merge another round of improvements to the warmup performance + + * Cleanup history rewriting in pyjitpl + + * Remove the forced minor collection that occurs when rewriting the + assembler at the start of the JIT backend + +* Internal refactorings: + + * Use a simpler logger to speed up translation + + * Drop vestiges of Python 2.5 support in testing + +.. _resolved: http://doc.pypy.org/en/latest/whatsnew-5.0.0.html +.. _`blog post`: http://morepypy.blogspot.com/2016/02/c-api-support-update.html + +Please update, and continue to help us make PyPy better. + +Cheers + +The PyPy Team + diff --git a/pypy/doc/whatsnew-5.1.0.rst b/pypy/doc/whatsnew-5.1.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-5.1.0.rst @@ -0,0 +1,62 @@ +========================= +What's new in PyPy 5.1 +========================= + +.. this is a revision shortly after release-5.0 +.. startrev: b238b48f9138 + +.. branch: s390x-backend + +The jit compiler backend implementation for the s390x architecutre. +The backend manages 64-bit values in the literal pool of the assembly instead of loading them as immediates. +It includes a simplification for the operation 'zero_array'. Start and length parameters are bytes instead of size. + +.. branch: remove-py-log + +Replace py.log with something simpler, which should speed up logging + +.. branch: where_1_arg + +Implemented numpy.where for 1 argument (thanks sergem) + +.. branch: fix_indexing_by_numpy_int + +Implement yet another strange numpy indexing compatibility; indexing by a scalar +returns a scalar + +.. branch: fix_transpose_for_list_v3 + +Allow arguments to transpose to be sequences + +.. branch: jit-leaner-frontend + +Improve the tracing speed in the frontend as well as heapcache by using a more compact representation +of traces + +.. branch: win32-lib-name + +.. branch: remove-frame-forcing-in-executioncontext + +.. branch: rposix-for-3 + +Wrap more POSIX functions in `rpython.rlib.rposix`. + +.. branch: cleanup-history-rewriting + +A local clean-up in the JIT front-end. + +.. branch: jit-constptr-2 + +Remove the forced minor collection that occurs when rewriting the +assembler at the start of the JIT backend. This is done by emitting +the ConstPtrs in a separate table, and loading from the table. It +gives improved warm-up time and memory usage, and also removes +annoying special-purpose code for pinned pointers. + +.. branch: fix-jitlog + +.. branch: cleanup-includes + +Remove old uneeded numpy headers, what is left is only for testing. Also +generate pypy_numpy.h which exposes functions to directly use micronumpy +ndarray and ufuncs diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -1,37 +1,7 @@ ========================= -What's new in PyPy 5.0.+ +What's new in PyPy 5.1+ ========================= -.. this is a revision shortly after release-5.0 -.. startrev: b238b48f9138 +.. this is a revision shortly after release-5.1 +.. startrev: 2180e1eaf6f6 -.. branch: s390x-backend - -The jit compiler backend implementation for the s390x architecutre. -The backend manages 64-bit values in the literal pool of the assembly instead of loading them as immediates. -It includes a simplification for the operation 'zero_array'. Start and length parameters are bytes instead of size. - -.. branch: remove-py-log - -Replace py.log with something simpler, which should speed up logging - -.. branch: where_1_arg - -Implemented numpy.where for 1 argument (thanks sergem) - -.. branch: fix_indexing_by_numpy_int - -Implement yet another strange numpy indexing compatibility; indexing by a scalar -returns a scalar - -.. branch: fix_transpose_for_list_v3 - -Allow arguments to transpose to be sequences - -.. branch: jit-leaner-frontend - -Improve the tracing speed in the frontend as well as heapcache by using a more compact representation -of traces - -.. branch: win32-lib-name - diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1029,6 +1029,9 @@ def newlist_int(self, list_i): return self.newlist([self.wrap(i) for i in list_i]) + def newlist_float(self, list_f): + return self.newlist([self.wrap(f) for f in list_f]) + def newlist_hint(self, sizehint): from pypy.objspace.std.listobject import make_empty_list_with_size return make_empty_list_with_size(self, sizehint) diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -277,9 +277,18 @@ raise NotImplementedError def get_traceback(self): - """Get the PyTraceback object, for app-level Python code. + """Calling this marks the PyTraceback as escaped, i.e. it becomes + accessible and inspectable by app-level Python code. For the JIT. + Note that this has no effect if there are already several traceback + frames recorded, because in this case they are already marked as + escaping by executioncontext.leave() being called with + got_exception=True. """ - return self._application_traceback + from pypy.interpreter.pytraceback import PyTraceback + tb = self._application_traceback + if tb is not None and isinstance(tb, PyTraceback): + tb.frame.mark_as_escaped() + return tb def set_traceback(self, traceback): """Set the current traceback.""" diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -74,6 +74,15 @@ finally: frame_vref = self.topframeref self.topframeref = frame.f_backref + if frame.escaped or got_exception: + # if this frame escaped to applevel, we must ensure that also + # f_back does + f_back = frame.f_backref() + if f_back: + f_back.mark_as_escaped() + # force the frame (from the JIT point of view), so that it can + # be accessed also later + frame_vref() jit.virtual_ref_finish(frame_vref, frame) # ________________________________________________________________ diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -65,6 +65,7 @@ last_exception = None f_backref = jit.vref_None + escaped = False # see mark_as_escaped() debugdata = None pycode = None # code object executed by that frame @@ -151,6 +152,15 @@ assert isinstance(cell, Cell) return cell + def mark_as_escaped(self): + """ + Must be called on frames that are exposed to applevel, e.g. by + sys._getframe(). This ensures that the virtualref holding the frame + is properly forced by ec.leave(), and thus the frame will be still + accessible even after the corresponding C stack died. + """ + self.escaped = True + def append_block(self, block): assert block.previous is self.lastblock self.lastblock = block diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -15,9 +15,9 @@ # ____________________________________________________________ -def sorted(lst, cmp=None, key=None, reverse=False): +def sorted(iterable, cmp=None, key=None, reverse=False): "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" - sorted_lst = list(lst) + sorted_lst = list(iterable) sorted_lst.sort(cmp, key, reverse) return sorted_lst diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -172,7 +172,7 @@ def _promote(space, w_obj): """ Promote the first argument of the function and return it. Promote is by value for ints, floats, strs, unicodes (but not subclasses thereof) and by - reference otherwise. + reference otherwise. (Unicodes not supported right now.) This function is experimental!""" from rpython.rlib import jit @@ -181,9 +181,10 @@ elif space.is_w(space.type(w_obj), space.w_float): jit.promote(space.float_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_str): - jit.promote(space.str_w(w_obj)) + jit.promote_string(space.str_w(w_obj)) elif space.is_w(space.type(w_obj), space.w_unicode): - jit.promote(space.unicode_w(w_obj)) + raise OperationError(space.w_TypeError, space.wrap( + "promoting unicode unsupported")) else: jit.promote(w_obj) return w_obj diff --git a/pypy/module/__pypy__/test/test_magic.py b/pypy/module/__pypy__/test/test_magic.py --- a/pypy/module/__pypy__/test/test_magic.py +++ b/pypy/module/__pypy__/test/test_magic.py @@ -53,7 +53,7 @@ assert _promote(1) == 1 assert _promote(1.1) == 1.1 assert _promote("abc") == "abc" - assert _promote(u"abc") == u"abc" + raises(TypeError, _promote, u"abc") l = [] assert _promote(l) is l class A(object): diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -48,6 +48,7 @@ 'from_buffer': 'func.from_buffer', 'string': 'func.string', + 'unpack': 'func.unpack', 'buffer': 'cbuffer.buffer', 'memmove': 'func.memmove', 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 @@ -323,14 +323,18 @@ from pypy.module._cffi_backend import ctypearray ctype = self.ctype if isinstance(ctype, ctypearray.W_CTypeArray): - return ctype.ctitem.unpack_list_of_int_items(self) + length = self.get_array_length() + with self as ptr: + return ctype.ctitem.unpack_list_of_int_items(ptr, length) return None def unpackiterable_float(self, space): from pypy.module._cffi_backend import ctypearray ctype = self.ctype if isinstance(ctype, ctypearray.W_CTypeArray): - return ctype.ctitem.unpack_list_of_float_items(self) + length = self.get_array_length() + with self as ptr: + return ctype.ctitem.unpack_list_of_float_items(ptr, length) return None @specialize.argtype(1) @@ -367,6 +371,25 @@ with self as ptr: return W_CDataGCP(self.space, ptr, self.ctype, self, w_destructor) + def unpack(self, length): + from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray + space = self.space + if not self.ctype.is_nonfunc_pointer_or_array: + raise oefmt(space.w_TypeError, + "expected a pointer or array, got '%s'", + self.ctype.name) + if length < 0: + raise oefmt(space.w_ValueError, "'length' cannot be negative") + ctype = self.ctype + assert isinstance(ctype, W_CTypePtrOrArray) + with self as ptr: + if not ptr: + raise oefmt(space.w_RuntimeError, + "cannot use unpack() on %s", + space.str_w(self.repr())) + w_result = ctype.ctitem.unpack_ptr(ctype, ptr, length) + return w_result + class W_CDataMem(W_CData): """This is used only by the results of cffi.cast('int', x) diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -7,11 +7,12 @@ from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rarithmetic import ovfcheck from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray +from pypy.module._cffi_backend import ctypeprim class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -49,10 +49,10 @@ def is_unichar_ptr_or_array(self): return False - def unpack_list_of_int_items(self, cdata): + def unpack_list_of_int_items(self, ptr, length): return None - def unpack_list_of_float_items(self, cdata): + def unpack_list_of_float_items(self, ptr, length): return None def pack_list_of_items(self, cdata, w_ob): @@ -127,6 +127,21 @@ raise oefmt(space.w_TypeError, "string(): unexpected cdata '%s' argument", self.name) + def unpack_ptr(self, w_ctypeptr, ptr, length): + # generic implementation, when the type of items is not known to + # be one for which a fast-case exists + space = self.space + itemsize = self.size + if itemsize < 0: + raise oefmt(space.w_ValueError, + "'%s' points to items of unknown size", + w_ctypeptr.name) + result_w = [None] * length + for i in range(length): + result_w[i] = self.convert_to_object(ptr) + ptr = rffi.ptradd(ptr, itemsize) + return space.newlist(result_w) + def add(self, cdata, i): space = self.space raise oefmt(space.w_TypeError, "cannot add a cdata '%s' and a number", diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -87,6 +87,13 @@ return self.space.wrap(s) return W_CType.string(self, cdataobj, maxlen) + def unpack_ptr(self, w_ctypeptr, ptr, length): + result = self.unpack_list_of_int_items(ptr, length) + if result is not None: + return self.space.newlist_int(result) + return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length) + + class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive): _attrs_ = [] is_primitive_integer = True @@ -125,6 +132,10 @@ value = self._convert_to_char(w_ob) cdata[0] = value + def unpack_ptr(self, w_ctypeptr, ptr, length): + s = rffi.charpsize2str(ptr, length) + return self.space.wrapbytes(s) + # XXX explicitly use an integer type instead of lltype.UniChar here, # because for now the latter is defined as unsigned by RPython (even @@ -171,6 +182,10 @@ value = self._convert_to_unichar(w_ob) rffi.cast(rffi.CWCHARP, cdata)[0] = value + def unpack_ptr(self, w_ctypeptr, ptr, length): + u = rffi.wcharpsize2unicode(rffi.cast(rffi.CWCHARP, ptr), length) + return self.space.wrap(u) + class W_CTypePrimitiveSigned(W_CTypePrimitive): _attrs_ = ['value_fits_long', 'value_smaller_than_long'] @@ -221,19 +236,16 @@ def write_raw_integer_data(self, w_cdata, value): w_cdata.write_raw_signed_data(value) - def unpack_list_of_int_items(self, w_cdata): + def unpack_list_of_int_items(self, ptr, length): if self.size == rffi.sizeof(rffi.LONG): from rpython.rlib.rrawarray import populate_list_from_raw_array res = [] - length = w_cdata.get_array_length() - with w_cdata as ptr: - buf = rffi.cast(rffi.LONGP, ptr) - populate_list_from_raw_array(res, buf, length) + buf = rffi.cast(rffi.LONGP, ptr) + populate_list_from_raw_array(res, buf, length) return res elif self.value_smaller_than_long: - res = [0] * w_cdata.get_array_length() - with w_cdata as ptr: - misc.unpack_list_from_raw_array(res, ptr, self.size) + res = [0] * length + misc.unpack_list_from_raw_array(res, ptr, self.size) return res return None @@ -313,11 +325,10 @@ def write_raw_integer_data(self, w_cdata, value): w_cdata.write_raw_unsigned_data(value) - def unpack_list_of_int_items(self, w_cdata): + def unpack_list_of_int_items(self, ptr, length): if self.value_fits_long: - res = [0] * w_cdata.get_array_length() - with w_cdata as ptr: - misc.unpack_unsigned_list_from_raw_array(res, ptr, self.size) + res = [0] * length + misc.unpack_unsigned_list_from_raw_array(res, ptr, self.size) return res return None @@ -391,19 +402,16 @@ value = space.float_w(space.float(w_ob)) misc.write_raw_float_data(cdata, value, self.size) - def unpack_list_of_float_items(self, w_cdata): + def unpack_list_of_float_items(self, ptr, length): if self.size == rffi.sizeof(rffi.DOUBLE): from rpython.rlib.rrawarray import populate_list_from_raw_array res = [] - length = w_cdata.get_array_length() - with w_cdata as ptr: - buf = rffi.cast(rffi.DOUBLEP, ptr) - populate_list_from_raw_array(res, buf, length) + buf = rffi.cast(rffi.DOUBLEP, ptr) + populate_list_from_raw_array(res, buf, length) return res elif self.size == rffi.sizeof(rffi.FLOAT): - res = [0.0] * w_cdata.get_array_length() - with w_cdata as ptr: - misc.unpack_cfloat_list_from_raw_array(res, ptr) + res = [0.0] * length + misc.unpack_cfloat_list_from_raw_array(res, ptr) return res return None @@ -421,6 +429,12 @@ return True return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob) + def unpack_ptr(self, w_ctypeptr, ptr, length): + result = self.unpack_list_of_float_items(ptr, length) + if result is not None: + return self.space.newlist_float(result) + return W_CType.unpack_ptr(self, w_ctypeptr, ptr, length) + class W_CTypePrimitiveLongDouble(W_CTypePrimitiveFloat): _attrs_ = [] diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py --- a/pypy/module/_cffi_backend/ffi_obj.py +++ b/pypy/module/_cffi_backend/ffi_obj.py @@ -542,6 +542,25 @@ return w_cdata.ctype.string(w_cdata, maxlen) + @unwrap_spec(w_cdata=W_CData, length=int) + def descr_unpack(self, w_cdata, length): + """Unpack an array of C data of the given length, +returning a Python string/unicode/list. + +If 'cdata' is a pointer to 'char', returns a byte string. +It does not stop at the first null. This is equivalent to: +ffi.buffer(cdata, length)[:] + +If 'cdata' is a pointer to 'wchar_t', returns a unicode string. +'length' is measured in wchar_t's; it is not the size in bytes. + +If 'cdata' is a pointer to anything else, returns a list of +'length' items. This is a faster equivalent to: +[cdata[i] for i in range(length)]""" + # + return w_cdata.unpack(length) + + def descr_sizeof(self, w_arg): """\ Return the size in bytes of the argument. @@ -739,4 +758,5 @@ sizeof = interp2app(W_FFIObject.descr_sizeof), string = interp2app(W_FFIObject.descr_string), typeof = interp2app(W_FFIObject.descr_typeof), + unpack = interp2app(W_FFIObject.descr_unpack), **_extras) diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -78,6 +78,12 @@ # ____________________________________________________________ +@unwrap_spec(w_cdata=cdataobj.W_CData, length=int) +def unpack(space, w_cdata, length): + return w_cdata.unpack(length) + +# ____________________________________________________________ + def _get_types(space): return space.newtuple([space.gettypefor(cdataobj.W_CData), space.gettypefor(ctypeobj.W_CType)]) 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 @@ -3514,3 +3514,72 @@ d = {} _get_common_types(d) assert d['bool'] == '_Bool' + +def test_unpack(): + BChar = new_primitive_type("char") + BArray = new_array_type(new_pointer_type(BChar), 10) # char[10] + p = newp(BArray, b"abc\x00def") + p0 = p + assert unpack(p, 10) == b"abc\x00def\x00\x00\x00" + assert unpack(p+1, 5) == b"bc\x00de" + BWChar = new_primitive_type("wchar_t") + BArray = new_array_type(new_pointer_type(BWChar), 10) # wchar_t[10] + p = newp(BArray, u"abc\x00def") + assert unpack(p, 10) == u"abc\x00def\x00\x00\x00" + + for typename, samples in [ + ("uint8_t", [0, 2**8-1]), + ("uint16_t", [0, 2**16-1]), + ("uint32_t", [0, 2**32-1]), + ("uint64_t", [0, 2**64-1]), + ("int8_t", [-2**7, 2**7-1]), + ("int16_t", [-2**15, 2**15-1]), + ("int32_t", [-2**31, 2**31-1]), + ("int64_t", [-2**63, 2**63-1]), + ("_Bool", [0, 1]), + ("float", [0.0, 10.5]), + ("double", [12.34, 56.78]), + ]: + BItem = new_primitive_type(typename) + BArray = new_array_type(new_pointer_type(BItem), 10) + p = newp(BArray, samples) + result = unpack(p, len(samples)) + assert result == samples + for i in range(len(samples)): + assert result[i] == p[i] and type(result[i]) is type(p[i]) + # + BInt = new_primitive_type("int") + py.test.raises(TypeError, unpack, p) + py.test.raises(TypeError, unpack, b"foobar", 6) + py.test.raises(TypeError, unpack, cast(BInt, 42), 1) + # + BPtr = new_pointer_type(BInt) + random_ptr = cast(BPtr, -424344) + other_ptr = cast(BPtr, 54321) + BArray = new_array_type(new_pointer_type(BPtr), None) + lst = unpack(newp(BArray, [random_ptr, other_ptr]), 2) + assert lst == [random_ptr, other_ptr] + # + BFunc = new_function_type((BInt, BInt), BInt, False) + BFuncPtr = new_pointer_type(BFunc) + lst = unpack(newp(new_array_type(BFuncPtr, None), 2), 2) + assert len(lst) == 2 + assert not lst[0] and not lst[1] + assert typeof(lst[0]) is BFunc + # + BStruct = new_struct_type("foo") + BStructPtr = new_pointer_type(BStruct) + e = py.test.raises(ValueError, unpack, cast(BStructPtr, 42), 5) + assert str(e.value) == "'foo *' points to items of unknown size" + complete_struct_or_union(BStruct, [('a1', BInt, -1), + ('a2', BInt, -1)]) + array_of_structs = newp(new_array_type(BStructPtr, None), [[4,5], [6,7]]) + lst = unpack(array_of_structs, 2) + assert typeof(lst[0]) is BStruct + assert lst[0].a1 == 4 and lst[1].a2 == 7 + # + py.test.raises(RuntimeError, unpack, cast(new_pointer_type(BChar), 0), 0) + py.test.raises(RuntimeError, unpack, cast(new_pointer_type(BChar), 0), 10) + # + py.test.raises(ValueError, unpack, p0, -1) + py.test.raises(ValueError, unpack, p, -1) diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py --- a/pypy/module/_cffi_backend/test/test_ffi_obj.py +++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py @@ -476,3 +476,11 @@ for i in range(5): raises(ValueError, ffi.init_once, do_init, "tag") assert seen == [1] * (i + 1) + + def test_unpack(self): + import _cffi_backend as _cffi1_backend + ffi = _cffi1_backend.FFI() + p = ffi.new("char[]", b"abc\x00def") + assert ffi.unpack(p+1, 7) == b"bc\x00def\x00" + p = ffi.new("int[]", [-123456789]) + assert ffi.unpack(p, 1) == [-123456789] diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py --- a/pypy/module/_file/test/test_file.py +++ b/pypy/module/_file/test/test_file.py @@ -285,6 +285,8 @@ from posix import openpty, fdopen, write, close except ImportError: skip('no openpty on this platform') + if 'gnukfreebsd' in sys.platform: + skip('close() hangs forever on kFreeBSD') read_fd, write_fd = openpty() write(write_fd, 'Abc\n') close(write_fd) diff --git a/pypy/module/_multiprocessing/test/test_win32.py b/pypy/module/_multiprocessing/test/test_win32.py --- a/pypy/module/_multiprocessing/test/test_win32.py +++ b/pypy/module/_multiprocessing/test/test_win32.py @@ -2,7 +2,8 @@ import sys class AppTestWin32: - spaceconfig = dict(usemodules=('_multiprocessing',)) + spaceconfig = dict(usemodules=('_multiprocessing', + 'signal', '_rawffi', 'binascii')) def setup_class(cls): if sys.platform != "win32": diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -733,6 +733,7 @@ try: while 1: count += cli.send(b'foobar' * 70) + assert count < 100000 except timeout: pass t.recv(count) diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -14,7 +14,7 @@ tmpfile2 = open(self.tmpfilename2, 'wb') tmpfileno2 = tmpfile2.fileno() - import struct, sys + import struct, sys, gc WORD = struct.calcsize('l') @@ -46,6 +46,8 @@ return count import _vmprof + gc.collect() # try to make the weakref list deterministic + gc.collect() # by freeing all dead code objects _vmprof.enable(tmpfileno, 0.01) _vmprof.disable() s = open(self.tmpfilename, 'rb').read() @@ -57,6 +59,8 @@ pass """ in d + gc.collect() + gc.collect() _vmprof.enable(tmpfileno2, 0.01) exec """def foo2(): diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -556,18 +556,18 @@ self.w_class = None self.method = method - if self.canoverflow: - assert self.bytes <= rffi.sizeof(rffi.ULONG) - if self.bytes == rffi.sizeof(rffi.ULONG) and not signed and \ - self.unwrap == 'int_w': - # Treat this type as a ULONG - self.unwrap = 'bigint_w' - self.canoverflow = False - def _freeze_(self): # hint for the annotator: track individual constant instances return True +if rffi.sizeof(rffi.UINT) == rffi.sizeof(rffi.ULONG): + # 32 bits: UINT can't safely overflow into a C long (rpython int) + # via int_w, handle it like ULONG below + _UINTTypeCode = \ + TypeCode(rffi.UINT, 'bigint_w') +else: + _UINTTypeCode = \ + TypeCode(rffi.UINT, 'int_w', True) types = { 'c': TypeCode(lltype.Char, 'str_w', method=''), 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''), @@ -576,7 +576,7 @@ 'h': TypeCode(rffi.SHORT, 'int_w', True, True), 'H': TypeCode(rffi.USHORT, 'int_w', True), 'i': TypeCode(rffi.INT, 'int_w', True, True), - 'I': TypeCode(rffi.UINT, 'int_w', True), + 'I': _UINTTypeCode, 'l': TypeCode(rffi.LONG, 'int_w', True, True), 'L': TypeCode(rffi.ULONG, 'bigint_w'), # Overflow handled by # rbigint.touint() which 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 @@ -99,12 +99,13 @@ for tc in 'BHIL': a = self.array(tc) - vals = [0, 2 ** a.itemsize - 1] + itembits = a.itemsize * 8 + vals = [0, 2 ** itembits - 1] a.fromlist(vals) assert a.tolist() == vals a = self.array(tc.lower()) - vals = [-1 * (2 ** a.itemsize) / 2, (2 ** a.itemsize) / 2 - 1] + vals = [-1 * (2 ** itembits) / 2, (2 ** itembits) / 2 - 1] a.fromlist(vals) assert a.tolist() == vals 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 @@ -144,26 +144,14 @@ target.chmod(0444) # make the file read-only, to make sure that nobody # edits it by mistake -def copy_header_files(dstdir, copy_numpy_headers): +def copy_header_files(dstdir): # XXX: 20 lines of code to recursively copy a directory, really?? assert dstdir.check(dir=True) headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl') - for name in ("pypy_decl.h", "pypy_macros.h", "pypy_structmember_decl.h"): + for name in ["pypy_macros.h"] + FUNCTIONS_BY_HEADER.keys(): headers.append(udir.join(name)) _copy_header_files(headers, dstdir) - if copy_numpy_headers: - try: - dstdir.mkdir('numpy') - except py.error.EEXIST: - pass - numpy_dstdir = dstdir / 'numpy' - - numpy_include_dir = include_dir / 'numpy' - numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl') - _copy_header_files(numpy_headers, numpy_dstdir) - - class NotSpecified(object): pass _NOT_SPECIFIED = NotSpecified() @@ -231,7 +219,8 @@ wrapper.c_name = cpyext_namespace.uniquename(self.c_name) return wrapper -def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header='pypy_decl.h', +DEFAULT_HEADER = 'pypy_decl.h' +def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER, gil=None, result_borrowed=False): """ Declares a function to be exported. @@ -265,6 +254,8 @@ func_name = func.func_name if header is not None: c_name = None + assert func_name not in FUNCTIONS, ( + "%s already registered" % func_name) else: c_name = func_name api_function = ApiFunction(argtypes, restype, func, error, @@ -272,10 +263,6 @@ result_borrowed=result_borrowed) func.api_func = api_function - if header is not None: - assert func_name not in FUNCTIONS, ( - "%s already registered" % func_name) - if error is _NOT_SPECIFIED: raise ValueError("function %s has no return value for exceptions" % func) @@ -363,7 +350,8 @@ unwrapper_catch = make_unwrapper(True) unwrapper_raise = make_unwrapper(False) if header is not None: - FUNCTIONS[func_name] = api_function + if header == DEFAULT_HEADER: + FUNCTIONS[func_name] = api_function FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] = api_function INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests return unwrapper_raise # used in 'normal' RPython code. @@ -792,10 +780,11 @@ # Structure declaration code members = [] structindex = {} - for name, func in sorted(FUNCTIONS.iteritems()): - restype, args = c_function_signature(db, func) - members.append('%s (*%s)(%s);' % (restype, name, args)) - structindex[name] = len(structindex) + for header, header_functions in FUNCTIONS_BY_HEADER.iteritems(): + for name, func in header_functions.iteritems(): + restype, args = c_function_signature(db, func) + members.append('%s (*%s)(%s);' % (restype, name, args)) + structindex[name] = len(structindex) structmembers = '\n'.join(members) struct_declaration_code = """\ struct PyPyAPI { @@ -804,7 +793,8 @@ RPY_EXTERN struct PyPyAPI* pypyAPI = &_pypyAPI; """ % dict(members=structmembers) - functions = generate_decls_and_callbacks(db, export_symbols) + functions = generate_decls_and_callbacks(db, export_symbols, + prefix='cpyexttest') global_objects = [] for name, (typ, expr) in GLOBALS.iteritems(): @@ -821,6 +811,11 @@ prologue = ("#include <Python.h>\n" "#include <structmember.h>\n" "#include <src/thread.c>\n") + if use_micronumpy: + prologue = ("#include <Python.h>\n" + "#include <structmember.h>\n" + "#include <pypy_numpy.h>\n" + "#include <src/thread.c>\n") code = (prologue + struct_declaration_code + global_code + @@ -896,13 +891,19 @@ pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') # implement structure initialization code - for name, func in FUNCTIONS.iteritems(): - if name.startswith('cpyext_'): # XXX hack - continue - pypyAPI[structindex[name]] = ctypes.cast( - ll2ctypes.lltype2ctypes(func.get_llhelper(space)), - ctypes.c_void_p) - + #for name, func in FUNCTIONS.iteritems(): + # if name.startswith('cpyext_'): # XXX hack + # continue + # pypyAPI[structindex[name]] = ctypes.cast( + # ll2ctypes.lltype2ctypes(func.get_llhelper(space)), + # ctypes.c_void_p) + for header, header_functions in FUNCTIONS_BY_HEADER.iteritems(): + for name, func in header_functions.iteritems(): + if name.startswith('cpyext_'): # XXX hack + continue + pypyAPI[structindex[name]] = ctypes.cast( + ll2ctypes.lltype2ctypes(func.get_llhelper(space)), + ctypes.c_void_p) setup_va_functions(eci) setup_init_functions(eci, translating=False) @@ -995,18 +996,12 @@ pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros)) -def generate_decls_and_callbacks(db, export_symbols, api_struct=True): +def generate_decls_and_callbacks(db, export_symbols, api_struct=True, prefix=''): "NOT_RPYTHON" # implement function callbacks and generate function decls functions = [] decls = {} pypy_decls = decls['pypy_decl.h'] = [] - pypy_decls.append("#ifndef _PYPY_PYPY_DECL_H\n") - pypy_decls.append("#define _PYPY_PYPY_DECL_H\n") - pypy_decls.append("#ifndef PYPY_STANDALONE\n") - pypy_decls.append("#ifdef __cplusplus") - pypy_decls.append("extern \"C\" {") - pypy_decls.append("#endif\n") pypy_decls.append('#define Signed long /* xxx temporary fix */\n') pypy_decls.append('#define Unsigned unsigned long /* xxx temporary fix */\n') @@ -1016,19 +1011,28 @@ for header_name, header_functions in FUNCTIONS_BY_HEADER.iteritems(): if header_name not in decls: header = decls[header_name] = [] + header.append('#define Signed long /* xxx temporary fix */\n') + header.append('#define Unsigned unsigned long /* xxx temporary fix */\n') else: header = decls[header_name] for name, func in sorted(header_functions.iteritems()): + if header == DEFAULT_HEADER: + _name = name + else: + # this name is not included in pypy_macros.h + _name = mangle_name(prefix, name) + assert _name is not None, 'error converting %s' % name + header.append("#define %s %s" % (name, _name)) restype, args = c_function_signature(db, func) - header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, name, args)) + header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, _name, args)) if api_struct: callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) if func.restype is lltype.Void: - body = "{ _pypyAPI.%s(%s); }" % (name, callargs) + body = "{ _pypyAPI.%s(%s); }" % (_name, callargs) else: - body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) + body = "{ return _pypyAPI.%s(%s); }" % (_name, callargs) functions.append('%s %s(%s)\n%s' % (restype, name, args, body)) for name in VA_TP_LIST: name_no_star = process_va_name(name) @@ -1045,13 +1049,10 @@ typ = 'PyObject*' pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name)) - pypy_decls.append('#undef Signed /* xxx temporary fix */\n') - pypy_decls.append('#undef Unsigned /* xxx temporary fix */\n') - pypy_decls.append("#ifdef __cplusplus") - pypy_decls.append("}") - pypy_decls.append("#endif") - pypy_decls.append("#endif /*PYPY_STANDALONE*/\n") - pypy_decls.append("#endif /*_PYPY_PYPY_DECL_H*/\n") + for header_name in FUNCTIONS_BY_HEADER.keys(): + header = decls[header_name] + header.append('#undef Signed /* xxx temporary fix */\n') + header.append('#undef Unsigned /* xxx temporary fix */\n') for header_name, header_decls in decls.iteritems(): decl_h = udir.join(header_name) @@ -1158,7 +1159,8 @@ generate_macros(export_symbols, prefix='PyPy') - functions = generate_decls_and_callbacks(db, [], api_struct=False) + functions = generate_decls_and_callbacks(db, [], api_struct=False, + prefix='PyPy') code = "#include <Python.h>\n" + "\n".join(functions) eci = build_eci(False, export_symbols, code) @@ -1200,14 +1202,16 @@ PyObjectP, 'pypy_static_pyobjs', eci2, c_type='PyObject **', getter_only=True, declare_as_extern=False) - for name, func in FUNCTIONS.iteritems(): - newname = mangle_name('PyPy', name) or name - deco = entrypoint_lowlevel("cpyext", func.argtypes, newname, relax=True) - deco(func.get_wrapper(space)) + for header, header_functions in FUNCTIONS_BY_HEADER.iteritems(): + for name, func in header_functions.iteritems(): + newname = mangle_name('PyPy', name) or name + deco = entrypoint_lowlevel("cpyext", func.argtypes, newname, + relax=True) + deco(func.get_wrapper(space)) setup_init_functions(eci, translating=True) trunk_include = pypydir.dirpath() / 'include' - copy_header_files(trunk_include, use_micronumpy) + copy_header_files(trunk_include) def init_static_data_translated(space): builder = space.fromcache(StaticObjectBuilder) diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -132,7 +132,18 @@ /* Missing definitions */ #include "missing.h" -#include <pypy_decl.h> +/* The declarations of most API functions are generated in a separate file */ +/* Don't include them while building PyPy, RPython also generated signatures + * which are similar but not identical. */ +#ifndef PYPY_STANDALONE +#ifdef __cplusplus +extern "C" { +#endif + #include <pypy_decl.h> +#ifdef __cplusplus +} +#endif +#endif /* PYPY_STANDALONE */ /* Define macros for inline documentation. */ #define PyDoc_VAR(name) static char name[] diff --git a/pypy/module/cpyext/include/numpy/__multiarray_api.h b/pypy/module/cpyext/include/numpy/__multiarray_api.h deleted file mode 100644 --- a/pypy/module/cpyext/include/numpy/__multiarray_api.h +++ /dev/null @@ -1,10 +0,0 @@ - - -typedef struct { - PyObject_HEAD - npy_bool obval; -} PyBoolScalarObject; - -#define import_array() -#define PyArray_New _PyArray_New - diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h --- a/pypy/module/cpyext/include/numpy/arrayobject.h +++ b/pypy/module/cpyext/include/numpy/arrayobject.h @@ -1,8 +1,6 @@ -/* NDArray object interface - S. H. Muller, 2013/07/26 - * It will be copied by numpy/core/setup.py by install_data to - * site-packages/numpy/core/includes/numpy -*/ +/* NDArray object interface - S. H. Muller, 2013/07/26 */ +/* For testing ndarrayobject only */ #ifndef Py_NDARRAYOBJECT_H #define Py_NDARRAYOBJECT_H @@ -10,13 +8,8 @@ extern "C" { #endif -#include "old_defines.h" #include "npy_common.h" -#include "__multiarray_api.h" - -#define NPY_UNUSED(x) x -#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) -#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) +#include "ndarraytypes.h" /* fake PyArrayObject so that code that doesn't do direct field access works */ #define PyArrayObject PyObject @@ -24,208 +17,20 @@ PyAPI_DATA(PyTypeObject) PyArray_Type; +#define PyArray_SimpleNew _PyArray_SimpleNew +#define PyArray_ZEROS _PyArray_ZEROS +#define PyArray_CopyInto _PyArray_CopyInto +#define PyArray_FILLWBYTE _PyArray_FILLWBYTE #define NPY_MAXDIMS 32 -#ifndef NDARRAYTYPES_H -typedef struct { - npy_intp *ptr; - int len; -} PyArray_Dims; - -/* data types copied from numpy/ndarraytypes.h - * keep numbers in sync with micronumpy.interp_dtype.DTypeCache - */ -enum NPY_TYPES { NPY_BOOL=0, - NPY_BYTE, NPY_UBYTE, - NPY_SHORT, NPY_USHORT, - NPY_INT, NPY_UINT, - NPY_LONG, NPY_ULONG, - NPY_LONGLONG, NPY_ULONGLONG, - NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, - NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE, - NPY_OBJECT=17, - NPY_STRING, NPY_UNICODE, - NPY_VOID, - /* - * New 1.6 types appended, may be integrated - * into the above in 2.0. - */ - NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF, - - NPY_NTYPES, - NPY_NOTYPE, - NPY_CHAR, /* special flag */ - NPY_USERDEF=256, /* leave room for characters */ - - /* The number of types not including the new 1.6 types */ - NPY_NTYPES_ABI_COMPATIBLE=21 -}; - -#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) -#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \ - ((type) <= NPY_ULONGLONG)) -#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \ - ((type) <= NPY_LONGDOUBLE)) || \ - ((type) == NPY_HALF)) -#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \ - ((type) <= NPY_CLONGDOUBLE)) - -#define PyArray_ISBOOL(arr) (PyTypeNum_ISBOOL(PyArray_TYPE(arr))) -#define PyArray_ISINTEGER(arr) (PyTypeNum_ISINTEGER(PyArray_TYPE(arr))) -#define PyArray_ISFLOAT(arr) (PyTypeNum_ISFLOAT(PyArray_TYPE(arr))) -#define PyArray_ISCOMPLEX(arr) (PyTypeNum_ISCOMPLEX(PyArray_TYPE(arr))) - - -/* flags */ -#define NPY_ARRAY_C_CONTIGUOUS 0x0001 -#define NPY_ARRAY_F_CONTIGUOUS 0x0002 -#define NPY_ARRAY_OWNDATA 0x0004 -#define NPY_ARRAY_FORCECAST 0x0010 -#define NPY_ARRAY_ENSURECOPY 0x0020 -#define NPY_ARRAY_ENSUREARRAY 0x0040 -#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 -#define NPY_ARRAY_ALIGNED 0x0100 -#define NPY_ARRAY_NOTSWAPPED 0x0200 -#define NPY_ARRAY_WRITEABLE 0x0400 -#define NPY_ARRAY_UPDATEIFCOPY 0x1000 - -#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ - NPY_ARRAY_WRITEABLE) -#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ - NPY_ARRAY_WRITEABLE | \ - NPY_ARRAY_NOTSWAPPED) -#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ - NPY_ARRAY_BEHAVED) -#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ - NPY_ARRAY_ALIGNED) -#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ - NPY_ARRAY_BEHAVED) -#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ - NPY_ARRAY_ALIGNED) -#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) -#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) -#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) -#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ - NPY_ARRAY_UPDATEIFCOPY) -#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) -#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) -#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ - NPY_ARRAY_UPDATEIFCOPY) - -#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ - NPY_ARRAY_F_CONTIGUOUS | \ - NPY_ARRAY_ALIGNED) - -#define NPY_FARRAY NPY_ARRAY_FARRAY -#define NPY_CARRAY NPY_ARRAY_CARRAY - -#define PyArray_CHKFLAGS(m, flags) (PyArray_FLAGS(m) & (flags)) - -#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) -#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) -#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) - -#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) -#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) - -#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ - PyArray_ISNOTSWAPPED(m)) - -#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) -#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) -#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) -#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) -#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) -#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) - -#define PyArray_ISONESEGMENT(arr) (1) -#define PyArray_ISNOTSWAPPED(arr) (1) -#define PyArray_ISBYTESWAPPED(arr) (0) - -#endif - -#define NPY_INT8 NPY_BYTE -#define NPY_UINT8 NPY_UBYTE -#define NPY_INT16 NPY_SHORT -#define NPY_UINT16 NPY_USHORT -#define NPY_INT32 NPY_INT -#define NPY_UINT32 NPY_UINT -#define NPY_INT64 NPY_LONG -#define NPY_UINT64 NPY_ULONG -#define NPY_FLOAT32 NPY_FLOAT -#define NPY_FLOAT64 NPY_DOUBLE -#define NPY_COMPLEX32 NPY_CFLOAT -#define NPY_COMPLEX64 NPY_CDOUBLE - - -/* functions */ -#ifndef PyArray_NDIM - -#define PyArray_Check _PyArray_Check -#define PyArray_CheckExact _PyArray_CheckExact -#define PyArray_FLAGS _PyArray_FLAGS - -#define PyArray_NDIM _PyArray_NDIM -#define PyArray_DIM _PyArray_DIM -#define PyArray_STRIDE _PyArray_STRIDE -#define PyArray_SIZE _PyArray_SIZE -#define PyArray_ITEMSIZE _PyArray_ITEMSIZE -#define PyArray_NBYTES _PyArray_NBYTES -#define PyArray_TYPE _PyArray_TYPE -#define PyArray_DATA _PyArray_DATA - -#define PyArray_Size PyArray_SIZE -#define PyArray_BYTES(arr) ((char *)PyArray_DATA(arr)) - -#define PyArray_FromAny _PyArray_FromAny -#define PyArray_FromObject _PyArray_FromObject -#define PyArray_ContiguousFromObject PyArray_FromObject -#define PyArray_ContiguousFromAny PyArray_FromObject - -#define PyArray_FROMANY(obj, typenum, min, max, requirements) (obj) -#define PyArray_FROM_OTF(obj, typenum, requirements) \ - PyArray_FromObject(obj, typenum, 0, 0) - -#define PyArray_New _PyArray_New -#define PyArray_SimpleNew _PyArray_SimpleNew -#define PyArray_SimpleNewFromData _PyArray_SimpleNewFromData -#define PyArray_SimpleNewFromDataOwning _PyArray_SimpleNewFromDataOwning - -#define PyArray_EMPTY(nd, dims, type_num, fortran) \ - PyArray_SimpleNew(nd, dims, type_num) +/* functions defined in ndarrayobject.c*/ PyAPI_FUNC(void) _PyArray_FILLWBYTE(PyObject* obj, int val); PyAPI_FUNC(PyObject *) _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran); PyAPI_FUNC(int) _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src); -#define PyArray_FILLWBYTE _PyArray_FILLWBYTE -#define PyArray_ZEROS _PyArray_ZEROS -#define PyArray_CopyInto _PyArray_CopyInto -#define PyArray_Resize(self, newshape, refcheck, fortran) (NULL) - -/* Don't use these in loops! */ - -#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \ - (i)*PyArray_STRIDE(obj,0))) - -#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \ - (i)*PyArray_STRIDE(obj,0) + \ - (j)*PyArray_STRIDE(obj,1))) - -#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \ - (i)*PyArray_STRIDE(obj,0) + \ - (j)*PyArray_STRIDE(obj,1) + \ - (k)*PyArray_STRIDE(obj,2))) - -#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \ - (i)*PyArray_STRIDE(obj,0) + \ - (j)*PyArray_STRIDE(obj,1) + \ - (k)*PyArray_STRIDE(obj,2) + \ - (l)*PyArray_STRIDE(obj,3))) - -#endif #ifdef __cplusplus } diff --git a/pypy/module/cpyext/include/numpy/ndarraytypes.h b/pypy/module/cpyext/include/numpy/ndarraytypes.h --- a/pypy/module/cpyext/include/numpy/ndarraytypes.h +++ b/pypy/module/cpyext/include/numpy/ndarraytypes.h @@ -1,69 +1,9 @@ #ifndef NDARRAYTYPES_H #define NDARRAYTYPES_H +/* For testing ndarrayobject only */ + #include "numpy/npy_common.h" -//#include "npy_endian.h" -//#include "npy_cpu.h" -//#include "utils.h" - -//for pypy - numpy has lots of typedefs -//for pypy - make life easier, less backward support -#define NPY_1_8_API_VERSION 0x00000008 -#define NPY_NO_DEPRECATED_API NPY_1_8_API_VERSION -#undef NPY_1_8_API_VERSION - -#define NPY_ENABLE_SEPARATE_COMPILATION 1 -#define NPY_VISIBILITY_HIDDEN - -#ifdef NPY_ENABLE_SEPARATE_COMPILATION - #define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN -#else - #define NPY_NO_EXPORT static -#endif - -/* Only use thread if configured in config and python supports it */ -#if defined WITH_THREAD && !NPY_NO_SMP - #define NPY_ALLOW_THREADS 1 -#else - #define NPY_ALLOW_THREADS 0 -#endif - - - -/* - * There are several places in the code where an array of dimensions - * is allocated statically. This is the size of that static - * allocation. - * - * The array creation itself could have arbitrary dimensions but all - * the places where static allocation is used would need to be changed - * to dynamic (including inside of several structures) - */ - -#define NPY_MAXDIMS 32 -#define NPY_MAXARGS 32 - -/* Used for Converter Functions "O&" code in ParseTuple */ -#define NPY_FAIL 0 -#define NPY_SUCCEED 1 - -/* - * Binary compatibility version number. This number is increased - * whenever the C-API is changed such that binary compatibility is - * broken, i.e. whenever a recompile of extension modules is needed. - */ -#define NPY_VERSION NPY_ABI_VERSION - -/* - * Minor API version. This number is increased whenever a change is - * made to the C-API -- whether it breaks binary compatibility or not. - * Some changes, such as adding a function pointer to the end of the - * function table, can be made without breaking binary compatibility. - * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION) - * would be increased. Whenever binary compatibility is broken, both - * NPY_VERSION and NPY_FEATURE_VERSION should be increased. - */ -#define NPY_FEATURE_VERSION NPY_API_VERSION enum NPY_TYPES { NPY_BOOL=0, NPY_BYTE, NPY_UBYTE, @@ -91,18 +31,6 @@ NPY_NTYPES_ABI_COMPATIBLE=21 }; -/* basetype array priority */ -#define NPY_PRIORITY 0.0 - -/* default subtype priority */ -#define NPY_SUBTYPE_PRIORITY 1.0 - -/* default scalar priority */ -#define NPY_SCALAR_PRIORITY -1000000.0 - -/* How many floating point types are there (excluding half) */ -#define NPY_NUM_FLOATTYPE 3 - /* * These characters correspond to the array type and the struct * module @@ -157,27 +85,6 @@ }; typedef enum { - NPY_QUICKSORT=0, - NPY_HEAPSORT=1, - NPY_MERGESORT=2 -} NPY_SORTKIND; -#define NPY_NSORTS (NPY_MERGESORT + 1) - - -typedef enum { - NPY_INTROSELECT=0, -} NPY_SELECTKIND; -#define NPY_NSELECTS (NPY_INTROSELECT + 1) - - -typedef enum { - NPY_SEARCHLEFT=0, - NPY_SEARCHRIGHT=1 -} NPY_SEARCHSIDE; -#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1) - - -typedef enum { NPY_NOSCALAR=-1, NPY_BOOL_SCALAR, NPY_INTPOS_SCALAR, @@ -186,7 +93,6 @@ NPY_COMPLEX_SCALAR, NPY_OBJECT_SCALAR } NPY_SCALARKIND; -#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1) /* For specifying array memory layout or iteration order */ typedef enum { @@ -200,729 +106,6 @@ NPY_KEEPORDER=2 } NPY_ORDER; -/* For specifying allowed casting in operations which support it */ -typedef enum { - /* Only allow identical types */ - NPY_NO_CASTING=0, - /* Allow identical and byte swapped types */ - NPY_EQUIV_CASTING=1, - /* Only allow safe casts */ - NPY_SAFE_CASTING=2, - /* Allow safe casts or casts within the same kind */ - NPY_SAME_KIND_CASTING=3, - /* Allow any casts */ - NPY_UNSAFE_CASTING=4, - - /* - * Temporary internal definition only, will be removed in upcoming - * release, see below - * */ - NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND = 100, -} NPY_CASTING; - -typedef enum { - NPY_CLIP=0, - NPY_WRAP=1, - NPY_RAISE=2 -} NPY_CLIPMODE; - -/* The special not-a-time (NaT) value */ -#define NPY_DATETIME_NAT NPY_MIN_INT64 - -/* - * Upper bound on the length of a DATETIME ISO 8601 string - * YEAR: 21 (64-bit year) - * MONTH: 3 - * DAY: 3 - * HOURS: 3 - * MINUTES: 3 - * SECONDS: 3 - * ATTOSECONDS: 1 + 3*6 - * TIMEZONE: 5 - * NULL TERMINATOR: 1 - */ -#define NPY_DATETIME_MAX_ISO8601_STRLEN (21+3*5+1+3*6+6+1) - -typedef enum { - NPY_FR_Y = 0, /* Years */ - NPY_FR_M = 1, /* Months */ - NPY_FR_W = 2, /* Weeks */ - /* Gap where 1.6 NPY_FR_B (value 3) was */ - NPY_FR_D = 4, /* Days */ - NPY_FR_h = 5, /* hours */ - NPY_FR_m = 6, /* minutes */ - NPY_FR_s = 7, /* seconds */ - NPY_FR_ms = 8, /* milliseconds */ - NPY_FR_us = 9, /* microseconds */ - NPY_FR_ns = 10,/* nanoseconds */ - NPY_FR_ps = 11,/* picoseconds */ - NPY_FR_fs = 12,/* femtoseconds */ - NPY_FR_as = 13,/* attoseconds */ - NPY_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */ -} NPY_DATETIMEUNIT; - -/* - * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS - * is technically one more than the actual number of units. - */ -#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1) -#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC - -/* - * Business day conventions for mapping invalid business - * days to valid business days. - */ -typedef enum { - /* Go forward in time to the following business day. */ - NPY_BUSDAY_FORWARD, - NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD, - /* Go backward in time to the preceding business day. */ - NPY_BUSDAY_BACKWARD, - NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD, - /* - * Go forward in time to the following business day, unless it - * crosses a month boundary, in which case go backward - */ - NPY_BUSDAY_MODIFIEDFOLLOWING, - /* - * Go backward in time to the preceding business day, unless it - * crosses a month boundary, in which case go forward. - */ - NPY_BUSDAY_MODIFIEDPRECEDING, - /* Produce a NaT for non-business days. */ - NPY_BUSDAY_NAT, - /* Raise an exception for non-business days. */ - NPY_BUSDAY_RAISE -} NPY_BUSDAY_ROLL; - -/************************************************************ - * NumPy Auxiliary Data for inner loops, sort functions, etc. - ************************************************************/ - -/* - * When creating an auxiliary data struct, this should always appear - * as the first member, like this: - * - * typedef struct { - * NpyAuxData base; - * double constant; - * } constant_multiplier_aux_data; - */ -typedef struct NpyAuxData_tag NpyAuxData; - -/* Function pointers for freeing or cloning auxiliary data */ -typedef void (NpyAuxData_FreeFunc) (NpyAuxData *); -typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *); - -struct NpyAuxData_tag { - NpyAuxData_FreeFunc *free; - NpyAuxData_CloneFunc *clone; - /* To allow for a bit of expansion without breaking the ABI */ - void *reserved[2]; -}; - -/* Macros to use for freeing and cloning auxiliary data */ -#define NPY_AUXDATA_FREE(auxdata) \ - do { \ - if ((auxdata) != NULL) { \ - (auxdata)->free(auxdata); \ - } \ - } while(0) -#define NPY_AUXDATA_CLONE(auxdata) \ - ((auxdata)->clone(auxdata)) - -#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr); -#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr); - -#define NPY_STRINGIFY(x) #x -#define NPY_TOSTRING(x) NPY_STRINGIFY(x) - - /* - * Macros to define how array, and dimension/strides data is - * allocated. - */ - - /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */ - -#define NPY_USE_PYMEM 1 - -#if NPY_USE_PYMEM == 1 -#define PyArray_malloc PyMem_Malloc -#define PyArray_free PyMem_Free -#define PyArray_realloc PyMem_Realloc -#else -#define PyArray_malloc malloc -#define PyArray_free free -#define PyArray_realloc realloc -#endif - -/* Dimensions and strides */ -#define PyDimMem_NEW(size) \ - ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp))) - -#define PyDimMem_FREE(ptr) PyArray_free(ptr) - -#define PyDimMem_RENEW(ptr,size) \ - ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp))) - -/* forward declaration */ -struct _PyArray_Descr; - -/* These must deal with unaligned and swapped data if necessary */ -typedef PyObject * (PyArray_GetItemFunc) (void *, void *); -typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *); - -typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp, - npy_intp, int, void *); - -typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *); -typedef npy_bool (PyArray_NonzeroFunc)(void *, void *); - - -/* - * These assume aligned and notswapped data -- a buffer will be used - * before or contiguous data will be obtained - */ - -typedef int (PyArray_CompareFunc)(const void *, const void *, void *); -typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *); - -typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *, - npy_intp, void *); - -typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, - void *); - -/* - * XXX the ignore argument should be removed next time the API version - * is bumped. It used to be the separator. - */ -typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr, - char *ignore, struct _PyArray_Descr *); -typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr, - struct _PyArray_Descr *); - -typedef int (PyArray_FillFunc)(void *, npy_intp, void *); - -typedef int (PyArray_SortFunc)(void *, npy_intp, void *); -typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *); -typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp, - npy_intp *, npy_intp *, - void *); -typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp, - npy_intp *, npy_intp *, - void *); - -typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *); - -typedef int (PyArray_ScalarKindFunc)(void *); - -typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min, - void *max, void *out); -typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in, - void *values, npy_intp nv); -typedef int (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray, - npy_intp nindarray, npy_intp n_outer, - npy_intp m_middle, npy_intp nelem, - NPY_CLIPMODE clipmode); - -typedef struct { - npy_intp *ptr; - int len; -} PyArray_Dims; - -typedef struct { - /* - * Functions to cast to most other standard types - * Can have some NULL entries. The types - * DATETIME, TIMEDELTA, and HALF go into the castdict - * even though they are built-in. - */ - PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE]; - - /* The next four functions *cannot* be NULL */ - - /* - * Functions to get and set items with standard Python types - * -- not array scalars - */ - PyArray_GetItemFunc *getitem; - PyArray_SetItemFunc *setitem; - - /* - * Copy and/or swap data. Memory areas may not overlap - * Use memmove first if they might - */ - PyArray_CopySwapNFunc *copyswapn; - PyArray_CopySwapFunc *copyswap; - - /* - * Function to compare items - * Can be NULL - */ - PyArray_CompareFunc *compare; - - /* - * Function to select largest - * Can be NULL - */ - PyArray_ArgFunc *argmax; - - /* - * Function to compute dot product - * Can be NULL - */ - PyArray_DotFunc *dotfunc; - - /* - * Function to scan an ASCII file and - * place a single value plus possible separator - * Can be NULL - */ - PyArray_ScanFunc *scanfunc; - - /* - * Function to read a single value from a string - * and adjust the pointer; Can be NULL - */ - PyArray_FromStrFunc *fromstr; - - /* - * Function to determine if data is zero or not - * If NULL a default version is - * used at Registration time. - */ - PyArray_NonzeroFunc *nonzero; - - /* - * Used for arange. - * Can be NULL. - */ - PyArray_FillFunc *fill; - - /* - * Function to fill arrays with scalar values - * Can be NULL - */ - PyArray_FillWithScalarFunc *fillwithscalar; - - /* - * Sorting functions - * Can be NULL - */ - PyArray_SortFunc *sort[NPY_NSORTS]; - PyArray_ArgSortFunc *argsort[NPY_NSORTS]; - - /* - * Dictionary of additional casting functions - * PyArray_VectorUnaryFuncs - * which can be populated to support casting - * to other registered types. Can be NULL - */ - PyObject *castdict; - - /* - * Functions useful for generalizing - * the casting rules. - * Can be NULL; - */ - PyArray_ScalarKindFunc *scalarkind; - int **cancastscalarkindto; - int *cancastto; - - PyArray_FastClipFunc *fastclip; - PyArray_FastPutmaskFunc *fastputmask; - PyArray_FastTakeFunc *fasttake; - - /* - * Function to select smallest - * Can be NULL - */ - PyArray_ArgFunc *argmin; - -} PyArray_ArrFuncs; - -/* The item must be reference counted when it is inserted or extracted. */ -#define NPY_ITEM_REFCOUNT 0x01 -/* Same as needing REFCOUNT */ -#define NPY_ITEM_HASOBJECT 0x01 -/* Convert to list for pickling */ -#define NPY_LIST_PICKLE 0x02 -/* The item is a POINTER */ -#define NPY_ITEM_IS_POINTER 0x04 -/* memory needs to be initialized for this data-type */ -#define NPY_NEEDS_INIT 0x08 -/* operations need Python C-API so don't give-up thread. */ -#define NPY_NEEDS_PYAPI 0x10 -/* Use f.getitem when extracting elements of this data-type */ -#define NPY_USE_GETITEM 0x20 -/* Use f.setitem when setting creating 0-d array from this data-type.*/ -#define NPY_USE_SETITEM 0x40 -/* A sticky flag specifically for structured arrays */ -#define NPY_ALIGNED_STRUCT 0x80 - -/* - *These are inherited for global data-type if any data-types in the - * field have them - */ -#define NPY_FROM_FIELDS (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \ - NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI) - -#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \ - NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \ - NPY_NEEDS_INIT | NPY_NEEDS_PYAPI) - -#define PyDataType_FLAGCHK(dtype, flag) \ - (((dtype)->flags & (flag)) == (flag)) - -#define PyDataType_REFCHK(dtype) \ - PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT) - -typedef struct _PyArray_Descr { - PyObject_HEAD - /* - * the type object representing an - * instance of this type -- should not - * be two type_numbers with the same type - * object. - */ - PyTypeObject *typeobj; - /* kind for this type */ - char kind; - /* unique-character representing this type */ - char type; - /* - * '>' (big), '<' (little), '|' - * (not-applicable), or '=' (native). - */ - char byteorder; - /* flags describing data type */ - char flags; - /* number representing this type */ - int type_num; - /* element size (itemsize) for this type */ - int elsize; - /* alignment needed for this type */ - int alignment; - /* - * Non-NULL if this type is - * is an array (C-contiguous) - * of some other type - */ - struct _arr_descr *subarray; - /* - * The fields dictionary for this type - * For statically defined descr this - * is always Py_None - */ - PyObject *fields; - /* - * An ordered tuple of field names or NULL - * if no fields are defined - */ - PyObject *names; - /* - * a table of functions specific for each - * basic data descriptor - */ - PyArray_ArrFuncs *f; - /* Metadata about this dtype */ - PyObject *metadata; - /* - * Metadata specific to the C implementation - * of the particular dtype. This was added - * for NumPy 1.7.0. - */ - NpyAuxData *c_metadata; -} PyArray_Descr; - -typedef struct _arr_descr { - PyArray_Descr *base; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit