Commit a261a911 authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'master' into 0.20.x

parents bbd49a35 8ce5dbcb
......@@ -23,6 +23,9 @@ Features added
* Constant Python float values are cached.
* String/Unicode formatting using the '%' operator uses a faster
C-API call.
* ``bytearray`` has become a known type and supports coercion from and
to C strings. Indexing, slicing and decoding is optimised. Note that
this may have an impact on existing code due to type inference.
......@@ -64,6 +67,9 @@ Features added
oft-used utility code once in a separate directory rather than as
part of each generated file.
* ``unraisable_tracebacks`` directive added to control printing of
tracebacks of unraisable exceptions.
Bugs fixed
----------
......
......@@ -2077,9 +2077,10 @@ class CCodeWriter(object):
Naming.clineno_cname,
Naming.lineno_cname,
Naming.filename_cname,
int(self.globalstate.directives['unraisable_tracebacks'])
)
self.funcstate.uses_error_indicator = True
self.putln('__Pyx_WriteUnraisable("%s", %s, %s, %s);' % format_tuple)
self.putln('__Pyx_WriteUnraisable("%s", %s, %s, %s, %s);' % format_tuple)
self.globalstate.use_utility_code(
UtilityCode.load_cached("WriteUnraisableException", "Exceptions.c"))
......
......@@ -2538,6 +2538,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
'__releasebuffer__')
if (func.is_special and Options.docstrings and
func.wrapperbase_cname and not is_buffer):
slot = TypeSlots.method_name_to_slot[func.name]
preprocessor_guard = slot.preprocessor_guard_code()
if preprocessor_guard:
code.putln(preprocessor_guard)
code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
code.putln("{")
code.putln(
......@@ -2558,6 +2562,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("}")
code.putln("}")
code.putln('#endif')
if preprocessor_guard:
code.putln('#endif')
if type.vtable_cname:
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
......
......@@ -1245,7 +1245,9 @@ class CVarDefNode(StatNode):
if (len(self.declarators) > 1
and not isinstance(declarator, CNameDeclaratorNode)
and env.directives['warn.multiple_declarators']):
warning(declarator.pos, "Non-trivial type declarators in shared declaration.", 1)
warning(declarator.pos,
"Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). " +
"Each pointer declaration should be on its own line.", 1)
if isinstance(declarator, CFuncDeclaratorNode):
name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
......
......@@ -112,6 +112,7 @@ directive_defaults = {
'c_string_type': 'bytes',
'c_string_encoding': '',
'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types
'unraisable_tracebacks': False,
# set __file__ and/or __path__ to known source/target path at import time (instead of not having them available)
'set_initial_path' : None, # SOURCEFILE or "/full/path/to/module"
......
......@@ -6,6 +6,7 @@ import DebugFlags
import Options
from Visitor import CythonTransform
from Errors import CompileError, InternalError, AbortError
import Naming
#
# Really small pipeline stages
......@@ -279,6 +280,9 @@ def create_pyx_as_pxd_pipeline(context, result):
for entry in root.scope.entries.values():
if not entry.in_cinclude:
entry.defined_in_pxd = 1
if entry.name == entry.cname and entry.visibility != 'extern':
# Always mangle non-extern cimported entries.
entry.cname = entry.scope.mangle(Naming.func_prefix, entry.name)
return StatListNode(root.pos, stats=[]), root.scope
pipeline.append(fake_pxd)
return pipeline
......
......@@ -417,16 +417,22 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
/////////////// WriteUnraisableException.proto ///////////////
static void __Pyx_WriteUnraisable(const char *name, int clineno,
int lineno, const char *filename); /*proto*/
int lineno, const char *filename,
int full_traceback); /*proto*/
/////////////// WriteUnraisableException ///////////////
//@requires: PyErrFetchRestore
static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename) {
CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
int full_traceback) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
__Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
if (full_traceback) {
__Pyx_ErrRestore(old_exc, old_val, old_tb);
PyErr_PrintEx(1);
}
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name);
#else
......
......@@ -695,13 +695,18 @@ static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyO
PyErr_SetString(PyExc_ValueError, "string must be of size 1");
return -1;
}
ival = PyString_AS_STRING(value)[0];
ival = (unsigned char) (PyString_AS_STRING(value)[0]);
} else
#endif
{
// CPython calls PyNumber_Index() internally
ival = __Pyx_PyIndex_AsSsize_t(value);
if (unlikely(ival == -1 && PyErr_Occurred()))
if (unlikely((ival < 0) | (ival > 255))) {
if (ival == -1 && PyErr_Occurred())
return -1;
PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
return -1;
}
}
return __Pyx_PyByteArray_Append(bytearray, ival);
}
......@@ -713,7 +718,6 @@ static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value
//////////////////// ByteArrayAppend ////////////////////
//@requires: ObjectHandling.c::PyObjectCallMethod
// signature uses Py_ssize_t to make coercions use PyNumber_Index(), as CPython does
static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value) {
PyObject *pyval, *retval;
#if CYTHON_COMPILING_IN_CPYTHON
......
......@@ -276,11 +276,34 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
return res;
}
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
#include "longintrepr.h"
#endif
#endif
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject *x;
#if PY_MAJOR_VERSION < 3
if (likely(PyInt_CheckExact(b)))
return PyInt_AS_LONG(b);
#endif
if (likely(PyLong_CheckExact(b))) {
#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
#if CYTHON_USE_PYLONG_INTERNALS
switch (Py_SIZE(b)) {
case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
case 0: return 0;
case 1: return ((PyLongObject*)b)->ob_digit[0];
}
#endif
#endif
#if PY_VERSION_HEX < 0x02060000
return PyInt_AsSsize_t(b);
#else
return PyLong_AsSsize_t(b);
#endif
}
x = PyNumber_Index(b);
if (!x) return -1;
ival = PyInt_AsSsize_t(x);
......
......@@ -363,6 +363,9 @@ Cython code. Here is the list of currently supported directives:
internally without paying attention to cache consistency, this option can
be set to False.
``unraisable_tracebacks`` (True / False)
Whether to print tracebacks when suppressing unraisable exceptions.
How to set directives
---------------------
......
......@@ -26,7 +26,7 @@ main new features of Cython v0.13 regarding C++ support:
* C++ objects can now be dynamically allocated with ``new`` and ``del`` keywords.
* C++ objects can be stack-allocated.
* C++ classes can be declared with the new keyword ``cppclass``.
* Templated classes are supported.
* Templated classes and functions are supported.
* Overloaded functions are supported.
* Overloading of C++ operators (such as operator+, operator[],...) is supported.
......@@ -388,7 +388,15 @@ Cython uses a bracket syntax for templating. A simple example for wrapping C++ v
del v
Multiple template parameters can be defined as a list, such as [T, U, V]
or [int, bool, char].
or [int, bool, char]. Template functions are defined similarly, with
the template parameter list following the function name::
cdef extern from "<algorithm>" namespace "std":
T max[T](T a, T b)
print max[long](3, 4)
print max(1.5, 2.5) # simple template argument deduction
Standard library
-----------------
......
......@@ -448,6 +448,9 @@ class TestBuilder(object):
continue
if filename.startswith('.'):
continue # certain emacs backup files
if context == 'pyregr':
tags = defaultdict(list)
else:
tags = parse_tags(filepath)
fqmodule = "%s.%s" % (context, module)
if not [ 1 for match in self.selectors
......
......@@ -21,7 +21,7 @@ cdef class C:
def __set__(self, x):
"And here is another one."
def __add__(self, other):
def __div__(self, other):
"usable docstring"
def __iter__(self):
"usable docstring"
......
......@@ -26,6 +26,16 @@ See also:
import numpy as np
numpy_version = np.__version__.split('.')[:2]
try:
numpy_version = tuple(map(int, numpy_version))
except ValueError:
numpy_version = (20, 0)
NUMPY_HAS_RELAXED_STRIDES = (
numpy_version < (1, 8) or
np.ones((10, 1), order="C").flags.f_contiguous)
def test_one_sized(array):
"""
......@@ -33,7 +43,8 @@ def test_one_sized(array):
>>> test_one_sized(contig)[0]
1.0
>>> a = np.arange(10, dtype=np.double)[::100]
>>> test_one_sized(a)[0]
>>> if NUMPY_HAS_RELAXED_STRIDES: print(test_one_sized(a)[0])
... else: print(1.0)
1.0
"""
cdef double[::1] a = array
......@@ -47,7 +58,7 @@ def test_zero_sized(array):
>>> _ = test_zero_sized(contig)
>>> a = np.arange(10, dtype=np.double)[100:200:10]
>>> _ = test_zero_sized(a)
>>> if NUMPY_HAS_RELAXED_STRIDES: _ = test_zero_sized(a)
"""
cdef double[::1] a = array
return a
......@@ -211,6 +211,21 @@ def bytearray_append(bytearray b, char c, int i, object o):
>>> print(b.decode('ascii'))
abcXxyz
>>> b = bytearray(b'abc')
>>> b = bytearray_append(b, ord('x'), ord('y'), ord('\\xc3') if IS_PY3 else b'\\xc3')
>>> print(b[:-1].decode('ascii'))
abcXxy
>>> print('%x' % b[-1])
c3
>>> b = bytearray(b'abc')
>>> try:
... b = bytearray_append(b, ord('x'), ord('y'), b'zz')
... except (TypeError, ValueError): pass # (Py3, Py2)
... else: print("FAIL")
>>> print(b.decode('ascii'))
abcXxy
>>> b = bytearray(b'abc')
>>> b = bytearray_append(b, -1, ord('y'), ord('z')) # doctest: +ELLIPSIS
Traceback (most recent call last):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment