diff options
author | Robert Bradshaw <robertwb@gmail.com> | 2015-02-11 23:45:56 -0800 |
---|---|---|
committer | Robert Bradshaw <robertwb@gmail.com> | 2015-02-11 23:45:56 -0800 |
commit | e9036d3a820c072afc9e8a0d1b4221b3b9a87813 (patch) | |
tree | ac32bc44c1d7c81da0df7b7d3bf13412780da1a3 | |
parent | 1fb644d60cb864521e071870af3f448137581455 (diff) | |
parent | 73022d117ef1b2da1f6dcb0196021ea86c97f83d (diff) | |
download | cython-e9036d3a820c072afc9e8a0d1b4221b3b9a87813.tar.gz |
Merge branch '0.22.x' into release-candidate
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 17 | ||||
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 5 | ||||
-rw-r--r-- | Cython/Utility/Profile.c | 92 | ||||
-rw-r--r-- | docs/src/userguide/buffer.rst | 10 | ||||
-rwxr-xr-x | runtests.py | 1 | ||||
-rw-r--r-- | tests/bugs.txt | 2 | ||||
-rw-r--r-- | tests/run/carray_coercion.pyx | 51 | ||||
-rw-r--r-- | tests/run/coverage.srctree | 64 | ||||
-rw-r--r-- | tests/run/numpy_math.pyx | 3 |
10 files changed, 194 insertions, 53 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 5af9a30ac..03a9c0d70 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -58,7 +58,7 @@ Other changes * ``_`` is no longer considered a cacheable builtin as it could interfere with gettext. -* Cythonize-computed metadata now cached in the generate C files. +* Cythonize-computed metadata now cached in the generated C files. * Several corrections and extensions in numpy, cpython, and libcpp pxd files. diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 61143c9df..f99ec6e92 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -6767,11 +6767,18 @@ class ListNode(SequenceNode): else: offset = '' for i, arg in enumerate(self.args): - code.putln("%s[%s%s] = %s;" % ( - self.result(), - i, - offset, - arg.result())) + if arg.type.is_array: + code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c")) + code.putln("memcpy(&(%s[%s%s]), %s, sizeof(%s[0]));" % ( + self.result(), i, offset, + arg.result(), self.result() + )) + else: + code.putln("%s[%s%s] = %s;" % ( + self.result(), + i, + offset, + arg.result())) if self.mult_factor: code.putln("}") code.putln("}") diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 94d60724c..47858583d 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -552,10 +552,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("/* Generated by Cython %s */" % Version.watermark) code.putln("") if metadata: - code.putln("/* Cython Metadata */") - code.putln("/*") + code.putln("/* BEGIN: Cython Metadata") code.putln(json.dumps(metadata, indent=4)) - code.putln("*/") + code.putln("END: Cython Metadata */") code.putln("") code.putln("#define PY_SSIZE_T_CLEAN") diff --git a/Cython/Utility/Profile.c b/Cython/Utility/Profile.c index e416e66c4..94e427689 100644 --- a/Cython/Utility/Profile.c +++ b/Cython/Utility/Profile.c @@ -35,45 +35,56 @@ #endif #define __Pyx_TraceDeclarations(codeobj) \ - static PyCodeObject *$frame_code_cname = NULL; if (codeobj != NULL) $frame_code_cname = (PyCodeObject*) codeobj; \ + static PyCodeObject *$frame_code_cname = NULL; \ CYTHON_FRAME_MODIFIER PyFrameObject *$frame_cname = NULL; \ - int __Pyx_use_tracing = 0; + int __Pyx_use_tracing = 0; \ + if (codeobj) $frame_code_cname = (PyCodeObject*) codeobj; #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \ - if (unlikely(PyThreadState_GET()->use_tracing && \ - (PyThreadState_GET()->c_profilefunc || (CYTHON_TRACE && PyThreadState_GET()->c_tracefunc)))) { \ - __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ + { PyThreadState* tstate = PyThreadState_GET(); \ + if (unlikely(tstate->use_tracing) && !tstate->tracing && \ + (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ + __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ + } \ } #define __Pyx_TraceException() \ - if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && \ - (PyThreadState_GET()->c_profilefunc || (CYTHON_TRACE && PyThreadState_GET()->c_tracefunc))) { \ + if (likely(!__Pyx_use_tracing)); else { \ PyThreadState* tstate = PyThreadState_GET(); \ - tstate->use_tracing = 0; \ - PyObject *exc_info = __Pyx_GetExceptionTuple(); \ - if (exc_info) { \ - if (CYTHON_TRACE && tstate->c_tracefunc) \ - tstate->c_tracefunc( \ - tstate->c_traceobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ - tstate->c_profilefunc( \ - tstate->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ - Py_DECREF(exc_info); \ + if (tstate->use_tracing && \ + (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ + tstate->tracing++; \ + tstate->use_tracing = 0; \ + PyObject *exc_info = __Pyx_GetExceptionTuple(); \ + if (exc_info) { \ + if (CYTHON_TRACE && tstate->c_tracefunc) \ + tstate->c_tracefunc( \ + tstate->c_traceobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ + tstate->c_profilefunc( \ + tstate->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ + Py_DECREF(exc_info); \ + } \ + tstate->use_tracing = 1; \ + tstate->tracing--; \ } \ - tstate->use_tracing = 1; \ } - #define __Pyx_TraceReturn(result) \ - if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing) { \ - PyThreadState* tstate = PyThreadState_GET(); \ - tstate->use_tracing = 0; \ - if (CYTHON_TRACE && tstate->c_tracefunc) \ - tstate->c_tracefunc( \ - tstate->c_traceobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \ - if (tstate->c_profilefunc) \ - tstate->c_profilefunc( \ - tstate->c_profileobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \ - CYTHON_FRAME_DEL; \ - tstate->use_tracing = 1; \ + #define __Pyx_TraceReturn(result) \ + if (likely(!__Pyx_use_tracing)); else { \ + PyThreadState* tstate = PyThreadState_GET(); \ + if (tstate->use_tracing) { \ + tstate->tracing++; \ + tstate->use_tracing = 0; \ + if (CYTHON_TRACE && tstate->c_tracefunc) \ + tstate->c_tracefunc( \ + tstate->c_traceobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \ + if (tstate->c_profilefunc) \ + tstate->c_profilefunc( \ + tstate->c_profileobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \ + CYTHON_FRAME_DEL; \ + tstate->use_tracing = 1; \ + tstate->tracing--; \ + } \ } static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/ @@ -90,12 +101,16 @@ #if CYTHON_TRACE #define __Pyx_TraceLine(lineno) \ - if (unlikely(__Pyx_use_tracing) && unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_tracefunc)) { \ + if (likely(!__Pyx_use_tracing)); else { \ PyThreadState* tstate = PyThreadState_GET(); \ - $frame_cname->f_lineno = lineno; \ - tstate->use_tracing = 0; \ - tstate->c_tracefunc(tstate->c_traceobj, $frame_cname, PyTrace_LINE, NULL); \ - tstate->use_tracing = 1; \ + if (unlikely(tstate->use_tracing && tstate->c_tracefunc)) { \ + $frame_cname->f_lineno = lineno; \ + tstate->tracing++; \ + tstate->use_tracing = 0; \ + tstate->c_tracefunc(tstate->c_traceobj, $frame_cname, PyTrace_LINE, NULL); \ + tstate->use_tracing = 1; \ + tstate->tracing--; \ + } \ } #else #define __Pyx_TraceLine(lineno) @@ -136,17 +151,18 @@ static int __Pyx_TraceSetupAndCall(PyCodeObject** code, #endif } (*frame)->f_lineno = firstlineno; + retval = 1; + tstate->tracing++; tstate->use_tracing = 0; #if CYTHON_TRACE if (tstate->c_tracefunc) - tstate->c_tracefunc(tstate->c_traceobj, *frame, PyTrace_CALL, NULL); - if (!tstate->c_profilefunc) - retval = 1; - else + retval = tstate->c_tracefunc(tstate->c_traceobj, *frame, PyTrace_CALL, NULL) == 0; + if (retval && tstate->c_profilefunc) #endif retval = tstate->c_profilefunc(tstate->c_profileobj, *frame, PyTrace_CALL, NULL) == 0; tstate->use_tracing = (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc)); + tstate->tracing--; return tstate->use_tracing && retval; } diff --git a/docs/src/userguide/buffer.rst b/docs/src/userguide/buffer.rst index b7dfb9d6f..01e61da24 100644 --- a/docs/src/userguide/buffer.rst +++ b/docs/src/userguide/buffer.rst @@ -66,23 +66,23 @@ which Cython handles specially. self.shape[1] = self.ncols # Stride 1 is the distance, in bytes, between two items in a row; - # this is the distance between two adjance items in the vector. + # this is the distance between two adjacent items in the vector. # Stride 0 is the distance between the first elements of adjacent rows. self.strides[1] = <Py_ssize_t>( <char *>&(self.v[1]) - <char *>&(self.v[0])) self.strides[0] = self.ncols * self.strides[1] buffer.buf = <char *>&(self.v[0]) - buffer.format = 'f' - buffer.internal = NULL + buffer.format = 'f' # float + buffer.internal = NULL # see References buffer.itemsize = itemsize - buffer.len = self.v.size() * itemsize + buffer.len = self.v.size() * itemsize # product(shape) * itemsize buffer.ndim = 2 buffer.obj = self buffer.readonly = 0 buffer.shape = self.shape buffer.strides = self.strides - buffer.suboffsets = NULL + buffer.suboffsets = NULL # for pointer arrays only def __releasebuffer__(self, Py_buffer *buffer): pass diff --git a/runtests.py b/runtests.py index 8ea4c723d..90b716430 100755 --- a/runtests.py +++ b/runtests.py @@ -102,6 +102,7 @@ EXT_DEP_MODULES = { 'tag:pstats': 'pstats', 'tag:posix' : 'posix', 'tag:array' : 'array', + 'tag:coverage': 'coverage', 'tag:ipython': 'IPython', 'tag:jedi': 'jedi', } diff --git a/tests/bugs.txt b/tests/bugs.txt index 5235bc933..1f0dfa9d3 100644 --- a/tests/bugs.txt +++ b/tests/bugs.txt @@ -14,6 +14,8 @@ inherited_final_method tryfinallychaining # also see FIXME in "yield_from_pep380" test cimport_alias_subclass +coverage # depends on newer coverage.py version + # CPython regression tests that don't current work: pyregr.test_signal pyregr.test_capi diff --git a/tests/run/carray_coercion.pyx b/tests/run/carray_coercion.pyx index e08d0adcc..d73fcf497 100644 --- a/tests/run/carray_coercion.pyx +++ b/tests/run/carray_coercion.pyx @@ -67,6 +67,57 @@ def from_int_array_array(): return v +def assign_int_array_array(): + """ + >>> assign_int_array_array() + [[11, 12, 13], [21, 22, 23]] + """ + cdef int[2][3] v = [[11, 12, 13], [21, 22, 23]] + return v + + +def assign_int_array_array_from_tuples(): + """ + >>> assign_int_array_array_from_tuples() + [[11, 12, 13], [21, 22, 23]] + """ + cdef int[2][3] v = ([11, 12, 13], [21, 22, 23]) + return v + + +''' FIXME: this currently crashes: +def assign_int_array_array_from_tuples(): + """ + >>> assign_int_array_array_from_tuples() + [[11, 12, 13], [21, 22, 23]] + """ + cdef int[2][3] v = ((11, 12, 13), (21, 22, 23)) + return v +''' + + +def build_from_list_of_arrays(): + """ + >>> build_from_list_of_arrays() + [[11, 12, 13], [21, 22, 23]] + """ + cdef int[3] x = [11, 12, 13] + cdef int[3] y = [21, 22, 23] + cdef int[2][3] v = [x, y] + return v + + +def build_from_tuple_of_arrays(): + """ + >>> build_from_tuple_of_arrays() + [[11, 12, 13], [21, 22, 23]] + """ + cdef int[3] x = [11, 12, 13] + cdef int[3] y = [21, 22, 23] + cdef int[2][3] v = (x, y) + return v + + ctypedef struct MyStructType: int x double y diff --git a/tests/run/coverage.srctree b/tests/run/coverage.srctree new file mode 100644 index 000000000..6a2ccb3ba --- /dev/null +++ b/tests/run/coverage.srctree @@ -0,0 +1,64 @@ +# mode: run +# tag: coverage,trace + +""" +PYTHON setup.py build_ext -i +PYTHON coverage_test.py +""" + +######## setup.py ######## + +from distutils.core import setup +from Cython.Build import cythonize + +setup(ext_modules = cythonize('coverage_test_cy.py')) + + +######## coverage_test_cy.py ######## +# cython: linetrace=True +# distutils: define_macros=CYTHON_TRACE=1 + +def func1(a, b): + x = 1 # 5 + c = func2(a) + b # 6 + return x + c # 7 + + +def func2(a): + return a * 2 # 11 + + +######## coverage_test.py ######## + +try: + # io.StringIO in Py2.x cannot handle str ... + from StringIO import StringIO +except ImportError: + from io import StringIO + +from coverage import coverage + +import coverage_test_cy + + +def run_coverage(): + cov = coverage() + cov.start() + assert coverage_test_cy.func1(1, 2) == 5 + assert coverage_test_cy.func2(2) == 4 + cov.stop() + + out = StringIO() + cov.report([coverage_test_cy], file=out) + lines = out.getvalue().splitlines() + assert any('coverage_test_cy' in line for line in lines), "coverage_test_cy not found in coverage" + + mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(coverage_test_cy) + assert 'coverage_test_cy' in mod_file + + executed = set(exec_lines) - set(missing_lines) + assert all(line in executed for line in [5, 6, 7, 11]), '%s / %s' % (exec_lines, missing_lines) + + +if __name__ == '__main__': + run_coverage() diff --git a/tests/run/numpy_math.pyx b/tests/run/numpy_math.pyx index 48fe7cce8..eafd23a81 100644 --- a/tests/run/numpy_math.pyx +++ b/tests/run/numpy_math.pyx @@ -37,7 +37,8 @@ def test_fp_classif(): assert not npmath.isnan(d_zero) assert not npmath.isnan(f_zero) - assert npmath.isinf(npmath.INFINITY) + assert npmath.isinf(npmath.INFINITY) == 1 + assert npmath.isinf(-npmath.INFINITY) == -1 assert npmath.isnan(npmath.NAN) assert npmath.signbit(npmath.copysign(1., -1.)) |