Commit 98b60d8f authored by Stefan Behnel's avatar Stefan Behnel

Merge branch 'master' into gen_exc_handling

parents 8b80a612 570f187b
......@@ -294,7 +294,7 @@ _parse_code = re.compile((
br'(?P<py_macro_api>Py[A-Z][a-z]+_[A-Z][A-Z_]+)|'
br'(?P<py_c_api>Py[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]*)'
br')(?=\()|' # look-ahead to exclude subsequent '(' from replacement
br'(?P<error_goto>(?:(?<=;) *if .* +)?\{__pyx_filename = .*goto __pyx_L\w+;\})'
br'(?P<error_goto>(?:(?<=;) *if [^;]* +)?__PYX_ERR\([^)]+\))'
).decode('ascii')).sub
......
......@@ -5376,7 +5376,7 @@ class SimpleCallNode(CallNode):
if formal_arg.not_none:
if self.self:
self.self = self.self.as_none_safe_node(
"'NoneType' object has no attribute '%s'",
"'NoneType' object has no attribute '%{0}s'".format('.30' if len(entry.name) <= 30 else ''),
error='PyExc_AttributeError',
format_args=[entry.name])
else:
......@@ -6758,7 +6758,7 @@ class AttributeNode(ExprNode):
format_args = ()
if (self.obj.type.is_extension_type and self.needs_none_check and not
self.is_py_attr):
msg = "'NoneType' object has no attribute '%s'"
msg = "'NoneType' object has no attribute '%{0}s'".format('.30' if len(self.attribute) <= 30 else '')
format_args = (self.attribute,)
elif self.obj.type.is_memoryviewslice:
if self.is_memslice_transpose:
......
......@@ -892,7 +892,7 @@ class IterationTransform(Visitor.EnvTransform):
method_node = ExprNodes.StringNode(
dict_obj.pos, is_identifier=True, value=method)
dict_obj = dict_obj.as_none_safe_node(
"'NoneType' object has no attribute '%s'",
"'NoneType' object has no attribute '%{0}s'".format('.30' if len(method) <= 30 else ''),
error = "PyExc_AttributeError",
format_args = [method])
else:
......@@ -2766,7 +2766,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
if is_list:
type_name = 'List'
obj = obj.as_none_safe_node(
"'NoneType' object has no attribute '%s'",
"'NoneType' object has no attribute '%.30s'",
error="PyExc_AttributeError",
format_args=['pop'])
else:
......@@ -3456,7 +3456,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
format_args=['decode', string_type.name])
else:
string_node = string_node.as_none_safe_node(
"'NoneType' object has no attribute '%s'",
"'NoneType' object has no attribute '%.30s'",
error="PyExc_AttributeError",
format_args=['decode'])
elif not string_type.is_string and not string_type.is_cpp_string:
......@@ -3653,7 +3653,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
format_args=[attr_name, function.obj.name])
else:
self_arg = self_arg.as_none_safe_node(
"'NoneType' object has no attribute '%s'",
"'NoneType' object has no attribute '%{0}s'".format('.30' if len(attr_name) <= 30 else ''),
error = "PyExc_AttributeError",
format_args = [attr_name])
args[0] = self_arg
......
......@@ -46,8 +46,10 @@ cdef class ExpandInplaceOperators(EnvTransform):
cdef class AlignFunctionDefinitions(CythonTransform):
cdef dict directives
cdef scope
cdef set imported_names
cdef object scope
@cython.final
cdef class YieldNodeCollector(TreeVisitor):
cdef public list yields
cdef public list returns
......@@ -57,15 +59,20 @@ cdef class YieldNodeCollector(TreeVisitor):
cdef public bint has_yield
cdef public bint has_await
@cython.final
cdef class MarkClosureVisitor(CythonTransform):
cdef bint needs_closure
@cython.final
cdef class CreateClosureClasses(CythonTransform):
cdef list path
cdef bint in_lambda
cdef module_scope
cdef generator_class
cdef create_class_from_scope(self, node, target_module_scope, inner_node=*)
cdef find_entries_used_in_closures(self, node)
cdef class GilCheck(VisitorTransform):
cdef list env_stack
cdef bint nogil
......
......@@ -611,9 +611,11 @@ class PxdPostParse(CythonTransform, SkipDeclarations):
else:
return node
class TrackNumpyAttributes(CythonTransform, SkipDeclarations):
def __init__(self, context):
super(TrackNumpyAttributes, self).__init__(context)
class TrackNumpyAttributes(VisitorTransform, SkipDeclarations):
# TODO: Make name handling as good as in InterpretCompilerDirectives() below - probably best to merge the two.
def __init__(self):
super(TrackNumpyAttributes, self).__init__()
self.numpy_module_names = set()
def visit_CImportStatNode(self, node):
......@@ -627,6 +629,9 @@ class TrackNumpyAttributes(CythonTransform, SkipDeclarations):
node.is_numpy_attribute = True
return node
visit_Node = VisitorTransform.recurse_to_children
class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
"""
After parsing, directives can be stored in a number of places:
......
......@@ -6,7 +6,6 @@ from time import time
from . import Errors
from . import DebugFlags
from . import Options
from .Visitor import CythonTransform
from .Errors import CompileError, InternalError, AbortError
from . import Naming
......@@ -183,7 +182,7 @@ def create_pipeline(context, mode, exclude_classes=()):
NormalizeTree(context),
PostParse(context),
_specific_post_parse,
TrackNumpyAttributes(context),
TrackNumpyAttributes(),
InterpretCompilerDirectives(context, context.compiler_directives),
ParallelRangeTransform(context),
AdjustDefByDirectives(context),
......@@ -324,8 +323,15 @@ def insert_into_pipeline(pipeline, transform, before=None, after=None):
# Running a pipeline
#
_pipeline_entry_points = {}
def run_pipeline(pipeline, source, printtree=True):
from .Visitor import PrintTree
exec_ns = globals().copy() if DebugFlags.debug_verbose_pipeline else None
def run(phase, data):
return phase(data)
error = None
data = source
......@@ -333,12 +339,19 @@ def run_pipeline(pipeline, source, printtree=True):
try:
for phase in pipeline:
if phase is not None:
if not printtree and isinstance(phase, PrintTree):
continue
if DebugFlags.debug_verbose_pipeline:
t = time()
print("Entering pipeline phase %r" % phase)
if not printtree and isinstance(phase, PrintTree):
continue
data = phase(data)
# create a new wrapper for each step to show the name in profiles
phase_name = getattr(phase, '__name__', type(phase).__name__)
try:
run = _pipeline_entry_points[phase_name]
except KeyError:
exec("def %s(phase, data): return phase(data)" % phase_name, exec_ns)
run = _pipeline_entry_points[phase_name] = exec_ns[phase_name]
data = run(phase, data)
if DebugFlags.debug_verbose_pipeline:
print(" %.3f seconds" % (time() - t))
except CompileError as err:
......
......@@ -422,10 +422,13 @@ void = typedef(int, "void")
for t in int_types + float_types + complex_types + other_types:
for i in range(1, 4):
gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i)
gs["%s_%s" % ('p'*i, t)] = gs[t]._pointer(i)
void = typedef(None, "void")
NULL = p_void(0)
NULL = gs['p_void'](0)
# looks like 'gs' has some users out there by now...
#del gs
integral = floating = numeric = _FusedType()
......
......@@ -13,8 +13,6 @@ typedef struct {
int ag_closed;
} __pyx_PyAsyncGenObject;
typedef struct __pyx_PyAsyncGenASend_struct __pyx_PyAsyncGenASend;
static PyTypeObject *__pyx__PyAsyncGenWrappedValueType = 0;
static PyTypeObject *__pyx__PyAsyncGenASendType = 0;
static PyTypeObject *__pyx__PyAsyncGenAThrowType = 0;
......@@ -23,10 +21,14 @@ static PyTypeObject *__pyx_AsyncGenType = 0;
#define __Pyx_AsyncGen_CheckExact(obj) (Py_TYPE(obj) == __pyx_AsyncGenType)
#define __pyx_PyAsyncGenASend_CheckExact(o) \
(Py_TYPE(o) == __pyx__PyAsyncGenASendType)
#define __pyx_PyAsyncGenAThrow_CheckExact(o) \
(Py_TYPE(o) == __pyx__PyAsyncGenAThrowType)
static PyObject *__Pyx_async_gen_anext(__pyx_PyAsyncGenObject *o);
static CYTHON_INLINE PyObject *__Pyx_async_gen_asend_iternext(__pyx_PyAsyncGenASend *o);
static PyObject *__Pyx_async_gen_asend_send(__pyx_PyAsyncGenASend *o, PyObject *arg);
static PyObject *__Pyx_async_gen_anext(PyObject *o);
static CYTHON_INLINE PyObject *__Pyx_async_gen_asend_iternext(PyObject *o);
static PyObject *__Pyx_async_gen_asend_send(PyObject *o, PyObject *arg);
static PyObject *__Pyx_async_gen_asend_close(PyObject *o, PyObject *args);
static PyObject *__Pyx_async_gen_athrow_close(PyObject *o, PyObject *args);
static PyObject *__Pyx__PyAsyncGenValueWrapperNew(PyObject *val);
......@@ -131,7 +133,7 @@ typedef enum {
__PYX_AWAITABLE_STATE_CLOSED, /* closed */
} __pyx_AwaitableState;
struct __pyx_PyAsyncGenASend_struct {
typedef struct {
PyObject_HEAD
__pyx_PyAsyncGenObject *ags_gen;
......@@ -139,7 +141,7 @@ struct __pyx_PyAsyncGenASend_struct {
PyObject *ags_sendval;
__pyx_AwaitableState ags_state;
};
} __pyx_PyAsyncGenASend;
typedef struct {
......@@ -237,8 +239,9 @@ __Pyx_async_gen_init_hooks(__pyx_PyAsyncGenObject *o)
static PyObject *
__Pyx_async_gen_anext(__pyx_PyAsyncGenObject *o)
__Pyx_async_gen_anext(PyObject *g)
{
__pyx_PyAsyncGenObject *o = (__pyx_PyAsyncGenObject*) g;
if (__Pyx_async_gen_init_hooks(o)) {
return NULL;
}
......@@ -478,8 +481,9 @@ __Pyx_async_gen_asend_traverse(__pyx_PyAsyncGenASend *o, visitproc visit, void *
static PyObject *
__Pyx_async_gen_asend_send(__pyx_PyAsyncGenASend *o, PyObject *arg)
__Pyx_async_gen_asend_send(PyObject *g, PyObject *arg)
{
__pyx_PyAsyncGenASend *o = (__pyx_PyAsyncGenASend*) g;
PyObject *result;
if (unlikely(o->ags_state == __PYX_AWAITABLE_STATE_CLOSED)) {
......@@ -506,7 +510,7 @@ __Pyx_async_gen_asend_send(__pyx_PyAsyncGenASend *o, PyObject *arg)
static CYTHON_INLINE PyObject *
__Pyx_async_gen_asend_iternext(__pyx_PyAsyncGenASend *o)
__Pyx_async_gen_asend_iternext(PyObject *o)
{
return __Pyx_async_gen_asend_send(o, Py_None);
}
......@@ -534,8 +538,9 @@ __Pyx_async_gen_asend_throw(__pyx_PyAsyncGenASend *o, PyObject *args)
static PyObject *
__Pyx_async_gen_asend_close(__pyx_PyAsyncGenASend *o, CYTHON_UNUSED PyObject *args)
__Pyx_async_gen_asend_close(PyObject *g, CYTHON_UNUSED PyObject *args)
{
__pyx_PyAsyncGenASend *o = (__pyx_PyAsyncGenASend*) g;
o->ags_state = __PYX_AWAITABLE_STATE_CLOSED;
Py_RETURN_NONE;
}
......@@ -920,8 +925,9 @@ __Pyx_async_gen_athrow_iternext(__pyx_PyAsyncGenAThrow *o)
static PyObject *
__Pyx_async_gen_athrow_close(__pyx_PyAsyncGenAThrow *o, CYTHON_UNUSED PyObject *args)
__Pyx_async_gen_athrow_close(PyObject *g, CYTHON_UNUSED PyObject *args)
{
__pyx_PyAsyncGenAThrow *o = (__pyx_PyAsyncGenAThrow*) g;
o->agt_state = __PYX_AWAITABLE_STATE_CLOSED;
Py_RETURN_NONE;
}
......
......@@ -90,7 +90,7 @@ static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject
#ifdef __Pyx_AsyncGen_USED
// inlined "__pyx_PyAsyncGenASend" handling to avoid the series of generic calls below
} else if (__pyx_PyAsyncGenASend_CheckExact(source)) {
retval = __Pyx_async_gen_asend_iternext((__pyx_PyAsyncGenASend *)source);
retval = __Pyx_async_gen_asend_iternext(source);
if (retval) {
Py_INCREF(source);
gen->yieldfrom = source;
......@@ -299,7 +299,7 @@ static PyObject *__Pyx__Coroutine_AsyncIterNext(PyObject *obj) {
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *obj) {
#ifdef __Pyx_AsyncGen_USED
if (__Pyx_AsyncGen_CheckExact(obj)) {
return __Pyx_async_gen_anext((__pyx_PyAsyncGenObject*) obj);
return __Pyx_async_gen_anext(obj);
}
#endif
#if CYTHON_USE_ASYNC_SLOTS
......@@ -422,6 +422,7 @@ static CYTHON_INLINE void __Pyx__Coroutine_ResetFrameBackpointer(PyThreadState *
static PyTypeObject *__pyx_CoroutineType = 0;
static PyTypeObject *__pyx_CoroutineAwaitType = 0;
#define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType)
#define __Pyx_CoroutineAwait_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineAwaitType)
#define __Pyx_Coroutine_New(body, closure, name, qualname, module_name) \
__Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname, module_name)
......@@ -429,6 +430,14 @@ static PyTypeObject *__pyx_CoroutineAwaitType = 0;
static int __pyx_Coroutine_init(void); /*proto*/
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
typedef struct {
PyObject_HEAD
PyObject *coroutine;
} __pyx_CoroutineAwaitObject;
static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self); /*proto*/
static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args); /*proto*/
//////////////////// Generator.proto ////////////////////
......@@ -758,7 +767,7 @@ static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
#endif
#ifdef __Pyx_AsyncGen_USED
if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
ret = __Pyx_async_gen_asend_send((__pyx_PyAsyncGenASend *)yf, value);
ret = __Pyx_async_gen_asend_send(yf, value);
} else
#endif
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000
......@@ -808,6 +817,21 @@ static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
if (!retval)
return -1;
} else
if (__Pyx_CoroutineAwait_CheckExact(yf)) {
retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf);
if (!retval)
return -1;
} else
#endif
#ifdef __Pyx_AsyncGen_USED
if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
retval = __Pyx_async_gen_asend_close(yf, NULL);
// cannot fail
} else
if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) {
retval = __Pyx_async_gen_athrow_close(yf, NULL);
// cannot fail
} else
#endif
{
PyObject *meth;
......@@ -941,12 +965,13 @@ static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject
#endif
#ifdef __Pyx_Coroutine_USED
|| __Pyx_Coroutine_CheckExact(yf)
#endif
#ifdef __Pyx_AsyncGen_USED
|| __Pyx_AsyncGen_CheckExact(yf)
#endif
) {
ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit);
#ifdef __Pyx_Coroutine_USED
} else if (__Pyx_CoroutineAwait_CheckExact(yf)) {
ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
#endif
} else {
PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
if (unlikely(!meth)) {
......@@ -1303,11 +1328,6 @@ static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
//@requires: CoroutineBase
//@requires: PatchGeneratorABC
typedef struct {
PyObject_HEAD
PyObject *coroutine;
} __pyx_CoroutineAwaitObject;
static void __Pyx_CoroutineAwait_dealloc(PyObject *self) {
PyObject_GC_UnTrack(self);
Py_CLEAR(((__pyx_CoroutineAwaitObject*)self)->coroutine);
......
......@@ -338,7 +338,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) {
}
#endif
#else
if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) {
res = PyNumber_Int(x);
}
#endif
if (likely(res)) {
#if PY_MAJOR_VERSION < 3
......
......@@ -1994,6 +1994,11 @@ def runtests(options, cmd_args, coverage=None):
compiler_default_options['gdb_debug'] = True
compiler_default_options['output_dir'] = os.getcwd()
if IS_PYPY:
if options.with_refnanny:
sys.stderr.write("Disabling refnanny in PyPy\n")
options.with_refnanny = False
if options.with_refnanny:
from pyximport.pyxbuild import pyx_to_dll
libpath = pyx_to_dll(os.path.join("Cython", "Runtime", "refnanny.pyx"),
......
......@@ -10,6 +10,9 @@ def double_to_short_int(double x):
4
>>> double_to_short_int(4)
4
>>> double_to_short_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef short r = int(x)
return r
......@@ -22,6 +25,9 @@ def double_to_pyssizet_int(double x):
4
>>> double_to_pyssizet_int(4)
4
>>> double_to_pyssizet_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef Py_ssize_t r = int(x)
return r
......@@ -34,6 +40,9 @@ def int_to_pyssizet_int(int x):
4
>>> int_to_pyssizet_int(4)
4
>>> int_to_pyssizet_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef Py_ssize_t r = int(x)
return r
......@@ -56,6 +65,9 @@ def int_to_short_int(int x):
"""
>>> int_to_short_int(4)
4
>>> int_to_short_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...integer...
"""
cdef short r = int(x)
return r
......@@ -66,6 +78,9 @@ def short_to_float_float(short x):
"""
>>> short_to_float_float(4)
4.0
>>> short_to_float_float('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...integer...
"""
cdef float r = float(x)
return r
......@@ -76,6 +91,9 @@ def short_to_double_float(short x):
"""
>>> short_to_double_float(4)
4.0
>>> short_to_double_float('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...integer...
"""
cdef double r = float(x)
return r
......@@ -86,6 +104,9 @@ def short_to_double_int(short x):
"""
>>> short_to_double_int(4)
4.0
>>> short_to_double_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...integer...
"""
cdef double r = int(x)
return r
......@@ -97,6 +118,9 @@ def float_to_float_float(float x):
True
>>> float_to_float_float(4)
4.0
>>> float_to_float_float('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef float r = float(x)
return r
......@@ -109,6 +133,9 @@ def double_to_double_float(double x):
True
>>> double_to_double_float(4)
4.0
>>> double_to_double_float('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef double r = float(x)
return r
......@@ -123,6 +150,9 @@ def double_to_py_int(double x):
4
>>> double_to_py_int(4)
4
>>> double_to_py_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
return int(x)
......@@ -134,6 +164,9 @@ def double_to_double_int(double x):
4.0
>>> double_to_double_int(4)
4.0
>>> double_to_double_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef double r = int(x)
return r
......@@ -150,6 +183,9 @@ def float_to_float_int(float x):
4.0
>>> float_to_float_int(4)
4.0
>>> float_to_float_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef float r = int(x)
return r
......@@ -166,6 +202,9 @@ def float_to_double_int(float x):
4.0
>>> float_to_double_int(4)
4.0
>>> float_to_double_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef double r = int(x)
return r
......@@ -182,6 +221,9 @@ def double_to_float_int(double x):
4.0
>>> double_to_float_int(4)
4.0
>>> double_to_float_int('4') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
cdef float r = int(x)
return r
......
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