Commit b8419151 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents ca3f5c6f 81fe6792
......@@ -162,52 +162,73 @@ pyexec_utility_code = UtilityCode(
proto = """
static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*);
""",
impl = """
impl = '''
static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) {
PyObject* result;
PyObject* s = 0;
char *code = 0;
if (!locals && !globals) {
globals = PyModule_GetDict(%s);""" % Naming.module_cname + """
if (!globals || globals == Py_None) {
globals = PyModule_GetDict(%s);''' % Naming.module_cname + '''
if (!globals)
goto bad;
} else if (!PyDict_Check(globals)) {
PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s",
globals->ob_type->tp_name);
goto bad;
}
if (!locals || locals == Py_None) {
locals = globals;
} else if (!locals) {
locals = globals;
} else if (!globals) {
globals = locals;
}
if (PyUnicode_Check(o)) {
s = PyUnicode_AsUTF8String(o);
if (!s) goto bad;
o = s;
#if PY_MAJOR_VERSION >= 3
} else if (!PyBytes_Check(o)) {
#else
} else if (!PyString_Check(o)) {
#endif
/* FIXME: support file objects and code objects */
PyErr_SetString(PyExc_TypeError,
"exec currently requires a string as code input.");
goto bad;
if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
}
#if PY_MAJOR_VERSION >= 3
code = PyBytes_AS_STRING(o);
#else
code = PyString_AS_STRING(o);
#endif
result = PyRun_String(code, Py_file_input, globals, locals);
if (PyCode_Check(o)) {
if (PyCode_GetNumFree((PyCodeObject *)o) > 0) {
PyErr_SetString(PyExc_TypeError,
"code object passed to exec() may not contain free variables");
goto bad;
}
result = PyEval_EvalCode((PyCodeObject *)o, globals, locals);
} else {
PyCompilerFlags cf;
cf.cf_flags = 0;
if (PyUnicode_Check(o)) {
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
s = PyUnicode_AsUTF8String(o);
if (!s) goto bad;
o = s;
#if PY_MAJOR_VERSION >= 3
} else if (!PyBytes_Check(o)) {
#else
} else if (!PyString_Check(o)) {
#endif
PyErr_SetString(PyExc_TypeError,
"exec: arg 1 must be string, bytes or code object");
goto bad;
}
#if PY_MAJOR_VERSION >= 3
code = PyBytes_AS_STRING(o);
#else
code = PyString_AS_STRING(o);
#endif
if (PyEval_MergeCompilerFlags(&cf)) {
result = PyRun_StringFlags(code, Py_file_input, globals, locals, &cf);
} else {
result = PyRun_String(code, Py_file_input, globals, locals);
}
Py_XDECREF(s);
}
Py_XDECREF(s);
return result;
bad:
Py_XDECREF(s);
return 0;
}
""")
''')
intern_utility_code = UtilityCode(
proto = """
......
......@@ -1244,6 +1244,15 @@ class CCodeWriter(object):
def put_finish_refcount_context(self):
self.putln("__Pyx_FinishRefcountContext();")
def put_trace_call(self, name, pos):
self.putln('__Pyx_TraceCall("%s", %s[%s], %s);' % (name, Naming.filetable_cname, self.lookup_filename(pos[0]), pos[1]));
def put_trace_exception(self):
self.putln("__Pyx_TraceException();")
def put_trace_return(self, retvalue_cname):
self.putln("__Pyx_TraceReturn(%s);" % retvalue_cname)
class PyrexCodeWriter(object):
# f file output file
......
......@@ -2487,6 +2487,9 @@ class GeneralCallNode(CallNode):
if self.starstar_arg:
self.starstar_arg.analyse_types(env)
if not self.function.type.is_pyobject:
if self.function.type.is_error:
self.type = error_type
return error_type
if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
error(self.pos, "Keyword arguments not allowed in cdef functions.")
else:
......@@ -2507,6 +2510,7 @@ class GeneralCallNode(CallNode):
self.is_temp = 1
def generate_result_code(self, code):
if self.type.is_error: return
if self.keyword_args and self.starstar_arg:
code.put_error_if_neg(self.pos,
"PyDict_Update(%s, %s)" % (
......
......@@ -566,6 +566,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('static PyObject *%s;' % env.module_cname)
code.putln('static PyObject *%s;' % Naming.builtins_cname)
code.putln('static PyObject *%s;' % Naming.empty_tuple)
code.putln('static PyObject *%s;' % Naming.empty_bytes)
if Options.pre_import is not None:
code.putln('static PyObject *%s;' % Naming.preimport_cname)
code.putln('static int %s;' % Naming.lineno_cname)
......@@ -1637,6 +1638,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#endif")
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("#if PY_MAJOR_VERSION < 3");
code.putln("%s = PyString_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
code.putln("#else");
code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
code.putln("#endif");
code.putln("/*--- Library function declarations ---*/")
env.generate_library_function_declarations(code)
......@@ -2463,6 +2469,7 @@ static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
#define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
""")
main_method = UtilityCode(
impl = """
#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
......
......@@ -75,6 +75,7 @@ c_api_tab_cname = pyrex_prefix + "c_api_tab"
gilstate_cname = pyrex_prefix + "state"
skip_dispatch_cname = pyrex_prefix + "skip_dispatch"
empty_tuple = pyrex_prefix + "empty_tuple"
empty_bytes = pyrex_prefix + "empty_bytes"
print_function = pyrex_prefix + "print"
print_function_kwargs = pyrex_prefix + "print_kwargs"
cleanup_cname = pyrex_prefix + "module_cleanup"
......@@ -84,6 +85,8 @@ import_star = pyrex_prefix + "import_star"
import_star_set = pyrex_prefix + "import_star_set"
cur_scope_cname = pyrex_prefix + "cur_scope"
enc_scope_cname = pyrex_prefix + "enc_scope"
frame_cname = pyrex_prefix + "frame"
frame_code_cname = pyrex_prefix + "frame_code"
line_c_macro = "__LINE__"
......
......@@ -979,6 +979,7 @@ class FuncDefNode(StatNode, BlockNode):
py_func = None
assmt = None
needs_closure = False
modifiers = []
def analyse_default_values(self, env):
genv = env.global_scope()
......@@ -1018,6 +1019,15 @@ class FuncDefNode(StatNode, BlockNode):
is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
self.entry.scope.is_c_class_scope)
if code.globalstate.directives['profile'] is None:
profile = 'inline' not in self.modifiers and not lenv.nogil
else:
profile = code.globalstate.directives['profile']
if profile and lenv.nogil:
error(self.pos, "Cannot profile nogil function.")
if profile:
code.globalstate.use_utility_code(trace_utility_code)
# Generate C code for header and body of function
code.enter_cfunc_scope()
......@@ -1059,6 +1069,8 @@ class FuncDefNode(StatNode, BlockNode):
env.use_utility_code(force_init_threads_utility_code)
code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
# ----- Automatic lead-ins for certain special functions
if profile:
code.put_trace_call(self.entry.name, self.pos)
if not lenv.nogil:
code.put_setup_refcount_context(self.entry.name)
if is_getbuffer_slot:
......@@ -1120,6 +1132,9 @@ class FuncDefNode(StatNode, BlockNode):
err_val = self.error_value()
exc_check = self.caller_will_check_exceptions()
if err_val is not None or exc_check:
# TODO: Fix exception tracing (though currently unused by cProfile).
# code.globalstate.use_utility_code(get_exception_tuple_utility_code)
# code.put_trace_exception()
code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
else:
warning(self.entry.pos, "Unraisable exception in function '%s'." \
......@@ -1149,9 +1164,6 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Non-error return cleanup
# If you add anything here, remember to add a condition to the
# if-test above in the error block (so that it can jump past this
# block).
code.put_label(code.return_label)
for entry in lenv.buffer_entries:
if entry.used:
......@@ -1188,6 +1200,12 @@ class FuncDefNode(StatNode, BlockNode):
# We do as Python instances and coerce -1 into -2.
code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
if profile:
if self.return_type.is_pyobject:
code.put_trace_return(Naming.retval_cname)
else:
code.put_trace_return("Py_None")
if acquire_gil:
code.putln("PyGILState_Release(_save);")
......@@ -1287,7 +1305,7 @@ class CFuncDefNode(FuncDefNode):
return self.entry.name
def analyse_declarations(self, env):
directive_locals = self.directive_locals = env.directives['locals']
self.directive_locals.update(env.directives['locals'])
base_type = self.base_type.analyse(env)
# The 2 here is because we need both function and argument names.
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
......@@ -5273,7 +5291,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
PyObject *py_srcfile = 0;
PyObject *py_funcname = 0;
PyObject *py_globals = 0;
PyObject *empty_string = 0;
PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0;
......@@ -5300,12 +5317,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
if (!py_funcname) goto bad;
py_globals = PyModule_GetDict(%(GLOBALS)s);
if (!py_globals) goto bad;
#if PY_MAJOR_VERSION < 3
empty_string = PyString_FromStringAndSize("", 0);
#else
empty_string = PyBytes_FromStringAndSize("", 0);
#endif
if (!empty_string) goto bad;
py_code = PyCode_New(
0, /*int argcount,*/
#if PY_MAJOR_VERSION >= 3
......@@ -5314,7 +5325,7 @@ static void __Pyx_AddTraceback(const char *funcname) {
0, /*int nlocals,*/
0, /*int stacksize,*/
0, /*int flags,*/
empty_string, /*PyObject *code,*/
%(EMPTY_BYTES)s, /*PyObject *code,*/
%(EMPTY_TUPLE)s, /*PyObject *consts,*/
%(EMPTY_TUPLE)s, /*PyObject *names,*/
%(EMPTY_TUPLE)s, /*PyObject *varnames,*/
......@@ -5323,7 +5334,7 @@ static void __Pyx_AddTraceback(const char *funcname) {
py_srcfile, /*PyObject *filename,*/
py_funcname, /*PyObject *name,*/
%(LINENO)s, /*int firstlineno,*/
empty_string /*PyObject *lnotab*/
%(EMPTY_BYTES)s /*PyObject *lnotab*/
);
if (!py_code) goto bad;
py_frame = PyFrame_New(
......@@ -5338,7 +5349,6 @@ static void __Pyx_AddTraceback(const char *funcname) {
bad:
Py_XDECREF(py_srcfile);
Py_XDECREF(py_funcname);
Py_XDECREF(empty_string);
Py_XDECREF(py_code);
Py_XDECREF(py_frame);
}
......@@ -5349,6 +5359,7 @@ bad:
'CLINENO': Naming.clineno_cname,
'GLOBALS': Naming.module_cname,
'EMPTY_TUPLE' : Naming.empty_tuple,
'EMPTY_BYTES' : Naming.empty_bytes,
})
restore_exception_utility_code = UtilityCode(
......@@ -5563,6 +5574,31 @@ bad:
#------------------------------------------------------------------------------------
get_exception_tuple_utility_code = UtilityCode(proto="""
static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
""",
impl = """
static PyObject *__Pyx_GetExceptionTuple(void) {
PyObject *type = NULL, *value = NULL, *tb = NULL;
if (__Pyx_GetException(&type, &value, &tb) == 0) {
PyObject* exc_info = PyTuple_New(3);
if (exc_info) {
Py_INCREF(type);
Py_INCREF(value);
Py_INCREF(tb);
PyTuple_SET_ITEM(exc_info, 0, type);
PyTuple_SET_ITEM(exc_info, 1, value);
PyTuple_SET_ITEM(exc_info, 2, tb);
return exc_info;
}
}
return NULL;
}
""",
requires=[get_exception_utility_code])
#------------------------------------------------------------------------------------
reset_exception_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
......@@ -5608,3 +5644,143 @@ proto="""
""")
#------------------------------------------------------------------------------------
# Note that cPython ignores PyTrace_EXCEPTION,
# but maybe some other profilers don't.
trace_utility_code = UtilityCode(proto="""
#ifndef CYTHON_TRACING
#define CYTHON_TRACING 1
#endif
#ifndef CYTHON_TRACING_REUSE_FRAME
#define CYTHON_TRACING_REUSE_FRAME 0
#endif
#if CYTHON_TRACING
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
#if CYTHON_TRACING_REUSE_FRAME
#define CYTHON_FRAME_MODIFIER static
#define CYTHON_FRAME_DEL
#else
#define CYTHON_FRAME_MODIFIER
#define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
#endif
#define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
static PyCodeObject *%(FRAME_CODE)s = NULL; \\
CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
int __Pyx_use_tracing = 0; \\
if (PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
__Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
}
#define __Pyx_TraceException() \\
if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
if (exc_info) { \\
PyThreadState_GET()->c_profilefunc( \\
PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
Py_DECREF(exc_info); \\
} \\
}
#define __Pyx_TraceReturn(result) \\
if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
PyThreadState_GET()->c_profilefunc( \\
PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
CYTHON_FRAME_DEL; \\
}
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
#else
#define __Pyx_TraceCall(funcname, srcfile, firstlineno)
#define __Pyx_TraceException()
#define __Pyx_TraceReturn(result)
#endif /* CYTHON_TRACING */
"""
% {
"FRAME": Naming.frame_cname,
"FRAME_CODE": Naming.frame_code_cname,
},
impl = """
#if CYTHON_TRACING
static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
PyFrameObject** frame,
const char *funcname,
const char *srcfile,
int firstlineno) {
if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
if (*code == NULL) {
*code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
if (*code == NULL) return 0;
}
*frame = PyFrame_New(
PyThreadState_GET(), /*PyThreadState *tstate*/
*code, /*PyCodeObject *code*/
PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
0 /*PyObject *locals*/
);
if (*frame == NULL) return 0;
}
else {
(*frame)->f_tstate = PyThreadState_GET();
}
return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
}
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
PyObject *py_srcfile = 0;
PyObject *py_funcname = 0;
PyCodeObject *py_code = 0;
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromString(funcname);
py_srcfile = PyString_FromString(srcfile);
#else
py_funcname = PyUnicode_FromString(funcname);
py_srcfile = PyUnicode_FromString(srcfile);
#endif
if (!py_funcname | !py_srcfile) goto bad;
py_code = PyCode_New(
0, /*int argcount,*/
#if PY_MAJOR_VERSION >= 3
0, /*int kwonlyargcount,*/
#endif
0, /*int nlocals,*/
0, /*int stacksize,*/
0, /*int flags,*/
%(EMPTY_BYTES)s, /*PyObject *code,*/
%(EMPTY_TUPLE)s, /*PyObject *consts,*/
%(EMPTY_TUPLE)s, /*PyObject *names,*/
%(EMPTY_TUPLE)s, /*PyObject *varnames,*/
%(EMPTY_TUPLE)s, /*PyObject *freevars,*/
%(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
py_srcfile, /*PyObject *filename,*/
py_funcname, /*PyObject *name,*/
firstlineno, /*int firstlineno,*/
%(EMPTY_BYTES)s /*PyObject *lnotab*/
);
bad:
Py_XDECREF(py_srcfile);
Py_XDECREF(py_funcname);
return py_code;
}
#endif /* CYTHON_TRACING */
""" % {
'EMPTY_TUPLE' : Naming.empty_tuple,
'EMPTY_BYTES' : Naming.empty_bytes,
"MODULE": Naming.module_cname,
})
......@@ -18,13 +18,9 @@ try:
except NameError:
from functools import reduce
#def unwrap_node(node):
# while isinstance(node, ExprNodes.PersistentNode):
# node = node.arg
# return node
# Temporary hack while PersistentNode is out of order
def unwrap_node(node):
while isinstance(node, UtilNodes.ResultRefNode):
node = node.expression
return node
def is_common_value(a, b):
......@@ -391,13 +387,17 @@ class SwitchTransform(Visitor.VisitorTransform):
is common among all clauses and both var and value are ints.
"""
def extract_conditions(self, cond):
if isinstance(cond, ExprNodes.CoerceToTempNode):
cond = cond.arg
while True:
if isinstance(cond, ExprNodes.CoerceToTempNode):
cond = cond.arg
elif isinstance(cond, UtilNodes.EvalWithTempExprNode):
# this is what we get from the FlattenInListTransform
cond = cond.subexpression
elif isinstance(cond, ExprNodes.TypecastNode):
cond = cond.operand
else:
break
if isinstance(cond, ExprNodes.TypecastNode):
cond = cond.operand
if (isinstance(cond, ExprNodes.PrimaryCmpNode)
and cond.cascade is None
and cond.operator == '=='
......
......@@ -67,10 +67,11 @@ option_defaults = {
'wraparound' : True,
'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this...
'callspec' : "",
'profile': None,
}
# Override types possibilities above, if needed
option_types = { }
option_types = { 'profile': bool }
for key, val in option_defaults.items():
if key not in option_types:
......
......@@ -836,13 +836,14 @@ static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */
""",
impl="""
static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) {
if (PyComplex_Check(o)) {
if (PyComplex_CheckExact(o)) {
return %(type_name)s_from_parts(
(%(real_type)s)((PyComplexObject *)o)->cval.real,
(%(real_type)s)((PyComplexObject *)o)->cval.imag);
}
else {
return %(type_name)s_from_parts(%(type_convert)s(o), 0);
Py_complex cval = PyComplex_AsCComplex(o);
return %(type_name)s_from_parts((%(real_type)s)cval.real, (%(real_type)s)cval.imag);
}
}
""")
......
# NumPy static imports for Cython
#
# If any of the PyArray_* functions are called, import_array must be
# called first.
#
# This also defines backwards-compatability buffer acquisition
# code for use in Python 2.x (or Python <= 2.5 when NumPy starts
# implementing PEP-3118 directly).
#
# Because of laziness, the format string of the buffer is statically
# allocated. Increase the size if this is not enough, or submit a
# patch to do this properly.
#
# Author: Dag Sverre Seljebotn
#
DEF _buffer_format_string_len = 255
cimport python_buffer as pybuf
cimport stdlib
cimport stdio
cdef extern from "Python.h":
ctypedef int Py_intptr_t
......@@ -21,42 +27,123 @@ cdef extern from "numpy/arrayobject.h":
ctypedef Py_intptr_t npy_intp
cdef enum NPY_TYPES:
NPY_BOOL,
NPY_BYTE, NPY_UBYTE,
NPY_SHORT, NPY_USHORT,
NPY_INT, NPY_UINT,
NPY_LONG, NPY_ULONG,
NPY_LONGLONG, NPY_ULONGLONG,
NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
NPY_OBJECT,
NPY_STRING, NPY_UNICODE,
NPY_VOID,
NPY_NTYPES,
NPY_NOTYPE,
NPY_CHAR,
NPY_USERDEF,
NPY_C_CONTIGUOUS,
NPY_BOOL
NPY_BYTE
NPY_UBYTE
NPY_SHORT
NPY_USHORT
NPY_INT
NPY_UINT
NPY_LONG
NPY_ULONG
NPY_LONGLONG
NPY_ULONGLONG
NPY_FLOAT
NPY_DOUBLE
NPY_LONGDOUBLE
NPY_CFLOAT
NPY_CDOUBLE
NPY_CLONGDOUBLE
NPY_OBJECT
NPY_STRING
NPY_UNICODE
NPY_VOID
NPY_NTYPES
NPY_NOTYPE
enum NPY_ORDER:
NPY_ANYORDER
NPY_CORDER
NPY_FORTRANORDER
enum NPY_CLIPMODE:
NPY_CLIP
NPY_WRAP
NPY_RAISE
enum NPY_SCALARKIND:
NPY_NOSCALAR,
NPY_BOOL_SCALAR,
NPY_INTPOS_SCALAR,
NPY_INTNEG_SCALAR,
NPY_FLOAT_SCALAR,
NPY_COMPLEX_SCALAR,
NPY_OBJECT_SCALAR
enum NPY_SORTKIND:
NPY_QUICKSORT
NPY_HEAPSORT
NPY_MERGESORT
cdef enum requirements:
NPY_C_CONTIGUOUS
NPY_F_CONTIGUOUS
NPY_CONTIGUOUS
NPY_FORTRAN
NPY_OWNDATA
NPY_FORCECAST
NPY_ENSURECOPY
NPY_ENSUREARRAY
NPY_ELEMENTSTRIDES
NPY_ALIGNED
NPY_NOTSWAPPED
NPY_WRITEABLE
NPY_UPDATEIFCOPY
NPY_ARR_HAS_DESCR
NPY_BEHAVED
NPY_BEHAVED_NS
NPY_CARRAY
NPY_CARRAY_RO
NPY_FARRAY
NPY_FARRAY_RO
NPY_DEFAULT
NPY_IN_ARRAY
NPY_OUT_ARRAY
NPY_INOUT_ARRAY
NPY_IN_FARRAY
NPY_OUT_FARRAY
NPY_INOUT_FARRAY
NPY_UPDATE_ALL
cdef enum:
NPY_MAXDIMS
npy_intp NPY_MAX_ELSIZE
ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *)
ctypedef class numpy.dtype [object PyArray_Descr]:
# Use PyDataType_* macros when possible, however there are no macros
# for accessing some of the fields, so some are defined. Please
# ask on cython-dev if you need more.
cdef int type_num
cdef int itemsize "elsize"
cdef char byteorder
cdef object fields
cdef object names
ctypedef extern class numpy.flatiter [object PyArrayIterObject]:
# Use through macros
pass
ctypedef extern class numpy.broadcast [object PyArrayMultiIterObject]:
# Use through macros
pass
ctypedef class numpy.ndarray [object PyArrayObject]:
cdef __cythonbufferdefaults__ = {"mode": "strided"}
cdef:
# Only taking a few of the most commonly used and stable fields.
# One should use PyArray_* macros instead to access the C fields.
char *data
int ndim "nd"
npy_intp *shape "dimensions"
npy_intp *strides
int flags
dtype descr
# Note: This syntax (function definition in pxd files) is an
......@@ -159,19 +246,9 @@ cdef extern from "numpy/arrayobject.h":
if sizeof(npy_intp) != sizeof(Py_ssize_t):
stdlib.free(info.strides)
# info.shape was stored after info.strides in the same block
cdef void* PyArray_DATA(ndarray arr)
cdef int PyArray_TYPE(ndarray arr)
cdef int PyArray_NDIM(ndarray arr)
cdef int PyArray_ISWRITEABLE(ndarray arr)
cdef npy_intp* PyArray_STRIDES(ndarray arr)
cdef npy_intp* PyArray_DIMS(ndarray arr)
cdef int PyArray_ITEMSIZE(ndarray arr)
cdef int PyArray_CHKFLAGS(ndarray arr, int flags)
cdef int PyArray_HASFIELDS(ndarray arr)
cdef int PyDataType_HASFIELDS(dtype obj)
ctypedef signed char npy_bool
ctypedef signed char npy_byte
ctypedef signed short npy_short
......@@ -216,17 +293,353 @@ cdef extern from "numpy/arrayobject.h":
ctypedef long double complex npy_complex256
ctypedef struct npy_cfloat:
float real
float imag
double real
double imag
ctypedef struct npy_cdouble:
float real
float imag
double real
double imag
ctypedef struct npy_clongdouble:
float real
float imag
double real
double imag
ctypedef struct PyArray_Dims:
npy_intp *ptr
int len
void import_array()
#
# Macros from ndarrayobject.h
#
bint PyArray_CHKFLAGS(ndarray m, int flags)
bint PyArray_ISISCONTIGUOUS(ndarray m)
bint PyArray_ISWRITEABLE(ndarray m)
bint PyArray_ISALIGNED(ndarray m)
int PyArray_NDIM(ndarray)
bint PyArray_ISONESEGMENT(ndarray)
bint PyArray_ISFORTRAN(ndarray)
int PyArray_FORTRANIF(ndarray)
void* PyArray_DATA(ndarray)
char* PyArray_BYTES(ndarray)
npy_intp* PyArray_DIMS(ndarray)
npy_intp* PyArray_STRIDES(ndarray)
npy_intp PyArray_DIM(ndarray, size_t)
npy_intp PyArray_STRIDE(ndarray, size_t)
# object PyArray_BASE(ndarray) wrong refcount semantics
# dtype PyArray_DESCR(ndarray) wrong refcount semantics
int PyArray_FLAGS(ndarray)
npy_intp PyArray_ITEMSIZE(ndarray)
int PyArray_TYPE(ndarray arr)
object PyArray_GETITEM(ndarray arr, void *itemptr)
int PyArray_SETITEM(ndarray arr, void *itemptr, object obj)
bint PyTypeNum_ISBOOL(int)
bint PyTypeNum_ISUNSIGNED(int)
bint PyTypeNum_ISSIGNED(int)
bint PyTypeNum_ISINTEGER(int)
bint PyTypeNum_ISFLOAT(int)
bint PyTypeNum_ISNUMBER(int)
bint PyTypeNum_ISSTRING(int)
bint PyTypeNum_ISCOMPLEX(int)
bint PyTypeNum_ISPYTHON(int)
bint PyTypeNum_ISFLEXIBLE(int)
bint PyTypeNum_ISUSERDEF(int)
bint PyTypeNum_ISEXTENDED(int)
bint PyTypeNum_ISOBJECT(int)
bint PyDataType_ISBOOL(dtype)
bint PyDataType_ISUNSIGNED(dtype)
bint PyDataType_ISSIGNED(dtype)
bint PyDataType_ISINTEGER(dtype)
bint PyDataType_ISFLOAT(dtype)
bint PyDataType_ISNUMBER(dtype)
bint PyDataType_ISSTRING(dtype)
bint PyDataType_ISCOMPLEX(dtype)
bint PyDataType_ISPYTHON(dtype)
bint PyDataType_ISFLEXIBLE(dtype)
bint PyDataType_ISUSERDEF(dtype)
bint PyDataType_ISEXTENDED(dtype)
bint PyDataType_ISOBJECT(dtype)
bint PyDataType_HASFIELDS(dtype)
bint PyArray_ISBOOL(ndarray)
bint PyArray_ISUNSIGNED(ndarray)
bint PyArray_ISSIGNED(ndarray)
bint PyArray_ISINTEGER(ndarray)
bint PyArray_ISFLOAT(ndarray)
bint PyArray_ISNUMBER(ndarray)
bint PyArray_ISSTRING(ndarray)
bint PyArray_ISCOMPLEX(ndarray)
bint PyArray_ISPYTHON(ndarray)
bint PyArray_ISFLEXIBLE(ndarray)
bint PyArray_ISUSERDEF(ndarray)
bint PyArray_ISEXTENDED(ndarray)
bint PyArray_ISOBJECT(ndarray)
bint PyArray_HASFIELDS(ndarray)
bint PyArray_ISVARIABLE(ndarray)
bint PyArray_SAFEALIGNEDCOPY(ndarray)
bint PyArray_ISNBO(ndarray)
bint PyArray_IsNativeByteOrder(ndarray)
bint PyArray_ISNOTSWAPPED(ndarray)
bint PyArray_ISBYTESWAPPED(ndarray)
bint PyArray_FLAGSWAP(ndarray, int)
bint PyArray_ISCARRAY(ndarray)
bint PyArray_ISCARRAY_RO(ndarray)
bint PyArray_ISFARRAY(ndarray)
bint PyArray_ISFARRAY_RO(ndarray)
bint PyArray_ISBEHAVED(ndarray)
bint PyArray_ISBEHAVED_RO(ndarray)
bint PyDataType_ISNOTSWAPPED(dtype)
bint PyDataType_ISBYTESWAPPED(dtype)
bint PyArray_DescrCheck(object)
bint PyArray_Check(object)
bint PyArray_CheckExact(object)
# Cannot be supported due to out arg:
# bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
# bint PyArray_HasArrayInterface(op, out)
bint PyArray_IsZeroDim(object)
# Cannot be supported due to ## ## in macro:
# bint PyArray_IsScalar(object, verbatim work)
bint PyArray_CheckScalar(object)
bint PyArray_IsPythonNumber(object)
bint PyArray_IsPythonScalar(object)
bint PyArray_IsAnyScalar(object)
bint PyArray_CheckAnyScalar(object)
ndarray PyArray_GETCONTIGUOUS(ndarray)
bint PyArray_SAMESHAPE(ndarray, ndarray)
npy_intp PyArray_SIZE(ndarray)
npy_intp PyArray_NBYTES(ndarray)
object PyArray_FROM_O(object)
object PyArray_FROM_OF(object m, int flags)
bint PyArray_FROM_OT(object m, int type)
bint PyArray_FROM_OTF(object m, int type, int flags)
object PyArray_FROMANY(object m, int type, int min, int max, int flags)
bint PyArray_ZEROS(ndarray m, dims, int type, int fortran)
object PyArray_EMPTY(object m, dims, int type, int fortran)
void PyArray_FILLWBYTE(object, int val)
npy_intp PyArray_REFCOUNT(object)
object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
bint PyArray_EquivByteorders(int b1, int b2)
object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
#object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
object PyArray_ToScalar(void* data, ndarray arr)
void* PyArray_GETPTR1(ndarray m, npy_intp i)
void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j)
void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k)
void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l)
void PyArray_XDECREF_ERR(ndarray)
# Cannot be supported due to out arg
# void PyArray_DESCR_REPLACE(descr)
object PyArray_Copy(ndarray)
object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
object PyArray_Cast(ndarray mp, int type_num)
object PyArray_Take(ndarray ap, object items, int axis)
object PyArray_Put(ndarray ap, object items, object values)
# Functions from __multiarray_api.h
# Functions taking dtype and returning object/ndarray are disabled
# for now as they steal dtype references. I'm conservative and disable
# more than is probably needed until it can be checked further.
int PyArray_SetNumericOps (object)
object PyArray_GetNumericOps ()
int PyArray_INCREF (ndarray)
int PyArray_XDECREF (ndarray)
void PyArray_SetStringFunction (object, int)
dtype PyArray_DescrFromType (int)
object PyArray_TypeObjectFromType (int)
char * PyArray_Zero (ndarray)
char * PyArray_One (ndarray)
#object PyArray_CastToType (ndarray, dtype, int)
int PyArray_CastTo (ndarray, ndarray)
int PyArray_CastAnyTo (ndarray, ndarray)
int PyArray_CanCastSafely (int, int)
npy_bool PyArray_CanCastTo (dtype, dtype)
int PyArray_ObjectType (object, int)
dtype PyArray_DescrFromObject (object, dtype)
#ndarray* PyArray_ConvertToCommonType (object, int *)
dtype PyArray_DescrFromScalar (object)
dtype PyArray_DescrFromTypeObject (object)
npy_intp PyArray_Size (object)
#object PyArray_Scalar (void *, dtype, object)
#object PyArray_FromScalar (object, dtype)
void PyArray_ScalarAsCtype (object, void *)
#int PyArray_CastScalarToCtype (object, void *, dtype)
#int PyArray_CastScalarDirect (object, dtype, void *, int)
object PyArray_ScalarFromObject (object)
#PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
object PyArray_FromDims (int, int *, int)
#object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
#object PyArray_FromAny (object, dtype, int, int, int, object)
object PyArray_EnsureArray (object)
object PyArray_EnsureAnyArray (object)
#object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
#object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
#object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
#object PyArray_FromIter (object, dtype, npy_intp)
object PyArray_Return (ndarray)
#object PyArray_GetField (ndarray, dtype, int)
#int PyArray_SetField (ndarray, dtype, int, object)
object PyArray_Byteswap (ndarray, npy_bool)
object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
int PyArray_MoveInto (ndarray, ndarray)
int PyArray_CopyInto (ndarray, ndarray)
int PyArray_CopyAnyInto (ndarray, ndarray)
int PyArray_CopyObject (ndarray, object)
object PyArray_NewCopy (ndarray, NPY_ORDER)
object PyArray_ToList (ndarray)
object PyArray_ToString (ndarray, NPY_ORDER)
int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *)
int PyArray_Dump (object, object, int)
object PyArray_Dumps (object, int)
int PyArray_ValidType (int)
void PyArray_UpdateFlags (ndarray, int)
object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
#object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
#dtype PyArray_DescrNew (dtype)
dtype PyArray_DescrNewFromType (int)
double PyArray_GetPriority (object, double)
object PyArray_IterNew (object)
object PyArray_MultiIterNew (int, ...)
int PyArray_PyIntAsInt (object)
npy_intp PyArray_PyIntAsIntp (object)
int PyArray_Broadcast (broadcast)
void PyArray_FillObjectArray (ndarray, object)
int PyArray_FillWithScalar (ndarray, object)
npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
dtype PyArray_DescrNewByteorder (dtype, char)
object PyArray_IterAllButAxis (object, int *)
#object PyArray_CheckFromAny (object, dtype, int, int, int, object)
#object PyArray_FromArray (ndarray, dtype, int)
object PyArray_FromInterface (object)
object PyArray_FromStructInterface (object)
#object PyArray_FromArrayAttr (object, dtype, object)
#NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
object PyArray_NewFlagsObject (object)
npy_bool PyArray_CanCastScalar (type, type)
#int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
int PyArray_RemoveSmallest (broadcast)
int PyArray_ElementStrides (object)
void PyArray_Item_INCREF (char *, dtype)
void PyArray_Item_XDECREF (char *, dtype)
object PyArray_FieldNames (object)
object PyArray_Transpose (ndarray, PyArray_Dims *)
object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
object PyArray_PutMask (ndarray, object, object)
object PyArray_Repeat (ndarray, object, int)
object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
int PyArray_Sort (ndarray, int, NPY_SORTKIND)
object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE)
object PyArray_ArgMax (ndarray, int, ndarray)
object PyArray_ArgMin (ndarray, int, ndarray)
object PyArray_Reshape (ndarray, object)
object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
object PyArray_Squeeze (ndarray)
#object PyArray_View (ndarray, dtype, type)
object PyArray_SwapAxes (ndarray, int, int)
object PyArray_Max (ndarray, int, ndarray)
object PyArray_Min (ndarray, int, ndarray)
object PyArray_Ptp (ndarray, int, ndarray)
object PyArray_Mean (ndarray, int, int, ndarray)
object PyArray_Trace (ndarray, int, int, int, int, ndarray)
object PyArray_Diagonal (ndarray, int, int, int)
object PyArray_Clip (ndarray, object, object, ndarray)
object PyArray_Conjugate (ndarray, ndarray)
object PyArray_Nonzero (ndarray)
object PyArray_Std (ndarray, int, int, ndarray, int)
object PyArray_Sum (ndarray, int, int, ndarray)
object PyArray_CumSum (ndarray, int, int, ndarray)
object PyArray_Prod (ndarray, int, int, ndarray)
object PyArray_CumProd (ndarray, int, int, ndarray)
object PyArray_All (ndarray, int, ndarray)
object PyArray_Any (ndarray, int, ndarray)
object PyArray_Compress (ndarray, object, int, ndarray)
object PyArray_Flatten (ndarray, NPY_ORDER)
object PyArray_Ravel (ndarray, NPY_ORDER)
npy_intp PyArray_MultiplyList (npy_intp *, int)
int PyArray_MultiplyIntList (int *, int)
void * PyArray_GetPtr (ndarray, npy_intp*)
int PyArray_CompareLists (npy_intp *, npy_intp *, int)
#int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
#int PyArray_As1D (object*, char **, int *, int)
#int PyArray_As2D (object*, char ***, int *, int *, int)
int PyArray_Free (object, void *)
#int PyArray_Converter (object, object*)
int PyArray_IntpFromSequence (object, npy_intp *, int)
object PyArray_Concatenate (object, int)
object PyArray_InnerProduct (object, object)
object PyArray_MatrixProduct (object, object)
object PyArray_CopyAndTranspose (object)
object PyArray_Correlate (object, object, int)
int PyArray_TypestrConvert (int, int)
#int PyArray_DescrConverter (object, dtype*)
#int PyArray_DescrConverter2 (object, dtype*)
int PyArray_IntpConverter (object, PyArray_Dims *)
#int PyArray_BufferConverter (object, chunk)
int PyArray_AxisConverter (object, int *)
int PyArray_BoolConverter (object, npy_bool *)
int PyArray_ByteorderConverter (object, char *)
int PyArray_OrderConverter (object, NPY_ORDER *)
unsigned char PyArray_EquivTypes (dtype, dtype)
#object PyArray_Zeros (int, npy_intp *, dtype, int)
#object PyArray_Empty (int, npy_intp *, dtype, int)
object PyArray_Where (object, object, object)
object PyArray_Arange (double, double, double, int)
#object PyArray_ArangeObj (object, object, object, dtype)
int PyArray_SortkindConverter (object, NPY_SORTKIND *)
object PyArray_LexSort (object, int)
object PyArray_Round (ndarray, int, ndarray)
unsigned char PyArray_EquivTypenums (int, int)
int PyArray_RegisterDataType (dtype)
int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *)
int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND)
#void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
object PyArray_IntTupleFromIntp (int, npy_intp *)
int PyArray_TypeNumFromName (char *)
int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *)
#int PyArray_OutputConverter (object, ndarray*)
object PyArray_BroadcastToShape (object, npy_intp *, int)
void _PyArray_SigintHandler (int)
void* _PyArray_GetSigintBuf ()
#int PyArray_DescrAlignConverter (object, dtype*)
#int PyArray_DescrAlignConverter2 (object, dtype*)
int PyArray_SearchsideConverter (object, void *)
object PyArray_CheckAxis (ndarray, int *, int)
npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
int PyArray_CompareString (char *, char *, size_t)
# Typedefs that matches the runtime dtype objects in
# the numpy module.
......@@ -252,8 +665,8 @@ ctypedef npy_float64 float64_t
#ctypedef npy_float80 float80_t
#ctypedef npy_float128 float128_t
ctypedef npy_complex64 complex64_t
ctypedef npy_complex128 complex128_t
ctypedef float complex complex64_t
ctypedef double complex complex128_t
# The int types are mapped a bit surprising --
# numpy.int corresponds to 'l' and numpy.long to 'q'
......
CC = gcc
CYTHON = ./../bin/cython
CYTHON_FREEZE = ../../bin/cython_freeze.py
CFLAGS = -fPIC -g -O2 -Wall -Wextra
CPPFLAGS = -I /usr/include/python2.6
LDFLAGS = -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
LDLIBS = /usr/lib/python2.6/config/libpython2.6.a \
-lm -ldl -pthread -lutil -lz
# Name of executable
TARGET = nCr
# List of Cython source files, with main module first.
CYTHON_SOURCE = combinatorics.pyx cmath.pyx
all : $(TARGET)
$(TARGET) : $(TARGET).o $(CYTHON_SOURCE:.pyx=.o)
$(TARGET).c :
$(CYTHON_FREEZE) $(CYTHON_SOURCE:.pyx=) > $@
%.c : %.pyx
$(CYTHON) $(CYTHONFLAGS) $^
clean:
$(RM) *.o *.c $(TARGET)
.PHONY: clean
.SECONDARY: $(CYTHON_SOURCE:.pyx=.c)
NAME
====
cython_freeze.py - create a C file for embedding Cython modules
SYNOPSIS
========
cython_freeze.py module [...]
DESCRIPTION
===========
**cython_freeze.py** generates a C source file to embed a Python interpreter
with one or more Cython modules built in. This allows one to create a single
executable from Cython code, without having to have separate shared objects
for each Cython module.
A major advantage of this approach is that it allows debuging with gprof(1),
which does not work with shared objects.
Note that this method differs from ``cython --embed``. The ``--embed`` options
modifies the resulting C source file to include a ``main()`` function, so it
can only be used on a single Cython module. The advantage ``--embed`` is
simplicity. This module, on the other hand, can be used with multiple
modules, but it requires another C source file to be created.
EXAMPLE
=======
In the example directory, there exist two Cython modules:
cmath.pyx
A module that interfaces with the -lm library.
combinatorics.pyx
A module that implements n-choose-r using cmath.
Both modules have the Python idiom ``if __name__ == "__main__"``, which only
execute if that module is the "main" module. If run as main, cmath prints the
factorial of the argument, while combinatorics prints n-choose-r.
The provided Makefile creates an executable, *nCr*, using combinatorics as the
"main" module. It basically performs the following (ignoring the compiler
flags)::
$ cython_freeze.py combintorics cmath > nCr.c
$ cython combinatorics.pyx
$ cython cmath.pyx
$ gcc nCr.c -o nCr.o
$ gcc combinatorics.c -o combinatorics.o
$ gcc cmath.c -o cmath.o
$ gcc nCr.o combinatorics.o cmath.o -o nCr
Because the combinatorics module was listed first, its ``__name__`` is set
to ``"__main__"``, while cmath's is set to ``"cmath"``. The executable now
contains a Python interpreter and both Cython modules. ::
$ ./nCr
USAGE: ./nCr n r
Prints n-choose-r.
$ ./nCr 15812351235 12
5.10028093999e+113
PREREQUISITES
=============
Cython 0.11.2 (or newer, assuming the API does not change)
SEE ALSO
========
* `Python <http://www.python.org>`_
* `Cython <http://www.cython.org>`_
* `freeze.py <http://wiki.python.org/moin/Freeze>`_
cdef extern from "math.h":
double c_lgamma "lgamma" (double)
double c_exp "exp" (double)
def exp(n):
"""Return e**n."""
return c_exp(n)
def lfactorial(n):
"""Return an estimate of the log factorial of n."""
return c_lgamma(n+1)
def factorial(n):
"""Return an estimate of the factorial of n."""
return c_exp( c_lgamma(n+1) )
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
sys.stderr.write("USAGE: %s n\nPrints n!.\n" % sys.argv[0])
sys.exit(1)
n = map(float, sys.argv[1:])
print factorial(n)
import cmath
def nCr(n, r):
"""Return the number of ways to choose r elements of a set of n."""
return cmath.exp( cmath.lfactorial(n) - cmath.lfactorial(r)
- cmath.lfactorial(n-r) )
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
sys.stderr.write("USAGE: %s n r\nPrints n-choose-r.\n" % sys.argv[0])
sys.exit(1)
n, r = map(float, sys.argv[1:])
print nCr(n, r)
......@@ -4,6 +4,12 @@ from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
try:
from numpy.distutils.misc_util import get_numpy_include_dirs
numpy_include_dirs = get_numpy_include_dirs()
except:
numpy_include_dirs = []
ext_modules=[
Extension("primes", ["primes.pyx"]),
Extension("spam", ["spam.pyx"]),
......@@ -11,7 +17,7 @@ ext_modules=[
for file in glob.glob("*.pyx"):
if file != "numeric_demo.pyx":
ext_modules.append(Extension(file[:-4], [file]))
ext_modules.append(Extension(file[:-4], [file], include_dirs = numpy_include_dirs))
setup(
name = 'Demos',
......
#!/usr/bin/env python
"""
Create a C file for embedding one or more Cython source files.
Requires Cython 0.11.2 (or perhaps newer).
See README.rst for more details.
"""
import sys
if len(sys.argv) < 2:
print >>sys.stderr, "USAGE: %s module [module ...]" % sys.argv[0]
sys.exit(1)
def format_modname(name):
if name.endswith('.pyx'):
name = name[:-4]
return name.replace('.','_')
modules = [format_modname(x) for x in sys.argv[1:]]
print """
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#if PY_MAJOR_VERSION < 3
# define MODINIT(name) init ## name
#else
# define MODINIT(name) PyInit_ ## name
#endif
"""
for name in modules:
print "PyMODINIT_FUNC MODINIT(%s) (void);" % name
print """
static struct _inittab inittab[] = {"""
for name in modules:
print ' {"%(name)s", MODINIT(%(name)s)},' % {'name' : name}
print """ {NULL, NULL}
};
extern int __pyx_module_is_main_%(main)s;
#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
int main(int argc, char** argv) {
#else
int wmain(int argc, wchar_t **argv) {
#endif
int r = 0;
PyObject *m = NULL;
if (PyImport_ExtendInittab(inittab)) {
fprintf(stderr, "No memory\\n");
exit(1);
}
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
__pyx_module_is_main_%(main)s = 1;
m = PyImport_ImportModule(inittab[0].name);
if (!m) {
r = 1;
PyErr_Print(); /* This exits with the right code if SystemExit. */
if (Py_FlushLine()); PyErr_Clear();
}
Py_XDECREF(m);
Py_Finalize();
return r;
}
""" % {'main' : modules[0]}
......@@ -14,3 +14,6 @@ large_consts_T237
bad_c_struct_T252
missing_baseclass_in_predecl_T262
ifelseexpr_T267
# Not yet enabled
profile_test
nonexisting(3, with_kw_arg=4)
_ERRORS = u"""
1:11: undeclared name not builtin: nonexisting
"""
......@@ -4,6 +4,21 @@
[2, 1]
>>> a.g()
(False, True)
>>> del_item({1: 'a', 2: 'b'}, 1)
{2: 'b'}
>>> del_item(range(10), 2)
[0, 1, 3, 4, 5, 6, 7, 8, 9]
>>> del_dict({1: 'a', 2: 'b'}, 1)
{2: 'b'}
>>> del_list(range(5), 3)
[0, 1, 2, 4]
>>> del_int(range(5), 3)
[0, 1, 2, 4]
>>> del_list_int(range(5), 3)
[0, 1, 2, 4]
>>> del_int({-1: 'neg', 1: 'pos'}, -1)
{1: 'pos'}
"""
class A:
......@@ -16,3 +31,23 @@ class A:
self.a = 3
del self.a
return (hasattr(self, u"a"), hasattr(self, u"g"))
def del_item(L, o):
del L[o]
return L
def del_dict(dict D, o):
del D[o]
return D
def del_list(list L, o):
del L[o]
return L
def del_int(L, int i):
del L[i]
return L
def del_list_int(L, int i):
del L[i]
return L
# -*- coding: utf-8 -*-
__doc__ = u"""
#>>> a
#Traceback (most recent call last):
......@@ -43,6 +45,21 @@ __doc__ = u"""
>>> list(add_iter())
[2, 3, 4, 5]
>>> d = {}
>>> test_encoding(d, None)
>>> print(d['b'])
üöä
>>> d = {}
>>> test_encoding_unicode(d, None)
>>> print(d['b'])
üöä
>>> d = dict(a=1, c=3)
>>> test_compile(d)
>>> d['b']
4
>>> # errors
>>> d1, d2 = {}, {}
......@@ -76,3 +93,23 @@ def test():
yield x+1
""" % varref in d
return d[u'test']
import sys
def test_encoding(d1, d2):
if sys.version_info[0] >= 3:
s = "b = 'üöä'"
else:
s = "# -*- coding: utf-8 -*-" + "\n" + "b = u'üöä'"
exec s in d1, d2
def test_encoding_unicode(d1, d2):
if sys.version_info[0] >= 3:
s = u"b = 'üöä'"
else:
s = u"b = u'üöä'"
exec s in d1, d2
def test_compile(d):
c = compile(u"b = a+c", u"<string>", u"exec")
exec c in d
......@@ -194,6 +194,11 @@ try:
Traceback (most recent call last):
...
ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes)
>>> test_complextypes()
1,1
1,1
8,16
"""
except:
......@@ -376,3 +381,15 @@ def test_unpacked_align(np.ndarray[UnpackedStruct] arr):
arr[0].a = 22
arr[0].b = 23
return repr(arr).replace('<', '!').replace('>', '!')
def test_complextypes():
cdef np.complex64_t x64 = 1, y64 = 1j
cdef np.complex128_t x128 = 1, y128 = 1j
x64 = x64 + y64
print "%.0f,%.0f" % (x64.real, x64.imag)
x128 = x128 + y128
print "%.0f,%.0f" % (x128.real, x128.imag)
print "%d,%d" % (sizeof(x64), sizeof(x128))
__doc__ = u"""
>>> import os, tempfile, cProfile as profile, pstats
>>> statsfile = tempfile.mkstemp()[1]
>>> profile.runctx("test_profile(100)", locals(), globals(), statsfile)
>>> s = pstats.Stats(statsfile)
>>> short_stats = dict([(k[2], v[1]) for k,v in s.stats.items()])
>>> short_stats['f_def']
100
>>> short_stats['f_cdef']
100
>>> short_stats['f_inline']
Traceback (most recent call last):
...
KeyError: 'f_inline'
>>> short_stats['f_inline_prof']
100
>>> short_stats['f_noprof']
Traceback (most recent call last):
...
KeyError: 'f_noprof'
>>> short_stats['f_raise']
100
>>> os.unlink(statsfile)
"""
cimport cython
def test_profile(long N):
cdef long i, n = 0
for i from 0 <= i < N:
n += f_def(i)
n += f_cdef(i)
n += f_inline(i)
n += f_inline_prof(i)
n += f_noprof(i)
try:
n += f_raise(i+2)
except RuntimeError:
pass
return n
def f_def(long a):
return a
cdef long f_cdef(long a):
return a
cdef inline long f_inline(long a):
return a
@cython.profile(True)
cdef inline long f_inline_prof(long a):
return a
@cython.profile(False)
cdef int f_noprof(long a):
return a
cdef long f_raise(long) except -2:
raise RuntimeError
......@@ -74,6 +74,17 @@ __doc__ = u"""
>>> switch_or(4)
0
>>> switch_in(0)
0
>>> switch_in(1)
1
>>> switch_in(2)
0
>>> switch_in(7)
1
>>> switch_in(8)
0
>>> switch_short(0)
0
>>> switch_short(1)
......@@ -161,6 +172,11 @@ def switch_or(int x):
return 0
return -1
def switch_in(int X):
if X in (1,3,5,7):
return 1
return 0
def switch_short(int x):
if x == 1:
return 1
......
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