diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2017-08-25 09:39:58 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-08-25 09:39:58 +0200 |
commit | 98b60d8f59f845b9b33782e822b251ac083c7996 (patch) | |
tree | 31168c280925a04cd86f83e088a28648c11ce2a4 | |
parent | 8b80a6120707fed0adc9d4b31577ac107f5fb668 (diff) | |
parent | 570f187bfbd24842df32b719d77567968d131679 (diff) | |
download | cython-98b60d8f59f845b9b33782e822b251ac083c7996.tar.gz |
Merge branch 'master' into gen_exc_handling
-rw-r--r-- | Cython/Compiler/Annotate.py | 2 | ||||
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 4 | ||||
-rw-r--r-- | Cython/Compiler/Optimize.py | 8 | ||||
-rw-r--r-- | Cython/Compiler/ParseTreeTransforms.pxd | 9 | ||||
-rw-r--r-- | Cython/Compiler/ParseTreeTransforms.py | 11 | ||||
-rw-r--r-- | Cython/Compiler/Pipeline.py | 23 | ||||
-rw-r--r-- | Cython/Shadow.py | 7 | ||||
-rw-r--r-- | Cython/Utility/AsyncGen.c | 30 | ||||
-rw-r--r-- | Cython/Utility/Coroutine.c | 42 | ||||
-rw-r--r-- | Cython/Utility/TypeConversion.c | 4 | ||||
-rwxr-xr-x | runtests.py | 5 | ||||
-rw-r--r-- | tests/run/int_float_builtins_as_casts_T400.pyx | 42 |
12 files changed, 145 insertions, 42 deletions
diff --git a/Cython/Compiler/Annotate.py b/Cython/Compiler/Annotate.py index 7338271a8..33f68cd3b 100644 --- a/Cython/Compiler/Annotate.py +++ b/Cython/Compiler/Annotate.py @@ -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 diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 6c3ab189c..3982d637c 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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: diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index dcec5c8b1..109c49794 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -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 diff --git a/Cython/Compiler/ParseTreeTransforms.pxd b/Cython/Compiler/ParseTreeTransforms.pxd index 3b221a0c4..8e7862708 100644 --- a/Cython/Compiler/ParseTreeTransforms.pxd +++ b/Cython/Compiler/ParseTreeTransforms.pxd @@ -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 diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 85758d182..dc079e071 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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: diff --git a/Cython/Compiler/Pipeline.py b/Cython/Compiler/Pipeline.py index 51cf7e54d..c915becb6 100644 --- a/Cython/Compiler/Pipeline.py +++ b/Cython/Compiler/Pipeline.py @@ -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: diff --git a/Cython/Shadow.py b/Cython/Shadow.py index 0001fcd72..cc959014d 100644 --- a/Cython/Shadow.py +++ b/Cython/Shadow.py @@ -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() diff --git a/Cython/Utility/AsyncGen.c b/Cython/Utility/AsyncGen.c index 238fe4011..4539cc2f0 100644 --- a/Cython/Utility/AsyncGen.c +++ b/Cython/Utility/AsyncGen.c @@ -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; } diff --git a/Cython/Utility/Coroutine.c b/Cython/Utility/Coroutine.c index 942a4ac13..f12868cbc 100644 --- a/Cython/Utility/Coroutine.c +++ b/Cython/Utility/Coroutine.c @@ -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; @@ -942,11 +966,12 @@ static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject #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); diff --git a/Cython/Utility/TypeConversion.c b/Cython/Utility/TypeConversion.c index f81f8c91d..5fe69fc7e 100644 --- a/Cython/Utility/TypeConversion.c +++ b/Cython/Utility/TypeConversion.c @@ -338,7 +338,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { } #endif #else - res = PyNumber_Int(x); + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } #endif if (likely(res)) { #if PY_MAJOR_VERSION < 3 diff --git a/runtests.py b/runtests.py index 53b5d7cda..aa16d7bc5 100755 --- a/runtests.py +++ b/runtests.py @@ -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"), diff --git a/tests/run/int_float_builtins_as_casts_T400.pyx b/tests/run/int_float_builtins_as_casts_T400.pyx index a2210ea95..6d02eff36 100644 --- a/tests/run/int_float_builtins_as_casts_T400.pyx +++ b/tests/run/int_float_builtins_as_casts_T400.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 |