summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bradshaw <robertwb@gmail.com>2015-02-11 23:45:56 -0800
committerRobert Bradshaw <robertwb@gmail.com>2015-02-11 23:45:56 -0800
commite9036d3a820c072afc9e8a0d1b4221b3b9a87813 (patch)
treeac32bc44c1d7c81da0df7b7d3bf13412780da1a3
parent1fb644d60cb864521e071870af3f448137581455 (diff)
parent73022d117ef1b2da1f6dcb0196021ea86c97f83d (diff)
downloadcython-e9036d3a820c072afc9e8a0d1b4221b3b9a87813.tar.gz
Merge branch '0.22.x' into release-candidate
-rw-r--r--CHANGES.rst2
-rw-r--r--Cython/Compiler/ExprNodes.py17
-rw-r--r--Cython/Compiler/ModuleNode.py5
-rw-r--r--Cython/Utility/Profile.c92
-rw-r--r--docs/src/userguide/buffer.rst10
-rwxr-xr-xruntests.py1
-rw-r--r--tests/bugs.txt2
-rw-r--r--tests/run/carray_coercion.pyx51
-rw-r--r--tests/run/coverage.srctree64
-rw-r--r--tests/run/numpy_math.pyx3
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.))