Author: Ronan Lamy <ronan.l...@gmail.com> Branch: follow_symlinks Changeset: r83775:16fdc05dd0b4 Date: 2016-04-19 20:12 +0100 http://bitbucket.org/pypy/pypy/changeset/16fdc05dd0b4/
Log: hg merge py3k diff too long, truncating to 2000 out of 8726 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -111,23 +111,24 @@ Simon Burton Martin Matusiak Konstantin Lopuhin + Stefano Rivera Wenzhu Man John Witulski Laurence Tratt Ivan Sichmann Freitas Greg Price Dario Bertini - Stefano Rivera Mark Pearse Simon Cross + Edd Barrett Andreas Stührk - Edd Barrett Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Spenser Bauman Jeremy Thurgood Paweł Piotr Przeradowski - Spenser Bauman + Tobias Pape Paul deGrandis Ilya Osadchiy marky1991 @@ -139,7 +140,7 @@ Georg Brandl Bert Freudenberg Stian Andreassen - Tobias Pape + Mark Young Wanja Saatkamp Gerald Klix Mike Blume @@ -170,9 +171,9 @@ Yichao Yu Rocco Moretti Gintautas Miliauskas + Devin Jeanpierre Michael Twomey Lucian Branescu Mihaila - Devin Jeanpierre Gabriel Lavoie Olivier Dormond Jared Grubb @@ -183,6 +184,7 @@ Victor Stinner Andrews Medina anatoly techtonik + Sergey Matyunin Stuart Williams Jasper Schulz Christian Hudon @@ -217,7 +219,6 @@ Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan - Mark Young Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -225,7 +226,9 @@ Pieter Zieschang Gabriel Lukas Vacek + Kunal Grover Andrew Dalke + Florin Papa Sylvain Thenault Jakub Stasiak Nathan Taylor @@ -240,7 +243,6 @@ Kristjan Valur Jonsson David Lievens Neil Blakey-Milner - Sergey Matyunin Lutz Paelike Lucio Torre Lars Wassermann @@ -252,9 +254,11 @@ Artur Lisiecki Sergey Kishchenko Ignas Mikalajunas + Alecsandru Patrascu Christoph Gerum Martin Blais Lene Wagner + Catalin Gabriel Manciu Tomo Cocoa Kim Jin Su Toni Mattis @@ -291,6 +295,7 @@ Akira Li Gustavo Niemeyer Stephan Busemann + florinpapa Rafał Gałczyński Matt Bogosian Christian Muirhead @@ -305,6 +310,7 @@ Boglarka Vezer Chris Pressey Buck Golemon + Diana Popa Konrad Delong Dinu Gherman Chris Lambacher diff --git a/lib-python/3/test/test_hash.py b/lib-python/3/test/test_hash.py --- a/lib-python/3/test/test_hash.py +++ b/lib-python/3/test/test_hash.py @@ -8,6 +8,7 @@ import sys import unittest from test.script_helper import assert_python_ok +from test.support import impl_detail, check_impl_detail from collections import Hashable IS_64BIT = sys.maxsize > 2**32 @@ -140,6 +141,7 @@ def get_hash_command(self, repr_): return 'print(hash(eval(%a)))' % repr_ + @impl_detail("PyPy does not support hash randomization", pypy=False) def get_hash(self, repr_, seed=None): env = os.environ.copy() env['__cleanenv'] = True # signal to assert_python not to do a copy @@ -161,6 +163,11 @@ self.assertNotEqual(run1, run2) class StringlikeHashRandomizationTests(HashRandomizationTests): + if check_impl_detail(pypy=True): + EMPTY_STRING_HASH = -1 + else: + EMPTY_STRING_HASH = 0 + def test_null_hash(self): # PYTHONHASHSEED=0 disables the randomized hash if IS_64BIT: @@ -194,21 +201,21 @@ repr_ = repr('abc') def test_empty_string(self): - self.assertEqual(hash(""), 0) + self.assertEqual(hash(""), self.EMPTY_STRING_HASH) class BytesHashRandomizationTests(StringlikeHashRandomizationTests, unittest.TestCase): repr_ = repr(b'abc') def test_empty_string(self): - self.assertEqual(hash(b""), 0) + self.assertEqual(hash(b""), self.EMPTY_STRING_HASH) class MemoryviewHashRandomizationTests(StringlikeHashRandomizationTests, unittest.TestCase): repr_ = "memoryview(b'abc')" def test_empty_string(self): - self.assertEqual(hash(memoryview(b"")), 0) + self.assertEqual(hash(memoryview(b"")), self.EMPTY_STRING_HASH) class DatetimeTests(HashRandomizationTests): def get_hash_command(self, repr_): diff --git a/lib-python/3/test/test_itertools.py b/lib-python/3/test/test_itertools.py --- a/lib-python/3/test/test_itertools.py +++ b/lib-python/3/test/test_itertools.py @@ -1728,6 +1728,7 @@ class LengthTransparency(unittest.TestCase): + @support.impl_detail("__length_hint__() API is undocumented") def test_repeat(self): from test.test_iterlen import len self.assertEqual(len(repeat(None, 50)), 50) diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.5.2 +Version: 1.6.0 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,8 +4,8 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.5.2" -__version_info__ = (1, 5, 2) +__version__ = "1.6.0" +__version_info__ = (1, 6, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -233,7 +233,7 @@ f = PySys_GetObject((char *)"stderr"); if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.5.2" + "\ncompiled with cffi version: 1.6.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -299,6 +299,23 @@ """ return self._backend.string(cdata, maxlen) + def unpack(self, 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 self._backend.unpack(cdata, length) + def buffer(self, cdata, size=-1): """Return a read-write buffer object that references the raw C data pointed to by the given 'cdata'. The 'cdata' must be a pointer or @@ -721,6 +738,26 @@ raise ValueError("ffi.def_extern() is only available on API-mode FFI " "objects") + def list_types(self): + """Returns the user type names known to this FFI instance. + This returns a tuple containing three lists of names: + (typedef_names, names_of_structs, names_of_unions) + """ + typedefs = [] + structs = [] + unions = [] + for key in self._parser._declarations: + if key.startswith('typedef '): + typedefs.append(key[8:]) + elif key.startswith('struct '): + structs.append(key[7:]) + elif key.startswith('union '): + unions.append(key[6:]) + typedefs.sort() + structs.sort() + unions.sort() + return (typedefs, structs, unions) + def _load_backend_lib(backend, name, flags): if name is None: diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -1231,7 +1231,7 @@ if c == '\n': return '\\n' return '\\%03o' % ord(c) lines = [] - for line in s.splitlines(True): + for line in s.splitlines(True) or ['']: lines.append('"%s"' % ''.join([_char_repr(c) for c in line])) return ' \\\n'.join(lines) @@ -1319,7 +1319,9 @@ s = s.encode('ascii') super(NativeIO, self).write(s) -def _make_c_or_py_source(ffi, module_name, preamble, target_file): +def _make_c_or_py_source(ffi, module_name, preamble, target_file, verbose): + if verbose: + print("generating %s" % (target_file,)) recompiler = Recompiler(ffi, module_name, target_is_python=(preamble is None)) recompiler.collect_type_table() @@ -1331,6 +1333,8 @@ with open(target_file, 'r') as f1: if f1.read(len(output) + 1) != output: raise IOError + if verbose: + print("(already up-to-date)") return False # already up-to-date except IOError: tmp_file = '%s.~%d' % (target_file, os.getpid()) @@ -1343,12 +1347,14 @@ os.rename(tmp_file, target_file) return True -def make_c_source(ffi, module_name, preamble, target_c_file): +def make_c_source(ffi, module_name, preamble, target_c_file, verbose=False): assert preamble is not None - return _make_c_or_py_source(ffi, module_name, preamble, target_c_file) + return _make_c_or_py_source(ffi, module_name, preamble, target_c_file, + verbose) -def make_py_source(ffi, module_name, target_py_file): - return _make_c_or_py_source(ffi, module_name, None, target_py_file) +def make_py_source(ffi, module_name, target_py_file, verbose=False): + return _make_c_or_py_source(ffi, module_name, None, target_py_file, + verbose) def _modname_to_file(outputdir, modname, extension): parts = modname.split('.') @@ -1438,7 +1444,8 @@ target = '*' # ext = ffiplatform.get_extension(ext_c_file, module_name, **kwds) - updated = make_c_source(ffi, module_name, preamble, c_file) + updated = make_c_source(ffi, module_name, preamble, c_file, + verbose=compiler_verbose) if call_c_compiler: patchlist = [] cwd = os.getcwd() @@ -1458,7 +1465,8 @@ else: if c_file is None: c_file, _ = _modname_to_file(tmpdir, module_name, '.py') - updated = make_py_source(ffi, module_name, c_file) + updated = make_py_source(ffi, module_name, c_file, + verbose=compiler_verbose) if call_c_compiler: return c_file else: @@ -1484,4 +1492,7 @@ def typeof_disabled(*args, **kwds): raise NotImplementedError ffi._typeof = typeof_disabled + for name in dir(ffi): + if not name.startswith('_') and not hasattr(module.ffi, name): + setattr(ffi, name, NotImplemented) return module.lib diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -81,13 +81,13 @@ Simon Burton Martin Matusiak Konstantin Lopuhin + Stefano Rivera Wenzhu Man John Witulski Laurence Tratt Ivan Sichmann Freitas Greg Price Dario Bertini - Stefano Rivera Mark Pearse Simon Cross Andreas Stührk @@ -95,9 +95,10 @@ Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov + Spenser Bauman Jeremy Thurgood Paweł Piotr Przeradowski - Spenser Bauman + Tobias Pape Paul deGrandis Ilya Osadchiy marky1991 @@ -109,7 +110,7 @@ Georg Brandl Bert Freudenberg Stian Andreassen - Tobias Pape + Mark Young Wanja Saatkamp Gerald Klix Mike Blume @@ -140,9 +141,9 @@ Yichao Yu Rocco Moretti Gintautas Miliauskas + Devin Jeanpierre Michael Twomey Lucian Branescu Mihaila - Devin Jeanpierre Gabriel Lavoie Olivier Dormond Jared Grubb @@ -153,6 +154,7 @@ Victor Stinner Andrews Medina anatoly techtonik + Sergey Matyunin Stuart Williams Jasper Schulz Christian Hudon @@ -187,7 +189,6 @@ Arjun Naik Valentina Mukhamedzhanova Stefano Parmesan - Mark Young Alexis Daboville Jens-Uwe Mager Carl Meyer @@ -195,7 +196,9 @@ Pieter Zieschang Gabriel Lukas Vacek + Kunal Grover Andrew Dalke + Florin Papa Sylvain Thenault Jakub Stasiak Nathan Taylor @@ -210,7 +213,6 @@ Kristjan Valur Jonsson David Lievens Neil Blakey-Milner - Sergey Matyunin Lutz Paelike Lucio Torre Lars Wassermann @@ -222,9 +224,11 @@ Artur Lisiecki Sergey Kishchenko Ignas Mikalajunas + Alecsandru Patrascu Christoph Gerum Martin Blais Lene Wagner + Catalin Gabriel Manciu Tomo Cocoa Kim Jin Su Toni Mattis @@ -261,6 +265,7 @@ Akira Li Gustavo Niemeyer Stephan Busemann + florinpapa Rafał Gałczyński Matt Bogosian Christian Muirhead @@ -275,6 +280,7 @@ Boglarka Vezer Chris Pressey Buck Golemon + Diana Popa Konrad Delong Dinu Gherman Chris Lambacher 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 + + * 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 + + * Fix sandbox startup (a regression in 5.0) + + * 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,42 +1,16 @@ ========================= -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 - -.. 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 +.. this is a revision shortly after release-5.1 +.. startrev: 2180e1eaf6f6 .. branch: rposix-for-3 -Wrap more POSIX functions in `rpython.rlib.rposix`. +Reuse rposix definition of TIMESPEC in rposix_stat, add wrapper for fstatat(). +This updates the underlying rpython functions with the ones needed for the +py3k branch + +.. branch: numpy_broadcast + +Add broadcast to micronumpy diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -583,6 +583,9 @@ # lives in pypy/module/exceptions, we rename it below for # sys.builtin_module_names bootstrap_modules = set(('sys', 'imp', 'builtins', 'exceptions')) + if sys.platform.startswith("win"): + self.setbuiltinmodule('_winreg') + bootstrap_modules.add('winreg') installed_builtin_modules = list(bootstrap_modules) exception_types_w = self.export_builtin_exceptions() @@ -1052,6 +1055,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) @@ -1509,7 +1515,7 @@ assert False # XXX rename/replace with code more like CPython getargs for buffers - def bufferstr_w(self, w_obj): + def bufferstr_w(self, w_obj, flags=BUF_SIMPLE): # Directly returns an interp-level str. Note that if w_obj is a # unicode string, this is different from str_w(buffer(w_obj)): # indeed, the latter returns a string with the raw bytes from @@ -1523,13 +1529,7 @@ except OperationError, e: if not e.match(self, self.w_TypeError): raise - try: - buf = w_obj.buffer_w(self, 0) - except BufferInterfaceNotFound: - raise oefmt(self.w_TypeError, - "'%T' does not support the buffer interface", w_obj) - else: - return buf.as_str() + return self.buffer_w(w_obj, flags).as_str() def str_or_None_w(self, w_obj): return None if self.is_none(w_obj) else self.str_w(w_obj) 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 @@ -5,9 +5,9 @@ # ____________________________________________________________ -def sorted(lst, key=None, reverse=False): +def sorted(iterable, key=None, reverse=False): "sorted(iterable, key=None, reverse=False) --> new sorted list" - sorted_lst = list(lst) + sorted_lst = list(iterable) sorted_lst.sort(key=key, reverse=reverse) return sorted_lst 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 @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi, entrypoint from rpython.rtyper.lltypesystem import rffi -VERSION = "1.5.2" +VERSION = "1.6.0" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: @@ -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.wrapbytes(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. @@ -611,6 +630,38 @@ return w_result + def descr_list_types(self): + """\ +Returns the user type names known to this FFI instance. +This returns a tuple containing three lists of names: +(typedef_names, names_of_structs, names_of_unions)""" + # + space = self.space + ctx = self.ctxobj.ctx + + lst1_w = [] + for i in range(rffi.getintfield(ctx, 'c_num_typenames')): + s = rffi.charp2str(ctx.c_typenames[i].c_name) + lst1_w.append(space.wrap(s)) + + lst2_w = [] + lst3_w = [] + for i in range(rffi.getintfield(ctx, 'c_num_struct_unions')): + su = ctx.c_struct_unions[i] + if su.c_name[0] == '$': + continue + s = rffi.charp2str(su.c_name) + if rffi.getintfield(su, 'c_flags') & cffi_opcode.F_UNION: + lst_w = lst3_w + else: + lst_w = lst2_w + lst_w.append(space.wrap(s)) + + return space.newtuple([space.newlist(lst1_w), + space.newlist(lst2_w), + space.newlist(lst3_w)]) + + def descr_init_once(self, w_func, w_tag): """\ init_once(function, tag): run function() once. More precisely, @@ -731,6 +782,7 @@ getctype = interp2app(W_FFIObject.descr_getctype), init_once = interp2app(W_FFIObject.descr_init_once), integer_const = interp2app(W_FFIObject.descr_integer_const), + list_types = interp2app(W_FFIObject.descr_list_types), memmove = interp2app(W_FFIObject.descr_memmove), new = interp2app(W_FFIObject.descr_new), new_allocator = interp2app(W_FFIObject.descr_new_allocator), @@ -739,4 +791,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 @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.5.2", ("This test_c.py file is for testing a version" +assert __version__ == "1.6.0", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): @@ -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/_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 @@ -1626,3 +1626,150 @@ # a case where 'onerror' is not callable raises(TypeError, ffi.def_extern(name='bar', onerror=42), lambda x: x) + + def test_extern_python_stdcall(self): + ffi, lib = self.prepare(""" + extern "Python" int __stdcall foo(int); + extern "Python" int WINAPI bar(int); + int (__stdcall * mycb1)(int); + int indirect_call(int); + """, 'test_extern_python_stdcall', """ + #ifndef _MSC_VER + # define __stdcall + #endif + static int (__stdcall * mycb1)(int); + static int indirect_call(int x) { + return mycb1(x); + } + """) + # + @ffi.def_extern() + def foo(x): + return x + 42 + @ffi.def_extern() + def bar(x): + return x + 43 + assert lib.foo(100) == 142 + assert lib.bar(100) == 143 + lib.mycb1 = lib.foo + assert lib.mycb1(200) == 242 + assert lib.indirect_call(300) == 342 + + def test_introspect_function(self): + ffi, lib = self.prepare(""" + float f1(double); + """, 'test_introspect_function', """ + float f1(double x) { return x; } + """) + assert dir(lib) == ['f1'] + FUNC = ffi.typeof(lib.f1) + assert FUNC.kind == 'function' + assert FUNC.args[0].cname == 'double' + assert FUNC.result.cname == 'float' + assert ffi.typeof(ffi.addressof(lib, 'f1')) is FUNC + + def test_introspect_global_var(self): + ffi, lib = self.prepare(""" + float g1; + """, 'test_introspect_global_var', """ + float g1; + """) + assert dir(lib) == ['g1'] + FLOATPTR = ffi.typeof(ffi.addressof(lib, 'g1')) + assert FLOATPTR.kind == 'pointer' + assert FLOATPTR.item.cname == 'float' + + def test_introspect_global_var_array(self): + ffi, lib = self.prepare(""" + float g1[100]; + """, 'test_introspect_global_var_array', """ + float g1[100]; + """) + assert dir(lib) == ['g1'] + FLOATARRAYPTR = ffi.typeof(ffi.addressof(lib, 'g1')) + assert FLOATARRAYPTR.kind == 'pointer' + assert FLOATARRAYPTR.item.kind == 'array' + assert FLOATARRAYPTR.item.length == 100 + assert ffi.typeof(lib.g1) is FLOATARRAYPTR.item + + def test_introspect_integer_const(self): + ffi, lib = self.prepare("#define FOO 42", + 'test_introspect_integer_const', """ + #define FOO 42 + """) + assert dir(lib) == ['FOO'] + assert lib.FOO == ffi.integer_const('FOO') == 42 + + def test_introspect_typedef(self): + ffi, lib = self.prepare("typedef int foo_t;", + 'test_introspect_typedef', """ + typedef int foo_t; + """) + assert ffi.list_types() == (['foo_t'], [], []) + assert ffi.typeof('foo_t').kind == 'primitive' + assert ffi.typeof('foo_t').cname == 'int' + + def test_introspect_typedef_multiple(self): + ffi, lib = self.prepare(""" + typedef signed char a_t, c_t, g_t, b_t; + """, 'test_introspect_typedef_multiple', """ + typedef signed char a_t, c_t, g_t, b_t; + """) + assert ffi.list_types() == (['a_t', 'b_t', 'c_t', 'g_t'], [], []) + + def test_introspect_struct(self): + ffi, lib = self.prepare(""" + struct foo_s { int a; }; + """, 'test_introspect_struct', """ + struct foo_s { int a; }; + """) + assert ffi.list_types() == ([], ['foo_s'], []) + assert ffi.typeof('struct foo_s').kind == 'struct' + assert ffi.typeof('struct foo_s').cname == 'struct foo_s' + + def test_introspect_union(self): + ffi, lib = self.prepare(""" + union foo_s { int a; }; + """, 'test_introspect_union', """ + union foo_s { int a; }; + """) + assert ffi.list_types() == ([], [], ['foo_s']) + assert ffi.typeof('union foo_s').kind == 'union' + assert ffi.typeof('union foo_s').cname == 'union foo_s' + + def test_introspect_struct_and_typedef(self): + ffi, lib = self.prepare(""" + typedef struct { int a; } foo_t; + """, 'test_introspect_struct_and_typedef', """ + typedef struct { int a; } foo_t; + """) + assert ffi.list_types() == (['foo_t'], [], []) + assert ffi.typeof('foo_t').kind == 'struct' + assert ffi.typeof('foo_t').cname == 'foo_t' + + def test_introspect_included_type(self): + SOURCE = """ + typedef signed char schar_t; + struct sint_t { int x; }; + """ + ffi1, lib1 = self.prepare(SOURCE, + "test_introspect_included_type_parent", SOURCE) + ffi2, lib2 = self.prepare("", + "test_introspect_included_type", SOURCE, + includes=[ffi1]) + assert ffi1.list_types() == ffi2.list_types() == ( + ['schar_t'], ['sint_t'], []) + + def test_introspect_order(self): + ffi, lib = self.prepare(""" + union aaa { int a; }; typedef struct ccc { int a; } b; + union g { int a; }; typedef struct cc { int a; } bbb; + union aa { int a; }; typedef struct a { int a; } bb; + """, "test_introspect_order", """ + union aaa { int a; }; typedef struct ccc { int a; } b; + union g { int a; }; typedef struct cc { int a; } bbb; + union aa { int a; }; typedef struct a { int a; } bb; + """) + assert ffi.list_types() == (['b', 'bb', 'bbb'], + ['a', 'cc', 'ccc'], + ['aa', 'aaa', 'g']) 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 @@ -758,6 +758,7 @@ try: while 1: count += cli.send(b'foobar' * 70) + assert count < 100000 except timeout: pass t.recv(count) 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 @@ -593,14 +593,6 @@ 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 @@ -609,6 +601,14 @@ return self.unwrap == 'int_w' or self.unwrap == 'bigint_w' +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.touint') +else: + _UINTTypeCode = \ + TypeCode(rffi.UINT, 'int_w', True) types = { 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''), 'b': TypeCode(rffi.SIGNEDCHAR, 'int_w', True, True), @@ -616,7 +616,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.touint'), 'q': TypeCode(rffi.LONGLONG, 'bigint_w.tolonglong', True, True), 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 @@ -77,14 +77,15 @@ except OverflowError: pass - for tc in 'BHIL': + for tc in 'BHILQ': 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() @@ -234,7 +222,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. @@ -268,6 +257,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, @@ -275,10 +266,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) @@ -366,7 +353,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. @@ -794,10 +782,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 { @@ -806,7 +795,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(): @@ -823,6 +813,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 + @@ -898,13 +893,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) @@ -997,18 +998,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') @@ -1018,19 +1013,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) @@ -1047,13 +1051,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) @@ -1162,7 +1163,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) @@ -1204,14 +1206,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 @@ -139,7 +139,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) + \ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit