Commit 416e3293 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents ae714eac 04c2f16b
......@@ -17,3 +17,4 @@ af6f1bed8cd40a2edefb57d3eacbc9274a8788b4 0.11.2.rc1
15ad532e2127840ae09dfbe46ccc80ac8c562f99 0.11.2
eb00d00a73c13b6aa8b440fe07cd7acb52a060e8 0.11.3.rc0
7c695fe49fd6912f52d995fe512d66baacf90ee6 0.11.3
4208042ceeae634f5c0999b8ab75f69faf46b6db 0.12.alpha0
......@@ -245,8 +245,9 @@ def put_acquire_arg_buffer(entry, code, pos):
# need to care about the buffer then.
put_unpack_buffer_aux_into_scope(buffer_aux, entry.type.mode, code)
def get_release_buffer_code(entry):
return "__Pyx_SafeReleaseBuffer(&%s)" % entry.buffer_aux.buffer_info_var.cname
def put_release_buffer_code(code, entry):
code.globalstate.use_utility_code(acquire_utility_code)
code.putln("__Pyx_SafeReleaseBuffer(&%s);" % entry.buffer_aux.buffer_info_var.cname)
def get_getbuffer_call(code, obj_cname, buffer_aux, buffer_type):
ndim = buffer_type.ndim
......
......@@ -17,7 +17,6 @@ Options:
-I, --include-dir <directory> Search for include files in named directory
(multiply include directories are allowed).
-o, --output-file <filename> Specify name of generated C file
-r, --recursive Recursively find and compile dependencies
-t, --timestamps Only compile newer source files (implied with -r)
-f, --force Compile all source files (overrides implied -t)
-q, --quiet Don't print module names in recursive mode
......@@ -40,6 +39,10 @@ Options:
-X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
"""
# The following is broken http://trac.cython.org/cython_trac/ticket/379
# -r, --recursive Recursively find and compile dependencies
#The following experimental options are supported only on MacOSX:
# -C, --compile Compile generated .c file to .o file
# --link Link .o file to produce extension module (implies -C)
......
......@@ -408,8 +408,10 @@ class GlobalState(object):
code_layout = [
'h_code',
'utility_code_proto_before_types',
'type_declarations',
'utility_code_proto',
'numeric_typedefs', # Let these detailed individual parts stay!,
'complex_type_declarations', # as the proper solution is to make a full DAG...
'type_declarations', # More coarse-grained blocks would simply hide
'utility_code_proto', # the ugliness, not fix it
'module_declarations',
'typeinfo',
'before_global_var',
......
......@@ -2572,7 +2572,7 @@ class SimpleCallNode(CallNode):
for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
code.putln("%s.%s = %s;" % (
self.opt_arg_struct,
formal_arg.name,
func_type.opt_arg_cname(formal_arg.name),
actual_arg.result_as(formal_arg.type)))
exc_checks = []
if self.type.is_pyobject:
......@@ -5601,6 +5601,7 @@ class CoercionNode(ExprNode):
# arg ExprNode node being coerced
subexprs = ['arg']
constant_result = not_a_constant
def __init__(self, arg):
self.pos = arg.pos
......
......@@ -658,8 +658,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_typedef(self, entry, code):
base_type = entry.type.typedef_base_type
code.putln("")
code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
if base_type.is_numeric:
writer = code.globalstate['numeric_typedefs']
else:
writer = code
writer.putln("")
writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
def sue_header_footer(self, type, kind, name):
if type.typedef_flag:
......
......@@ -1179,8 +1179,8 @@ class FuncDefNode(StatNode, BlockNode):
code.globalstate.use_utility_code(restore_exception_utility_code)
code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
for entry in lenv.buffer_entries:
code.putln("%s;" % Buffer.get_release_buffer_code(entry))
for entry in lenv.buffer_entries:
Buffer.put_release_buffer_code(code, entry)
#code.putln("%s = 0;" % entry.cname)
code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
......@@ -1222,7 +1222,7 @@ class FuncDefNode(StatNode, BlockNode):
code.put_label(code.return_label)
for entry in lenv.buffer_entries:
if entry.used:
code.putln("%s;" % Buffer.get_release_buffer_code(entry))
Buffer.put_release_buffer_code(code, entry)
if is_getbuffer_slot:
self.getbuffer_normal_cleanup(code)
# ----- Return cleanup for both error and no-error return
......@@ -1519,13 +1519,11 @@ class CFuncDefNode(FuncDefNode):
code.putln('if (%s) {' % Naming.optional_args_cname)
for arg in self.args:
if arg.default:
# FIXME: simple name prefixing doesn't work when
# argument name mangling is in place
code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
declarator = arg.declarator
while not hasattr(declarator, 'name'):
declarator = declarator.base
code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
i += 1
for _ in range(self.type.optional_arg_count):
code.putln('}')
......
......@@ -7,6 +7,7 @@ import UtilNodes
import TypeSlots
import Symtab
import Options
import Naming
from Code import UtilityCode
from StringEncoding import EncodedString, BytesLiteral
......@@ -755,7 +756,9 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
### cleanup to avoid redundant coercions to/from Python types
def visit_PyTypeTestNode(self, node):
def _visit_PyTypeTestNode(self, node):
# disabled - appears to break assignments in some cases, and
# also drops a None check, which might still be required
"""Flatten redundant type checks after tree changes.
"""
old_arg = node.arg
......@@ -832,6 +835,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
else:
return function_handler(node, arg_tuple)
elif function.is_attribute:
attr_name = function.attribute
arg_list = arg_tuple.args
self_arg = function.obj
obj_type = self_arg.type
......@@ -849,9 +853,14 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
else:
type_name = "object" # safety measure
method_handler = self._find_handler(
"method_%s_%s" % (type_name, function.attribute), kwargs)
"method_%s_%s" % (type_name, attr_name), kwargs)
if method_handler is None:
return node
if attr_name in TypeSlots.method_name_to_slot \
or attr_name == '__new__':
method_handler = self._find_handler(
"slot%s" % attr_name, kwargs)
if method_handler is None:
return node
if self_arg is not None:
arg_list = [self_arg] + list(arg_list)
if kwargs:
......@@ -1030,6 +1039,51 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
)
return node
### special methods
Pyx_tp_new_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("type", Builtin.type_type, None)
])
def _handle_simple_slot__new__(self, node, args, is_unbound_method):
"""Replace 'exttype.__new__(exttype)' by a call to exttype->tp_new()
"""
obj = node.function.obj
if not is_unbound_method or len(args) != 1:
return node
type_arg = args[0]
if not obj.is_name or not type_arg.is_name:
# play safe
return node
if obj.type != Builtin.type_type or type_arg.type != Builtin.type_type:
# not a known type, play safe
return node
if not type_arg.type_entry or not obj.type_entry:
if obj.name != type_arg.name:
return node
# otherwise, we know it's a type and we know it's the same
# type for both - that should do
elif type_arg.type_entry != obj.type_entry:
# different types - may or may not lead to an error at runtime
return node
# FIXME: we could potentially look up the actual tp_new C method
# of the extension type and call that instead of the generic slot
if not type_arg.type_entry:
# arbitrary variable, needs a None check for safety
type_arg = ExprNodes.NoneCheckNode(
type_arg, "PyExc_TypeError",
"object.__new__(X): X is not a type object (NoneType)")
return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_tp_new", self.Pyx_tp_new_func_type,
args = [type_arg],
utility_code = tpnew_utility_code,
is_temp = node.is_temp
)
### methods of builtin types
PyObject_Append_func_type = PyrexTypes.CFuncType(
......@@ -1050,6 +1104,40 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
utility_code = append_utility_code
)
PyObject_Pop_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None),
])
PyObject_PopIndex_func_type = PyrexTypes.CFuncType(
PyrexTypes.py_object_type, [
PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_long_type, None),
])
def _handle_simple_method_object_pop(self, node, args, is_unbound_method):
# X.pop([n]) is almost always referring to a list
if len(args) == 1:
return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_PyObject_Pop", self.PyObject_Pop_func_type,
args = args,
is_temp = node.is_temp,
utility_code = pop_utility_code
)
elif len(args) == 2:
if isinstance(args[1], ExprNodes.CoerceToPyTypeNode) and args[1].arg.type.is_int:
original_type = args[1].arg.type
if PyrexTypes.widest_numeric_type(original_type, PyrexTypes.c_py_ssize_t_type) == PyrexTypes.c_py_ssize_t_type:
args[1] = args[1].arg
return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_PyObject_PopIndex", self.PyObject_PopIndex_func_type,
args = args,
is_temp = node.is_temp,
utility_code = pop_index_utility_code
)
return node
PyList_Append_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_int_type, [
PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None),
......@@ -1306,6 +1394,76 @@ impl = ""
)
pop_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
if (likely(PyList_CheckExact(L))
/* Check that both the size is positive and no reallocation shrinking needs to be done. */
&& likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
Py_SIZE(L) -= 1;
return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
}
else {
PyObject *r, *m;
m = __Pyx_GetAttrString(L, "pop");
if (!m) return NULL;
r = PyObject_CallObject(m, NULL);
Py_DECREF(m);
return r;
}
}
""",
impl = ""
)
pop_index_utility_code = UtilityCode(
proto = """
static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix);
""",
impl = """
static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
PyObject *r, *m, *t, *py_ix;
if (likely(PyList_CheckExact(L))) {
Py_ssize_t size = PyList_GET_SIZE(L);
if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
if (ix < 0) {
ix += size;
}
if (likely(0 <= ix && ix < size)) {
Py_ssize_t i;
PyObject* v = PyList_GET_ITEM(L, ix);
Py_SIZE(L) -= 1;
size -= 1;
for(i=ix; i<size; i++) {
PyList_SET_ITEM(L, i, PyList_GET_ITEM(L, i+1));
}
return v;
}
}
}
py_ix = t = NULL;
m = __Pyx_GetAttrString(L, "pop");
if (!m) goto bad;
py_ix = PyInt_FromSsize_t(ix);
if (!py_ix) goto bad;
t = PyTuple_New(1);
if (!t) goto bad;
PyTuple_SET_ITEM(t, 0, py_ix);
py_ix = NULL;
r = PyObject_CallObject(m, t);
Py_DECREF(m);
Py_DECREF(t);
return r;
bad:
Py_XDECREF(m);
Py_XDECREF(t);
Py_XDECREF(py_ix);
return NULL;
}
"""
)
pytype_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_Type(PyObject* o) {
......@@ -1317,6 +1475,16 @@ static INLINE PyObject* __Pyx_Type(PyObject* o) {
)
tpnew_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) {
return (PyObject*) (((PyTypeObject*)(type_obj))->tp_new(
(PyTypeObject*)(type_obj), %(TUPLE)s, NULL));
}
""" % {'TUPLE' : Naming.empty_tuple}
)
class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
"""Calculate the result of constant expressions to store it in
``expr_node.constant_result``, and replace trivial cases by their
......
......@@ -871,17 +871,34 @@ class CComplexType(CNumericType):
scope = None
def __init__(self, real_type):
while real_type.is_typedef and not real_type.typedef_is_external:
real_type = real_type.typedef_base_type
if real_type.is_typedef and real_type.typedef_is_external:
# The below is not actually used: Coercions are currently disabled
# so that complex types of external types can not be created
self.funcsuffix = "_%s" % real_type.specalization_name()
elif hasattr(real_type, 'math_h_modifier'):
self.funcsuffix = real_type.math_h_modifier
else:
self.funcsuffix = "_%s" % real_type.specalization_name()
self.real_type = real_type
CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
self.binops = {}
self.from_parts = "%s_from_parts" % self.specalization_name()
self.default_value = "%s(0, 0)" % self.from_parts
def __eq__(self, other):
if isinstance(self, CComplexType) and isinstance(other, CComplexType):
return self.real_type == other.real_type
else:
return False
def __ne__(self, other):
if isinstance(self, CComplexType) and isinstance(other, CComplexType):
return self.real_type != other.real_type
else:
return True
def __lt__(self, other):
if isinstance(self, CComplexType) and isinstance(other, CComplexType):
......@@ -893,7 +910,7 @@ class CComplexType(CNumericType):
def __hash__(self):
return ~hash(self.real_type)
def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0):
if for_display:
......@@ -907,6 +924,14 @@ class CComplexType(CNumericType):
real_type_name = real_type_name.replace('long__double','long_double')
return Naming.type_prefix + real_type_name + "_complex"
def assignable_from(self, src_type):
# Temporary hack/feature disabling, see #441
if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
and src_type.typedef_is_external):
return False
else:
return super(CComplexType, self).assignable_from(src_type)
def assignable_from_resolved_type(self, src_type):
return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
......@@ -927,7 +952,7 @@ class CComplexType(CNumericType):
CFuncType(self, [CFuncTypeArg("self", self, None)]),
pos=None,
defining=1,
cname="__Pyx_c_conj%s" % self.real_type.math_h_modifier)
cname="__Pyx_c_conj%s" % self.funcsuffix)
return True
......@@ -943,7 +968,7 @@ class CComplexType(CNumericType):
utility_code.specialize(
self,
real_type = self.real_type.declaration_code(''),
m = self.real_type.math_h_modifier))
m = self.funcsuffix))
return True
def create_to_py_utility_code(self, env):
......@@ -960,7 +985,7 @@ class CComplexType(CNumericType):
utility_code.specialize(
self,
real_type = self.real_type.declaration_code(''),
m = self.real_type.math_h_modifier))
m = self.funcsuffix))
self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
return True
......@@ -971,8 +996,7 @@ class CComplexType(CNumericType):
pass
try:
op_name = complex_ops[nargs, op]
modifier = self.real_type.math_h_modifier
self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, modifier)
self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
return func_name
except KeyError:
return None
......@@ -1032,7 +1056,7 @@ proto="""
""")
complex_type_utility_code = UtilityCode(
proto_block='utility_code_proto_before_types',
proto_block='complex_type_declarations',
proto="""
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
......@@ -1113,7 +1137,7 @@ proto="""
#define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
#define __Pyx_c_neg%(m)s(a) (-(a))
#ifdef __cplusplus
#define __Pyx_c_is_zero%(m)s(z) ((z)==0.0)
#define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0)
#define __Pyx_c_conj%(m)s(z) (::std::conj(z))
/*#define __Pyx_c_abs%(m)s(z) (::std::abs(z))*/
#else
......@@ -1191,7 +1215,6 @@ impl="""
#endif
""")
class CArrayType(CType):
# base_type CType Element type
# size integer or None Number of elements
......@@ -1512,6 +1535,9 @@ class CFuncType(CType):
def signature_cast_string(self):
s = self.declaration_code("(*)", with_calling_convention=False)
return '(%s)' % s
def opt_arg_cname(self, arg_name):
return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
class CFuncTypeArg(object):
......
version = '0.11.3'
version = '0.12.alpha0'
......@@ -16,7 +16,7 @@ include Demos/embed/*
include Demos/freeze/*
include Demos/Setup.py
include Demos/Makefile*
include Tools/*
recursive-include Tools *
recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt
include runtests.py
......
......@@ -3,6 +3,7 @@
import os
import sys
import re
import gc
import codecs
import shutil
import unittest
......@@ -99,7 +100,7 @@ class ErrorWriter(object):
class TestBuilder(object):
def __init__(self, rootdir, workdir, selectors, exclude_selectors, annotate,
cleanup_workdir, cleanup_sharedlibs, with_pyregr, cython_only,
languages, test_bugs):
languages, test_bugs, fork):
self.rootdir = rootdir
self.workdir = workdir
self.selectors = selectors
......@@ -111,6 +112,7 @@ class TestBuilder(object):
self.cython_only = cython_only
self.languages = languages
self.test_bugs = test_bugs
self.fork = fork
def build_suite(self):
suite = unittest.TestSuite()
......@@ -192,12 +194,13 @@ class TestBuilder(object):
annotate=self.annotate,
cleanup_workdir=self.cleanup_workdir,
cleanup_sharedlibs=self.cleanup_sharedlibs,
cython_only=self.cython_only)
cython_only=self.cython_only,
fork=self.fork)
class CythonCompileTestCase(unittest.TestCase):
def __init__(self, directory, workdir, module, language='c',
expect_errors=False, annotate=False, cleanup_workdir=True,
cleanup_sharedlibs=True, cython_only=False):
cleanup_sharedlibs=True, cython_only=False, fork=True):
self.directory = directory
self.workdir = workdir
self.module = module
......@@ -207,6 +210,7 @@ class CythonCompileTestCase(unittest.TestCase):
self.cleanup_workdir = cleanup_workdir
self.cleanup_sharedlibs = cleanup_sharedlibs
self.cython_only = cython_only
self.fork = fork
unittest.TestCase.__init__(self)
def shortDescription(self):
......@@ -391,8 +395,9 @@ class CythonRunTestCase(CythonCompileTestCase):
pass
def run_doctests(self, module_name, result):
if sys.version_info[0] >= 3 or not hasattr(os, 'fork'):
if sys.version_info[0] >= 3 or not hasattr(os, 'fork') or not self.fork:
doctest.DocTestSuite(module_name).run(result)
gc.collect()
return
# fork to make sure we do not keep the tested module loaded
......@@ -407,11 +412,13 @@ class CythonRunTestCase(CythonCompileTestCase):
partial_result = PartialTestResult(result)
tests = doctest.DocTestSuite(module_name)
tests.run(partial_result)
gc.collect()
except Exception:
if tests is None:
# importing failed, try to fake a test class
tests = _FakeClass(
failureException=None,
shortDescription = self.shortDescription,
**{module_name: None})
partial_result.addError(tests, sys.exc_info())
result_code = 1
......@@ -421,9 +428,13 @@ class CythonRunTestCase(CythonCompileTestCase):
except: pass
os._exit(result_code)
input = os.fdopen(input, 'rb')
PartialTestResult.join_results(result, pickle.load(input))
cid, result_code = os.waitpid(child_id, 0)
if result_code in (0,1):
input = os.fdopen(input, 'rb')
try:
PartialTestResult.join_results(result, pickle.load(input))
finally:
input.close()
if result_code:
raise Exception("Tests in module '%s' exited with status %d" %
(module_name, result_code >> 8))
......@@ -663,6 +674,9 @@ if __name__ == '__main__':
parser.add_option("--no-refnanny", dest="with_refnanny",
action="store_false", default=True,
help="do not regression test reference counting")
parser.add_option("--no-fork", dest="fork",
action="store_false", default=True,
help="do not fork to run tests")
parser.add_option("--sys-pyregr", dest="system_pyregr",
action="store_true", default=False,
help="run the regression tests of the CPython installation")
......@@ -814,14 +828,16 @@ if __name__ == '__main__':
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, options.pyregr,
options.cython_only, languages, test_bugs)
options.cython_only, languages, test_bugs,
options.fork)
test_suite.addTest(filetests.build_suite())
if options.system_pyregr and languages:
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, True,
options.cython_only, languages, test_bugs)
options.cython_only, languages, test_bugs,
options.fork)
test_suite.addTest(
filetests.handle_directory(
os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'),
......
......@@ -5,5 +5,4 @@ methodmangling_T5
class_attribute_init_values_T18
numpy_ValueError_T172
unsignedbehaviour_T184
bad_c_struct_T252
missing_baseclass_in_predecl_T262
def test():
cdef object[int] not_assigned_to
not_assigned_to[2] = 3
extern int generic_error(void);
extern int specified_error(void);
extern int dynamic_error(void);
cdef void raise_py_error():
pass
cdef extern from "cpp_exceptions.h":
cdef int generic_error() except +
cdef int specified_error() except +MemoryError
cdef int dynamic_error() except +raise_py_error
def test_it():
generic_error()
specified_error()
dynamic_error()
cdef cf(default=None):
return default
cpdef cpf(default=None):
cpdef cpf(default=100):
"""
>>> cpf()
None
100
>>> cpf(1)
1
>>> cpf(default=2)
......@@ -13,10 +13,10 @@ cpdef cpf(default=None):
default = cf(default)
return default
def pf(default=None):
def pf(default=100):
"""
>>> pf()
None
100
>>> pf(1)
1
>>> pf(default=2)
......
......@@ -31,12 +31,16 @@ True
True
>>> all([div_int_py(a,b) == a // b for a in range(-10, 10) for b in range(-10, 10) if b != 0])
True
"""
>>> def simple_warn(msg, *args): print(msg)
>>> import warnings
>>> warnings.showwarning = simple_warn
import warnings
orig_showwarning = warnings.showwarning
true_py_functions = {}
exec "def simple_warn(msg, *args): print(msg)" in true_py_functions
simple_warn = true_py_functions['simple_warn']
del true_py_functions
"""
def _all(seq):
for x in seq:
......@@ -100,9 +104,11 @@ def test_cdiv_cmod(short a, short b):
@cython.cdivision_warnings(True)
def mod_int_c_warn(int a, int b):
"""
>>> warnings.showwarning = simple_warn
>>> mod_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-7
>>> warnings.showwarning = orig_showwarning
"""
return a % b
......@@ -110,9 +116,11 @@ def mod_int_c_warn(int a, int b):
@cython.cdivision_warnings(True)
def div_int_c_warn(int a, int b):
"""
>>> warnings.showwarning = simple_warn
>>> div_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-1
>>> warnings.showwarning = orig_showwarning
"""
return a // b
......@@ -120,12 +128,14 @@ def div_int_c_warn(int a, int b):
@cython.cdivision_warnings(True)
def complex_expression(int a, int b, int c, int d):
"""
>>> warnings.showwarning = simple_warn
>>> complex_expression(-150, 20, 19, -7)
verbose_call(20)
division with oppositely signed operands, C and Python semantics differ
verbose_call(19)
division with oppositely signed operands, C and Python semantics differ
-2
>>> warnings.showwarning = orig_showwarning
"""
return (a // verbose_call(b)) % (verbose_call(c) // d)
......@@ -173,7 +183,7 @@ def py_div_long(long a, long b):
"""
>>> py_div_long(-5, -1)
5
>>> import sys
>>> import sys
>>> maxint = getattr(sys, ((sys.version_info[0] >= 3) and 'maxsize' or 'maxint'))
>>> py_div_long(-maxint-1, -1)
Traceback (most recent call last):
......
import cython
def test_arith(int complex a, int complex b):
"""
>>> test_arith(4, 2)
((-4+0j), (6+0j), (2+0j), (8+0j), (2+0j))
>>> test_arith(6+9j, 3j)
((-6-9j), (6+12j), (6+6j), (-27+18j), (3-2j))
>>> test_arith(29+11j, 5+7j)
((-29-11j), (34+18j), (24+4j), (68+258j), (3-2j))
"""
return -a, a+b, a-b, a*b, a/b
@cython.cdivision(False)
def test_div_by_zero(long complex z):
"""
>>> test_div_by_zero(4j)
-25j
>>> test_div_by_zero(0)
Traceback (most recent call last):
...
ZeroDivisionError: float division
"""
return 100/z
def test_coercion(int a, long b, int complex c):
"""
>>> test_coercion(1, -2, 3-3j)
(1+0j)
(-2+0j)
(3-3j)
(5-6j)
"""
cdef double complex z
z = a; print z
z = b; print z
z = c; print z
return z + a + b + c
def test_conjugate(long complex z):
"""
>>> test_conjugate(2+3j)
(2-3j)
"""
return z.conjugate()
\ No newline at end of file
#cdef extern from "complex.h":
# pass
cimport cython
def test_object_conversion(o):
......@@ -23,21 +20,20 @@ def test_arithmetic(double complex z, double complex w):
((6+12j), (-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j))
>>> test_arithmetic(5-10j, 3+4j)
((5-10j), (-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j))
## XXX this is not working
## >>> test_div_by_zero(4j)
## -0.25j
## >>> test_div_by_zero(0)
## Traceback (most recent call last):
## ...
## ZeroDivisionError: float division
"""
return +z, -z, z+w, z-w, z*w, z/w
## XXX this is not working
## @cython.cdivision(False)
## def test_div_by_zero(double complex z):
## return 1/z
@cython.cdivision(False)
def test_div_by_zero(double complex z):
"""
>>> test_div_by_zero(4j)
-0.25j
>>> test_div_by_zero(0)
Traceback (most recent call last):
...
ZeroDivisionError: float division
"""
return 1/z
def test_coercion(int a, float b, double c, float complex d, double complex e):
"""
......@@ -127,13 +123,43 @@ def test_conjugate_double(double complex z):
ctypedef double complex cdouble
def test_conjugate_typedef(cdouble z):
"""
>>> test_conjugate_typedef(2+3j)
(2-3j)
"""
return z.conjugate()
## cdef extern from "complex_numbers_T305.h":
## ctypedef double double_really_float "myfloat"
## ctypedef float float_really_double "mydouble"
## ctypedef float real_float "myfloat"
## ctypedef double real_double "mydouble"
## def test_conjugate_nosizeassumptions(double_really_float x,
## float_really_double y,
## real_float z, real_double w):
## """
## >>> test_conjugate_nosizeassumptions(1, 1, 1, 1)
## (-1j, -1j, -1j, -1j)
## >>> ["%.2f" % x.imag for x in test_conjugate_nosizeassumptions(2e300, 2e300, 2e300, 2e300)]
## ['-inf', '-2e+300', '-inf', '-2e+300']
## """
## cdef double complex I = 1j
## return ((x*I).conjugate(), (y*I).conjugate(), (z*I).conjugate(), (w*I).conjugate())
ctypedef double mydouble
def test_coerce_typedef_multiply(mydouble x, double complex z):
"""
>>> test_coerce_typedef_multiply(3, 1j)
(3j)
>>> test_coerce_typedef_multiply(3, 1+1j)
(3+3j)
"""
return x * z
ctypedef int myint
def test_coerce_typedef_multiply_int(myint x, double complex z):
"""
>>> test_coerce_typedef_multiply_int(3, 1+1j)
(3+3j)
"""
return x * z
......
cdef int raise_py_error() except *:
raise TypeError("custom")
cdef extern from "cpp_exceptions_helper.cpp":
cdef extern from "cpp_exceptions_helper.h":
cdef int raise_int_raw "raise_int"(bint fire) except +
cdef int raise_int_value "raise_int"(bint fire) except +ValueError
cdef int raise_int_custom "raise_int"(bint fire) except +raise_py_error
......
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '").replace(u' u"', u' "')
def for_else():
"""
>>> for_else()
30
>>> print( u'*'.join(int_comp()) )
>>> print( int_comp() )
00*01*02
"""
cdef int i, j=0, k=2
......@@ -18,5 +15,5 @@ def for_else():
def int_comp():
cdef int i
return tuple([ u"%02d" % i
for i from 0 <= i < 3 ])
return u'*'.join(tuple([ u"%02d" % i
for i from 0 <= i < 3 ]))
__doc__ = u"""
>>> index_object(100, 100)
Traceback (most recent call last):
...
TypeError: 'int' object is unsubscriptable
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'is unsubscriptable', u'is not subscriptable')
elif sys.version_info < (2,5):
__doc__ = __doc__.replace(u"'int' object is unsubscriptable", u'unsubscriptable object')
def index_tuple(tuple t, int i):
"""
>>> index_tuple((1,1,2,3,5), 0)
......@@ -52,10 +60,6 @@ def index_object(object o, int i):
Traceback (most recent call last):
...
IndexError: string index out of range
>>> index_object(100, 100)
Traceback (most recent call last):
...
TypeError: 'int' object is unsubscriptable
"""
return o[i]
......
__doc__ = u"""
>>> c_longs()
(1, 1L, -1L, 18446744073709551615L)
>>> py_longs()
(1, 1L, 100000000000000000000000000000000L, -100000000000000000000000000000000L)
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'L', u'')
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'L', u'')
def c_longs():
"""
>>> c_longs()
(1, 1L, -1L, 18446744073709551615L)
"""
cdef long a = 1L
cdef unsigned long ua = 1UL
cdef long long aa = 0xFFFFFFFFFFFFFFFFLL
......@@ -16,8 +24,4 @@ def c_longs():
return a, ua, aa, uaa
def py_longs():
"""
>>> py_longs()
(1, 1L, 100000000000000000000000000000000L, -100000000000000000000000000000000L)
"""
return 1, 1L, 100000000000000000000000000000000, -100000000000000000000000000000000
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
class C:
"""
>>> C().xxx(5)
5
>>> C().xxx()
u'a b'
'a b'
>>> C().xxx(42)
42
>>> C().xxx()
u'a b'
'a b'
"""
def xxx(self, p=u"a b"):
def xxx(self, p="a b"):
return p
cimport cython
class A:
def pop(self, *args):
print args
return None
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def simple_pop(L):
"""
>>> L = range(10)
>>> simple_pop(L)
9
>>> simple_pop(L)
8
>>> L
[0, 1, 2, 3, 4, 5, 6, 7]
>>> while L:
... _ = simple_pop(L)
>>> L
[]
>>> simple_pop(L)
Traceback (most recent call last):
...
IndexError: pop from empty list
>>> simple_pop(A())
()
"""
return L.pop()
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def index_pop(L, int i):
"""
>>> L = range(10)
>>> index_pop(L, 2)
2
>>> index_pop(L, -2)
8
>>> L
[0, 1, 3, 4, 5, 6, 7, 9]
>>> index_pop(L, 100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> index_pop(L, -100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> while L:
... _ = index_pop(L, 0)
>>> L
[]
>>> index_pop(L, 0)
Traceback (most recent call last):
...
IndexError: pop from empty list
>>> index_pop(A(), 3)
(3,)
"""
return L.pop(i)
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def crazy_pop(L):
"""
>>> crazy_pop(range(10))
Traceback (most recent call last):
...
TypeError: pop() takes at most 1 argument (3 given)
>>> crazy_pop(A())
(1, 2, 3)
"""
return L.pop(1, 2, 3)
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
def f():
"""
>>> f()
>>> g
42
>>> x
u'spam'
>>> y
u'eggs'
>>> z
u'spameggs'
>>> x == 'spam'
True
>>> y == 'eggs'
True
>>> z == 'spameggs'
True
"""
pass
......
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"u'", u"'")
import sys, types
def test(obj):
"""
>>> test(Exception(u'hi'))
Raising: Exception(u'hi',)
Caught: Exception(u'hi',)
>>> test(Exception('hi'))
Raising: Exception('hi',)
Caught: Exception('hi',)
"""
print u"Raising: %s%r" % (obj.__class__.__name__, obj.args)
try:
......
......@@ -20,7 +20,10 @@ __doc__ = u"""
KeyError: 'f_noprof'
>>> short_stats['f_raise']
100
>>> os.unlink(statsfile)
>>> try:
... os.unlink(statsfile)
... except:
... pass
"""
import sys
......
__doc__ = u"""
>>> f(100)
101L
>>> g(3000000000)
3000000001L
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"L", u"")
def f(x):
"""
>>> f(100)
101L
"""
cdef unsigned long long ull
ull = x
return ull + 1
def g(unsigned long x):
"""
>>> g(3000000000)
3000000001L
"""
return x + 1
cimport cython
cdef class MyType:
def __cinit__(self):
print "CINIT"
def __init__(self):
print "INIT"
cdef class MySubType(MyType):
def __cinit__(self):
print "CINIT(SUB)"
def __init__(self):
print "INIT"
class MyClass(object):
def __cinit__(self):
print "CINIT"
def __init__(self):
print "INIT"
class MyTypeSubClass(MyType):
def __cinit__(self):
# not called: Python class!
print "CINIT(PYSUB)"
def __init__(self):
print "INIT"
# only this can be safely optimised:
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def make_new():
"""
>>> isinstance(make_new(), MyType)
CINIT
True
"""
m = MyType.__new__(MyType)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def make_new_typed_target():
"""
>>> isinstance(make_new_typed_target(), MyType)
CINIT
True
"""
cdef MyType m
m = MyType.__new__(MyType)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def make_new_builtin():
"""
>>> isinstance(make_new_builtin(), tuple)
True
"""
m = dict.__new__(dict)
m = list.__new__(list)
m = tuple.__new__(tuple)
return m
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def make_new_none(type t=None):
"""
>>> isinstance(make_new_none(), MyType)
Traceback (most recent call last):
TypeError: object.__new__(X): X is not a type object (NoneType)
"""
m = t.__new__(t)
return m
# these cannot:
@cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_pyclass():
"""
>>> isinstance(make_new_pyclass(), MyTypeSubClass)
CINIT
True
"""
m = MyClass.__new__(MyClass)
m = MyTypeSubClass.__new__(MyTypeSubClass)
return m
@cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_args(type t1=None, type t2=None):
"""
>>> isinstance(make_new_args(), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType, MyType), MyType)
CINIT
True
>>> isinstance(make_new_args(MyType, MySubType), MySubType)
Traceback (most recent call last):
TypeError: tp_new.MyType.__new__(tp_new.MySubType) is not safe, use tp_new.MySubType.__new__()
>>> isinstance(make_new_args(MySubType, MyType), MyType)
Traceback (most recent call last):
TypeError: tp_new.MySubType.__new__(tp_new.MyType): tp_new.MyType is not a subtype of tp_new.MySubType
"""
if t1 is None:
t1 = MyType
if t2 is None:
t2 = MyType
m = t1.__new__(t2)
return m
@cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_none_typed(tuple t=None):
"""
>>> isinstance(make_new_none(), MyType)
Traceback (most recent call last):
TypeError: object.__new__(X): X is not a type object (NoneType)
"""
m = t.__new__(t)
return m
@cython.test_assert_path_exists('//SimpleCallNode/AttributeNode')
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def make_new_untyped(t):
"""
>>> make_new_untyped(None)
Traceback (most recent call last):
TypeError: object.__new__(X): X is not a type object (NoneType)
"""
m = t.__new__(t)
return m
__doc__ = """
>>> readonly()
Traceback (most recent call last):
...
TypeError: readonly attribute
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u'TypeError:', u'AttributeError:')
......@@ -53,11 +60,5 @@ def longdouble_access():
def readonly():
"""
>>> readonly()
Traceback (most recent call last):
...
TypeError: readonly attribute
"""
c = MyClass()
c.actual_double = 3
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