Commit ae714eac authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents 91d8ecbc d0d88e68
......@@ -27,8 +27,6 @@ Options:
-z, --pre-import <module> If specified, assume undeclared names in this
module. Emulates the behavior of putting
"from <module> import *" at the top of the file.
--incref-local-binop Force local an extra incref on local variables before
performing any binary operations.
--cleanup <level> Release interned objects on python exit, for memory debugging.
Level indicates aggressiveness, default 0 releases nothing.
-w, --working <directory> Sets the working directory for Cython (the directory modules
......@@ -108,8 +106,6 @@ def parse_command_line(args):
Options.embed_pos_in_docstring = 1
elif option in ("-z", "--pre-import"):
Options.pre_import = pop_arg()
elif option == "--incref-local-binop":
Options.incref_local_binop = 1
elif option == "--cleanup":
Options.generate_cleanup_code = int(pop_arg())
elif option in ("-D", "--no-docstrings"):
......
......@@ -1518,22 +1518,24 @@ class IteratorNode(ExprNode):
def generate_result_code(self, code):
is_builtin_sequence = self.sequence.type is list_type or \
self.sequence.type is tuple_type
self.sequence.type is tuple_type
may_be_a_sequence = is_builtin_sequence or not self.sequence.type.is_builtin_type
if is_builtin_sequence:
code.putln(
"if (likely(%s != Py_None)) {" % self.sequence.py_result())
else:
elif may_be_a_sequence:
code.putln(
"if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
self.sequence.py_result(),
self.sequence.py_result()))
code.putln(
"%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
self.counter_cname,
self.result(),
self.sequence.py_result(),
self.result()))
code.putln("} else {")
if may_be_a_sequence:
code.putln(
"%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
self.counter_cname,
self.result(),
self.sequence.py_result(),
self.result()))
code.putln("} else {")
if is_builtin_sequence:
code.putln(
'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
......@@ -1545,7 +1547,8 @@ class IteratorNode(ExprNode):
self.sequence.py_result(),
code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
code.putln("}")
if may_be_a_sequence:
code.putln("}")
class NextNode(AtomicExprNode):
......@@ -1564,12 +1567,15 @@ class NextNode(AtomicExprNode):
self.is_temp = 1
def generate_result_code(self, code):
if self.iterator.sequence.type is list_type:
sequence_type = self.iterator.sequence.type
if sequence_type is list_type:
type_checks = [(list_type, "List")]
elif self.iterator.sequence.type is tuple_type:
elif sequence_type is tuple_type:
type_checks = [(tuple_type, "Tuple")]
else:
elif not sequence_type.is_builtin_type:
type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
else:
type_checks = []
for py_type, prefix in type_checks:
if len(type_checks) > 1:
......@@ -1781,6 +1787,12 @@ class IndexNode(ExprNode):
self.is_buffer_access = False
self.base.analyse_types(env)
if self.base.type.is_error:
# Do not visit child tree if base is undeclared to avoid confusing
# error messages
self.type = PyrexTypes.error_type
return
# Handle the case where base is a literal char* (and we expect a string, not an int)
if isinstance(self.base, BytesNode):
self.base = self.base.coerce_to_pyobject(env)
......@@ -3086,7 +3098,7 @@ class AttributeNode(ExprNode):
self.put_nonecheck(code)
select_code = self.result()
if self.type.is_pyobject:
if self.type.is_pyobject and self.use_managed_ref:
rhs.make_owned_reference(code)
code.put_giveref(rhs.py_result())
code.put_gotref(select_code)
......@@ -4541,8 +4553,6 @@ class BinopNode(ExprNode):
self.coerce_operands_to_pyobjects(env)
self.type = py_object_type
self.is_temp = 1
if Options.incref_local_binop and self.operand1.type.is_pyobject:
self.operand1 = self.operand1.coerce_to_temp(env)
else:
self.analyse_c_operation(env)
......
......@@ -138,7 +138,7 @@ class Context(object):
IntroduceBufferAuxiliaryVars(self),
_check_c_declarations,
AnalyseExpressionsTransform(self),
OptimizeBuiltinCalls(),
OptimizeBuiltinCalls(self),
IterationTransform(),
SwitchTransform(),
DropRefcountingTransform(),
......
......@@ -2515,13 +2515,30 @@ refnanny_utility_code = UtilityCode(proto="""
main_method = UtilityCode(
impl = """
#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif
#if PY_MAJOR_VERSION < 3
int main(int argc, char** argv) {
#else
#elif defined(WIN32) || defined(MS_WINDOWS)
int wmain(int argc, wchar_t **argv) {
#else
static int __Pyx_main(int argc, wchar_t **argv) {
#endif
int r = 0;
PyObject* m = NULL;
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
* exceptions by default. Here we disable them.
*/
#ifdef __FreeBSD__
fp_except_t m;
m = fpgetmask();
fpsetmask(m & ~FP_X_OFL);
#endif
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
......@@ -2529,17 +2546,157 @@ int wmain(int argc, wchar_t **argv) {
#if PY_MAJOR_VERSION < 3
init%(module_name)s();
#else
m = PyInit_%(module_name)s(name);
m = PyInit_%(module_name)s();
#endif
if (PyErr_Occurred() != NULL) {
r = 1;
PyErr_Print(); /* This exits with the right code if SystemExit. */
#if PY_MAJOR_VERSION < 3
if (Py_FlushLine()) PyErr_Clear();
#endif
}
Py_XDECREF(m);
Py_Finalize();
return r;
}
#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
#include <locale.h>
static wchar_t*
__Pyx_char2wchar(char* arg)
{
wchar_t *res;
#ifdef HAVE_BROKEN_MBSTOWCS
/* Some platforms have a broken implementation of
* mbstowcs which does not count the characters that
* would result from conversion. Use an upper bound.
*/
size_t argsize = strlen(arg);
#else
size_t argsize = mbstowcs(NULL, arg, 0);
#endif
size_t count;
unsigned char *in;
wchar_t *out;
#ifdef HAVE_MBRTOWC
mbstate_t mbs;
#endif
if (argsize != (size_t)-1) {
res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
if (!res)
goto oom;
count = mbstowcs(res, arg, argsize+1);
if (count != (size_t)-1) {
wchar_t *tmp;
/* Only use the result if it contains no
surrogate characters. */
for (tmp = res; *tmp != 0 &&
(*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
;
if (*tmp == 0)
return res;
}
free(res);
}
/* Conversion failed. Fall back to escaping with surrogateescape. */
#ifdef HAVE_MBRTOWC
/* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
/* Overallocate; as multi-byte characters are in the argument, the
actual output could use less memory. */
argsize = strlen(arg) + 1;
res = malloc(argsize*sizeof(wchar_t));
if (!res) goto oom;
in = (unsigned char*)arg;
out = res;
memset(&mbs, 0, sizeof mbs);
while (argsize) {
size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
if (converted == 0)
/* Reached end of string; null char stored. */
break;
if (converted == (size_t)-2) {
/* Incomplete character. This should never happen,
since we provide everything that we have -
unless there is a bug in the C library, or I
misunderstood how mbrtowc works. */
fprintf(stderr, "unexpected mbrtowc result -2\\n");
return NULL;
}
if (converted == (size_t)-1) {
/* Conversion error. Escape as UTF-8b, and start over
in the initial shift state. */
*out++ = 0xdc00 + *in++;
argsize--;
memset(&mbs, 0, sizeof mbs);
continue;
}
if (*out >= 0xd800 && *out <= 0xdfff) {
/* Surrogate character. Escape the original
byte sequence with surrogateescape. */
argsize -= converted;
while (converted--)
*out++ = 0xdc00 + *in++;
continue;
}
/* successfully converted some bytes */
in += converted;
argsize -= converted;
out++;
}
#else
/* Cannot use C locale for escaping; manually escape as if charset
is ASCII (i.e. escape all bytes > 128. This will still roundtrip
correctly in the locale's charset, which must be an ASCII superset. */
res = malloc((strlen(arg)+1)*sizeof(wchar_t));
if (!res) goto oom;
in = (unsigned char*)arg;
out = res;
while(*in)
if(*in < 128)
*out++ = *in++;
else
*out++ = 0xdc00 + *in++;
*out = 0;
#endif
return res;
oom:
fprintf(stderr, "out of memory\\n");
return NULL;
}
int
main(int argc, char **argv)
{
wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
/* We need a second copies, as Python might modify the first one. */
wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
int i, res;
char *oldloc;
if (!argv_copy || !argv_copy2) {
fprintf(stderr, "out of memory\\n");
return 1;
}
oldloc = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "");
for (i = 0; i < argc; i++) {
argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
if (!argv_copy[i])
return 1;
}
setlocale(LC_ALL, oldloc);
free(oldloc);
res = __Pyx_main(argc, argv_copy);
for (i = 0; i < argc; i++) {
free(argv_copy2[i]);
}
free(argv_copy);
free(argv_copy2);
return res;
}
#endif
""")
packed_struct_utility_code = UtilityCode(proto="""
......
......@@ -3165,8 +3165,6 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
self.rhs.analyse_types(env)
self.lhs.analyse_target_types(env)
if Options.incref_local_binop and self.dup.type.is_pyobject:
self.dup = self.dup.coerce_to_temp(env)
import ExprNodes
if self.lhs.type.is_pyobject:
self.rhs = self.rhs.coerce_to_pyobject(env)
......
This diff is collapsed.
......@@ -10,12 +10,6 @@ gcc_branch_hints = 1
pre_import = None
docstrings = True
# This is a SAGE-specific option that will
# cause Cython to incref local variables before
# performing a binary operation on them, for
# safe detection of inplace operators.
incref_local_binop = 0
# Decref global variables in this module on exit for garbage collection.
# 0: None, 1+: interned objects, 2+: cdef globals, 3+: types objects
# Mostly for reducing noise for Valgrind, only executes at process exit
......
from Cython.Compiler.Visitor import VisitorTransform, CythonTransform, TreeVisitor
from Cython.Compiler.Visitor import VisitorTransform, TreeVisitor
from Cython.Compiler.Visitor import CythonTransform, EnvTransform
from Cython.Compiler.ModuleNode import ModuleNode
from Cython.Compiler.Nodes import *
from Cython.Compiler.ExprNodes import *
......@@ -983,21 +984,6 @@ class GilCheck(VisitorTransform):
return node
class EnvTransform(CythonTransform):
"""
This transformation keeps a stack of the environments.
"""
def __call__(self, root):
self.env_stack = [root.scope]
return super(EnvTransform, self).__call__(root)
def visit_FuncDefNode(self, node):
self.env_stack.append(node.local_scope)
self.visitchildren(node)
self.env_stack.pop()
return node
class TransformBuiltinMethods(EnvTransform):
def visit_SingleAssignmentNode(self, node):
......
......@@ -621,8 +621,8 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, zero = 0;
const int is_unsigned = neg_one > zero;
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) < sizeof(long)) {
long val = __Pyx_PyInt_AsLong(x);
if (unlikely(val != (long)(%(type)s)val)) {
......@@ -646,8 +646,8 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, zero = 0;
const int is_unsigned = neg_one > zero;
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
#if PY_VERSION_HEX < 0x03000000
if (likely(PyInt_Check(x))) {
long val = PyInt_AS_LONG(x);
......@@ -687,8 +687,8 @@ static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, zero = 0;
const int is_unsigned = neg_one > zero;
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) == sizeof(char)) {
if (is_unsigned)
return (%(type)s)__Pyx_PyInt_AsUnsignedChar(x);
......@@ -734,8 +734,8 @@ static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
""",
impl="""
static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
const %(type)s neg_one = (%(type)s)-1, zero = 0;
const int is_unsigned = neg_one > zero;
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) < sizeof(long)) {
return PyInt_FromLong((long)val);
} else if (sizeof(%(type)s) == sizeof(long)) {
......@@ -875,6 +875,7 @@ class CComplexType(CNumericType):
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):
......
......@@ -187,8 +187,8 @@ class FixedSlot(SlotDescriptor):
#
# value string
def __init__(self, slot_name, value, py3k=True):
SlotDescriptor.__init__(self, slot_name, py3k=py3k)
def __init__(self, slot_name, value, py3k=True, py2=True, ifdef=None):
SlotDescriptor.__init__(self, slot_name, py3k=py3k, py2=py2, ifdef=ifdef)
self.value = value
def slot_code(self, scope):
......@@ -198,8 +198,8 @@ class FixedSlot(SlotDescriptor):
class EmptySlot(FixedSlot):
# Descriptor for a type slot whose value is always 0.
def __init__(self, slot_name, py3k=True):
FixedSlot.__init__(self, slot_name, "0", py3k=py3k)
def __init__(self, slot_name, py3k=True, py2=True, ifdef=None):
FixedSlot.__init__(self, slot_name, "0", py3k=py3k, py2=py2, ifdef=ifdef)
class MethodSlot(SlotDescriptor):
......@@ -692,6 +692,8 @@ slot_table = (
EmptySlot("tp_cache"),
EmptySlot("tp_subclasses"),
EmptySlot("tp_weaklist"),
EmptySlot("tp_del"),
EmptySlot("tp_version_tag", ifdef="PY_VERSION_HEX >= 0x02060000"),
)
#------------------------------------------------------------------------------------------
......
......@@ -306,6 +306,22 @@ class ScopeTrackingTransform(CythonTransform):
def visit_CStructOrUnionDefNode(self, node):
return self.visit_scope(node, 'struct')
class EnvTransform(CythonTransform):
"""
This transformation keeps a stack of the environments.
"""
def __call__(self, root):
self.env_stack = [root.scope]
return super(EnvTransform, self).__call__(root)
def visit_FuncDefNode(self, node):
self.env_stack.append(node.local_scope)
self.visitchildren(node)
self.env_stack.pop()
return node
class RecursiveNodeReplacer(VisitorTransform):
"""
Recursively replace all occurrences of a node in a subtree by
......
......@@ -26,6 +26,7 @@ cdef extern from "Python.h":
cdef extern from "numpy/arrayobject.h":
ctypedef Py_intptr_t npy_intp
ctypedef size_t npy_uintp
cdef enum NPY_TYPES:
NPY_BOOL
......@@ -193,7 +194,7 @@ cdef extern from "numpy/arrayobject.h":
cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
ndim = PyArray_NDIM(self)
if sizeof(npy_intp) != sizeof(Py_ssize_t):
copy_shape = 1
else:
......@@ -735,7 +736,8 @@ ctypedef double complex complex128_t
# numpy.int corresponds to 'l' and numpy.long to 'q'
ctypedef npy_long int_t
ctypedef npy_longlong long_t
ctypedef npy_intp intp_t
ctypedef npy_uintp uintp_t
ctypedef npy_ulong uint_t
ctypedef npy_ulonglong ulong_t
......
# Makefile for creating our standalone Cython program
PYVERSION=2.3
PYPREFIX=/usr
PYVERSION=$(shell python -c "import sys; print sys.version[:3]")
PYPREFIX=$(shell python -c "import sys; print sys.prefix")
INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION)
embedded: embedded.o
gcc -o $@ $^ -lpython$(PYVERSION)
gcc -o $@ $^ -lpython$(PYVERSION)
embedded.o: embedded.c
gcc -c $^ $(INCLUDES)
gcc -c $^ $(INCLUDES)
embedded.c: embedded.pyx
@python ../../cython.py --embed embedded.pyx
@python ../../cython.py --embed embedded.pyx
all: embedded
clean:
@echo Cleaning Demos/embed
@rm -f *~ *.o *.so core core.* *.c embedded
@rm -f *~ *.o *.so core core.* *.c embedded test.output
test: clean all
./embedded > test.output
python assert_equal.py embedded.output test.output
import sys
if open(sys.argv[1]).read() != open(sys.argv[2]).read():
print "Files differ"
sys.exit(1)
else:
print "Files identical"
__main__
Hi, I'm embedded.
CC = gcc
CYTHON = ./../bin/cython
CYTHON_FREEZE = ../../bin/cython_freeze.py
CYTHON = ../../bin/cython
CYTHON_FREEZE = ../../bin/cython_freeze
PYTHON = python
RST2HTML = rst2html
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
PY_LDFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join([g("LINKFORSHARED"), "-L"+g("LIBPL")]) + "\n")')
PY_CPPFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import *; import sys; sys.stdout.write("-I"+get_python_inc() + "\n")')
PY_LDLIBS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join(["-lpython"+g("VERSION"), g("SYSLIBS"), g("LIBS"), g("LOCALMODLIBS")]) + "\n")')
CFLAGS = -fPIC -fno-strict-aliasing -g -O2 -Wall -Wextra
CPPFLAGS = $(PY_CPPFLAGS)
LDFLAGS = $(PY_LDFLAGS)
LDLIBS = $(PY_LDLIBS)
# Name of executable
TARGET = nCr
TARGETS = nCr python
# List of Cython source files, with main module first.
CYTHON_SOURCE = combinatorics.pyx cmath.pyx
CYTHON_SECONDARY = $(CYTHON_SOURCE:.pyx=.c) $(TARGETS:=.c)
all : $(TARGET)
all : $(TARGETS)
html : README.html
$(TARGET) : $(TARGET).o $(CYTHON_SOURCE:.pyx=.o)
$(TARGETS) : % : %.o $(CYTHON_SOURCE:.pyx=.o)
$(TARGET).c :
nCr.c :
$(CYTHON_FREEZE) $(CYTHON_SOURCE:.pyx=) > $@
python.c :
$(CYTHON_FREEZE) --pymain $(CYTHON_SOURCE:.pyx=) > $@
%.c : %.pyx
$(CYTHON) $(CYTHONFLAGS) $^
%.html : %.txt
$(RST2HTML) $^ $@
clean:
$(RM) *.o *.c $(TARGET)
$(RM) *.o $(CYTHON_SECONDARY) $(TARGETS) README.html
.PHONY: clean
.SECONDARY: $(CYTHON_SOURCE:.pyx=.c)
.SECONDARY: $(CYTHON_SECONDARY)
NAME
====
cython_freeze.py - create a C file for embedding Cython modules
cython_freeze - create a C file for embedding Cython modules
SYNOPSIS
========
cython_freeze.py module [...]
cython_freeze [-o outfile] [-p] module [...]
DESCRIPTION
===========
**cython_freeze.py** generates a C source file to embed a Python interpreter
**cython_freeze** 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.
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.
A major advantage of this approach is that it allows debuging with gprof(1),
which does not work with shared objects.
Unless ``-p`` is given, the first module's ``__name__`` is set to
``"__main__"`` and is imported on startup; if ``-p`` is given, a normal Python
interpreter is built, with the given modules built into the binary.
Note that this method differs from ``cython --embed``. The ``--embed`` options
modifies the resulting C source file to include a ``main()`` function, so it
......@@ -28,10 +30,17 @@ simplicity. This module, on the other hand, can be used with multiple
modules, but it requires another C source file to be created.
OPTIONS
=======
-o FILE, --outfile=FILE write output to FILE instead of standard output
-p, --pymain do not automatically run the first module as __main__
EXAMPLE
=======
In the example directory, there exist two Cython modules:
In the Demos/freeze directory, there exist two Cython modules:
cmath.pyx
A module that interfaces with the -lm library.
......@@ -47,12 +56,12 @@ 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_freeze combinatorics 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 -c nCr.c
$ gcc -c combinatorics.c
$ gcc -c cmath.c
$ gcc nCr.o combinatorics.o cmath.o -o nCr
Because the combinatorics module was listed first, its ``__name__`` is set
......@@ -65,7 +74,27 @@ contains a Python interpreter and both Cython modules. ::
$ ./nCr 15812351235 12
5.10028093999e+113
You may wish to build a normal Python interpreter, rather than having one
module as "main". This may happen if you want to use your module from an
interactive shell or from another script, yet you still want it statically
linked so you can profile it with gprof. To do this, add the ``--pymain``
flag to ``cython_freeze``. In the Makefile, the *python* executable is built
like this. ::
$ cython_freeze --pymain combinatorics cmath -o python.c
$ gcc -c python.c
$ gcc python.o combinatorics.o cmath.o -o python
Now ``python`` is a normal Python interpreter, but the cmath and combinatorics
modules will be built into the executable. ::
$ ./python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> cmath.factorial(155)
4.7891429014634364e+273
PREREQUISITES
......
......@@ -19,6 +19,6 @@ 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:])
sys.exit(2)
n, = map(float, sys.argv[1:])
print factorial(n)
......@@ -9,6 +9,6 @@ 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)
sys.exit(2)
n, r = map(float, sys.argv[1:])
print nCr(n, r)
......@@ -9,13 +9,13 @@ clean:
@echo Cleaning Source
@rm -fr build
@rm -f *.pyc */*.pyc */*/*.pyc
@rm -f *.so */*.so */*/*.so
@rm -f *.pyd */*.pyd */*/*.pyd
@rm -f *~ */*~ */*/*~
@rm -f core */core
@rm -f Cython/Compiler/Parsing.{c,so,pyd}
@rm -f Cython/Compiler/Scanning.{c,so,pyd}
@rm -f Cython/Compiler/Visitor.{c,so,pyd}
@rm -f Cython/Runtime/refnanny.{c,so,pyd}
@rm -f Cython/Plex/Scanners.{c,so,pyd}
@rm -f Cython/Compiler/*.c
@rm -f Cython/Plex/*.c
@rm -f Cython/Runtime/refnanny.c
@(cd Demos; $(MAKE) clean)
testclean:
......
This diff is collapsed.
#!/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 Demos/freeze/README.txt for more details.
"""
import optparse
usage= '%prog [-o outfile] [-p] module [module ...]'
description = 'Create a C file for embedding Cython modules.'
p = optparse.OptionParser(usage=usage, description=description)
p.add_option('-o', '--output', metavar='FILE',
help='write output to FILE instead of standard output')
p.add_option('-p', '--pymain', action='store_true', default=False,
help='do not automatically run the first module as __main__')
options, args = p.parse_args()
if len(args) < 1:
p.print_help()
p.exit(1)
if options.output:
import sys
old_stdout = sys.stdout
sys.stdout = open(options.output, 'w')
def format_modname(name):
if name.endswith('.pyx'):
name = name[:-4]
elif name.endswith('.py'):
name = name[:-3]
return name.replace('.','_')
modules = [format_modname(x) for x in args]
print """\
#include <Python.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif
#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}
};
""",
if not options.pymain:
print "\nextern int __pyx_module_is_main_%s;" % modules[0]
print """
#if PY_MAJOR_VERSION < 3
int main(int argc, char** argv) {
#elif defined(WIN32) || defined(MS_WINDOWS)
int wmain(int argc, wchar_t **argv) {
#else
static int python_main(int argc, wchar_t **argv) {
#endif
""",
if not options.pymain:
print """\
PyObject *m = NULL;
int r = 0;
""",
print """\
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
* exceptions by default. Here we disable them.
*/
#ifdef __FreeBSD__
fp_except_t m;
m = fpgetmask();
fpsetmask(m & ~FP_X_OFL);
#endif
if (PyImport_ExtendInittab(inittab)) {
fprintf(stderr, "No memory\\n");
exit(1);
}
""",
if options.pymain:
print """\
return Py_Main(argc, argv);
}
"""
else:
print """\
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_MAJOR_VERSION < 3
if (Py_FlushLine())
PyErr_Clear();
#endif
}
Py_XDECREF(m);
Py_Finalize();
return r;
}
""" % {'main' : modules[0]},
print r"""
#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
static wchar_t*
char2wchar(char* arg)
{
wchar_t *res;
#ifdef HAVE_BROKEN_MBSTOWCS
/* Some platforms have a broken implementation of
* mbstowcs which does not count the characters that
* would result from conversion. Use an upper bound.
*/
size_t argsize = strlen(arg);
#else
size_t argsize = mbstowcs(NULL, arg, 0);
#endif
size_t count;
unsigned char *in;
wchar_t *out;
#ifdef HAVE_MBRTOWC
mbstate_t mbs;
#endif
if (argsize != (size_t)-1) {
res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
if (!res)
goto oom;
count = mbstowcs(res, arg, argsize+1);
if (count != (size_t)-1) {
wchar_t *tmp;
/* Only use the result if it contains no
surrogate characters. */
for (tmp = res; *tmp != 0 &&
(*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
;
if (*tmp == 0)
return res;
}
free(res);
}
/* Conversion failed. Fall back to escaping with surrogateescape. */
#ifdef HAVE_MBRTOWC
/* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
/* Overallocate; as multi-byte characters are in the argument, the
actual output could use less memory. */
argsize = strlen(arg) + 1;
res = malloc(argsize*sizeof(wchar_t));
if (!res) goto oom;
in = (unsigned char*)arg;
out = res;
memset(&mbs, 0, sizeof mbs);
while (argsize) {
size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
if (converted == 0)
/* Reached end of string; null char stored. */
break;
if (converted == (size_t)-2) {
/* Incomplete character. This should never happen,
since we provide everything that we have -
unless there is a bug in the C library, or I
misunderstood how mbrtowc works. */
fprintf(stderr, "unexpected mbrtowc result -2\n");
return NULL;
}
if (converted == (size_t)-1) {
/* Conversion error. Escape as UTF-8b, and start over
in the initial shift state. */
*out++ = 0xdc00 + *in++;
argsize--;
memset(&mbs, 0, sizeof mbs);
continue;
}
if (*out >= 0xd800 && *out <= 0xdfff) {
/* Surrogate character. Escape the original
byte sequence with surrogateescape. */
argsize -= converted;
while (converted--)
*out++ = 0xdc00 + *in++;
continue;
}
/* successfully converted some bytes */
in += converted;
argsize -= converted;
out++;
}
#else
/* Cannot use C locale for escaping; manually escape as if charset
is ASCII (i.e. escape all bytes > 128. This will still roundtrip
correctly in the locale's charset, which must be an ASCII superset. */
res = malloc((strlen(arg)+1)*sizeof(wchar_t));
if (!res) goto oom;
in = (unsigned char*)arg;
out = res;
while(*in)
if(*in < 128)
*out++ = *in++;
else
*out++ = 0xdc00 + *in++;
*out = 0;
#endif
return res;
oom:
fprintf(stderr, "out of memory\n");
return NULL;
}
int
main(int argc, char **argv)
{
wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
/* We need a second copies, as Python might modify the first one. */
wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
int i, res;
char *oldloc;
if (!argv_copy || !argv_copy2) {
fprintf(stderr, "out of memory\n");
return 1;
}
oldloc = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "");
for (i = 0; i < argc; i++) {
argv_copy2[i] = argv_copy[i] = char2wchar(argv[i]);
if (!argv_copy[i])
return 1;
}
setlocale(LC_ALL, oldloc);
free(oldloc);
res = python_main(argc, argv_copy);
for (i = 0; i < argc; i++) {
free(argv_copy2[i]);
}
free(argv_copy);
free(argv_copy2);
return res;
}
#endif"""
#!/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]
elif name.endswith('.py'):
name = name[:-3]
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]}
......@@ -127,6 +127,10 @@ class TestBuilder(object):
continue
suite.addTest(
self.handle_directory(path, filename))
if sys.platform not in ['win32'] and sys.version_info[0] < 3:
# Non-Windows makefile, can't run Cython under Py3.
if [1 for selector in self.selectors if selector("embedded")]:
suite.addTest(unittest.makeSuite(EmbedTest))
return suite
def handle_directory(self, path, context):
......@@ -429,6 +433,7 @@ is_private_field = re.compile('^_[^_]').match
class _FakeClass(object):
def __init__(self, **kwargs):
self.shortDescription = lambda x: kwargs.get('module_name')
self.__dict__.update(kwargs)
try: # Py2.7+ and Py3.2+
......@@ -555,6 +560,28 @@ def collect_doctests(path, module_prefix, suite, selectors):
except ValueError: # no tests
pass
# TODO: Support cython_freeze needed here as well.
# TODO: Windows support.
class EmbedTest(unittest.TestCase):
working_dir = "Demos/embed"
def setUp(self):
self.old_dir = os.getcwd()
os.chdir(self.working_dir)
os.system("make clean > /dev/null")
def tearDown(self):
try:
os.system("make clean > /dev/null")
except:
pass
os.chdir(self.old_dir)
def test_embed(self):
self.assert_(os.system("make test > make.output") == 0)
class MissingDependencyExcluder:
def __init__(self, deps):
# deps: { module name : matcher func }
......
cdef f(void=None):
pass
cdef struct foo:
int void
cdef class Foo:
cdef int void
cdef extern void spam(char *s)
cdef struct Grail:
char silly[42]
cdef void eggs():
cdef char silly[42]
cdef Grail grail
spam(silly)
spam(grail.silly)
eggs()
......@@ -3,5 +3,8 @@ ctypedef struct Foo:
cdef Foo f():
blarg = 1 + 2
cdef Foo foo
foo.blarg = blarg
return foo
f()
......@@ -5,27 +5,33 @@ __doc__ = u"""
>>> x
46
>>> add_pyrange(10)
46
>>> add_py(10)
46
>>> add_c(10)
46
"""
def add_pyrange(max):
"""
>>> add_pyrange(10)
46
"""
x = 1
for i in range(max):
x = x + i
return x
def add_py(max):
"""
>>> add_py(10)
46
"""
x = 1
for i from 0 <= i < max:
x = x + i
return x
def add_c(max):
"""
>>> add_c(10)
46
"""
cdef int x,i
x = 1
for i from 0 <= i < max:
......
__doc__ = u"""
def f():
"""
>>> f()
(30, 22)
"""
def f():
"""
cdef int int1, int2, int3
cdef char *ptr1, *ptr2 = "test", *ptr3 = "toast"
int2 = 10
......
__doc__ = u"""
def f(int a):
"""
>>> f(5)
5
"""
def f(int a):
"""
cdef int i,j
cdef int *p
i = a
......
__doc__ = u"""
>>> func1(None)
>>> func1(*[None])
>>> func1(arg=None)
Traceback (most recent call last):
...
TypeError: func1() takes no keyword arguments
>>> func2(None)
>>> func2(*[None])
>>> func2(arg=None)
Traceback (most recent call last):
...
TypeError: func2() takes no keyword arguments
>>> func3(None)
>>> func3(*[None])
>>> func3(arg=None)
>>> A().meth1(None)
>>> A().meth1(*[None])
>>> A().meth1(arg=None)
Traceback (most recent call last):
...
TypeError: meth1() takes no keyword arguments
>>> A().meth2(None)
>>> A().meth2(*[None])
>>> A().meth2(arg=None)
Traceback (most recent call last):
...
TypeError: meth2() takes no keyword arguments
>>> A().meth3(None)
>>> A().meth3(*[None])
>>> A().meth3(arg=None)
"""
cimport cython
def func1(arg):
"""
>>> func1(None)
>>> func1(*[None])
>>> func1(arg=None)
Traceback (most recent call last):
...
TypeError: func1() takes no keyword arguments
"""
pass
@cython.always_allow_keywords(False)
def func2(arg):
"""
>>> func2(None)
>>> func2(*[None])
>>> func2(arg=None)
Traceback (most recent call last):
...
TypeError: func2() takes no keyword arguments
"""
pass
@cython.always_allow_keywords(True)
def func3(arg):
"""
>>> func3(None)
>>> func3(*[None])
>>> func3(arg=None)
"""
pass
cdef class A:
"""
>>> A().meth1(None)
>>> A().meth1(*[None])
>>> A().meth1(arg=None)
Traceback (most recent call last):
...
TypeError: meth1() takes no keyword arguments
>>> A().meth2(None)
>>> A().meth2(*[None])
>>> A().meth2(arg=None)
Traceback (most recent call last):
...
TypeError: meth2() takes no keyword arguments
>>> A().meth3(None)
>>> A().meth3(*[None])
>>> A().meth3(arg=None)
"""
def meth1(self, arg):
pass
......
__doc__ = u"""
>>> a,b = 'a *','b *' # use non-interned strings
>>> and2_assign(2,3) == (2 and 3)
True
>>> and2_assign('a', 'b') == ('a' and 'b')
True
>>> and2_assign(a, b) == (a and b)
True
>>> and2(2,3) == (2 and 3)
True
>>> and2(0,2) == (0 and 2)
True
>>> and2('a', 'b') == ('a' and 'b')
True
>>> and2(a, b) == (a and b)
True
>>> and2('', 'b') == ('' and 'b')
True
>>> and2([], [1]) == ([] and [1])
True
>>> and2([], [a]) == ([] and [a])
True
>>> and3(0,1,2) == (0 and 1 and 2)
True
>>> and3([],(),[1]) == ([] and () and [1])
True
>>> and2_no_result(2,3)
>>> and2_no_result(0,2)
>>> and2_no_result('a','b')
>>> and2_no_result(a,b)
>>> a and b
'b *'
"""
a,b = 'a *','b *' # use non-interned strings
def and2_assign(a,b):
"""
>>> a,b = 'a *','b *' # use non-interned strings
>>> and2_assign(2,3) == (2 and 3)
True
>>> and2_assign('a', 'b') == ('a' and 'b')
True
>>> and2_assign(a, b) == (a and b)
True
"""
c = a and b
return c
def and2(a,b):
"""
>>> and2(2,3) == (2 and 3)
True
>>> and2(0,2) == (0 and 2)
True
>>> and2('a', 'b') == ('a' and 'b')
True
>>> and2(a, b) == (a and b)
True
>>> and2('', 'b') == ('' and 'b')
True
>>> and2([], [1]) == ([] and [1])
True
>>> and2([], [a]) == ([] and [a])
True
"""
return a and b
def and3(a,b,c):
"""
>>> and3(0,1,2) == (0 and 1 and 2)
True
>>> and3([],(),[1]) == ([] and () and [1])
True
"""
d = a and b and c
return d
def and2_no_result(a,b):
"""
>>> and2_no_result(2,3)
>>> and2_no_result(0,2)
>>> and2_no_result('a','b')
>>> and2_no_result(a,b)
>>> a and b
'b *'
"""
a and b
__doc__ = u"""
>>> test_append([])
None
None
None
got error
[1, 2, (3, 4)]
>>> _ = test_append(A())
appending
1
appending
2
appending
(3, 4)
got error
>>> test_append(B())
None
None
None
None
[1, 2, (3, 4), 5, 6]
"""
class A:
def append(self, x):
print u"appending"
......@@ -32,6 +9,28 @@ class B(list):
list.append(self, arg)
def test_append(L):
"""
>>> test_append([])
None
None
None
got error
[1, 2, (3, 4)]
>>> _ = test_append(A())
appending
1
appending
2
appending
(3, 4)
got error
>>> test_append(B())
None
None
None
None
[1, 2, (3, 4), 5, 6]
"""
print L.append(1)
print L.append(2)
print L.append((3,4))
......@@ -40,4 +39,3 @@ def test_append(L):
except TypeError:
print u"got error"
return L
__doc__ = u"""
>>> f0()
(1, 2)
>>> g0()
(1, 2)
>>> f1()
[1, 2]
>>> g1()
[1, 2]
>>> f2()
{1: 2}
>>> g2()
{1: 2}
>>> f3() #doctest: +ELLIPSIS
<argdefault.Foo object at ...>
>>> g3() #doctest: +ELLIPSIS
<argdefault.Foo object at ...>
>>> f4() #doctest: +ELLIPSIS
<argdefault.Bar object at ...>
>>> g4() #doctest: +ELLIPSIS
<argdefault.Bar object at ...>
>>> f5() #doctest: +ELLIPSIS
<argdefault.Bla object at ...>
>>> g5() #doctest: +ELLIPSIS
<argdefault.Bla object at ...>
>>> f6()
7
>>> g6()
7
"""
GLB0 = (1, 2)
def f0(arg=GLB0):
"""
>>> f0()
(1, 2)
"""
return arg
def g0(arg=(1, 2)):
"""
>>> g0()
(1, 2)
"""
return arg
GLB1 = [1, 2]
def f1(arg=GLB1):
"""
>>> f1()
[1, 2]
"""
return arg
def g1(arg=[1, 2]):
"""
>>> g1()
[1, 2]
"""
return arg
cdef GLB2 = {1: 2}
def f2(arg=GLB2):
"""
>>> f2()
{1: 2}
"""
return arg
def g2(arg={1: 2}):
"""
>>> g2()
{1: 2}
"""
return arg
......@@ -60,8 +47,16 @@ class Foo(object):
pass
cdef GLB3 = Foo()
def f3(arg=GLB3):
"""
>>> f3() #doctest: +ELLIPSIS
<argdefault.Foo object at ...>
"""
return arg
def g3(arg=Foo()):
"""
>>> g3() #doctest: +ELLIPSIS
<argdefault.Foo object at ...>
"""
return arg
......@@ -69,8 +64,16 @@ cdef class Bar:
pass
cdef Bar GLB4 = Bar()
def f4(arg=GLB4):
"""
>>> f4() #doctest: +ELLIPSIS
<argdefault.Bar object at ...>
"""
return arg
def g4(arg=Bar()):
"""
>>> g4() #doctest: +ELLIPSIS
<argdefault.Bar object at ...>
"""
return arg
......@@ -78,13 +81,29 @@ cdef class Bla:
pass
cdef Bla GLB5 = Bla()
def f5(Bla arg=GLB5):
"""
>>> f5() #doctest: +ELLIPSIS
<argdefault.Bla object at ...>
"""
return arg
def g5(Bla arg=Bla()):
"""
>>> g5() #doctest: +ELLIPSIS
<argdefault.Bla object at ...>
"""
return arg
cdef int GLB6 = 7
def f6(int arg=GLB6):
"""
>>> f6()
7
"""
return arg
def g6(int arg=7):
"""
>>> g6()
7
"""
return arg
__doc__ = u"""
>>> test_literal_list_slice_all()
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start()
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_end()
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_end()
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_param(4)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_param(3)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_param(5)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_end_param(5)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_end_param(4)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_end_param(6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_end_param(2,7)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_end_param(3,7)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_start_end_param(1,7)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_end_param(2,6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_start_end_param(2,8)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_end_param(3,6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 3
>>> test_literal_list_slice_start_end_param(1,8)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 7
>>> test_ptr_literal_list_slice_all()
(1, 2, 3, 4, 5)
>>> test_ptr_literal_list_slice_start()
(1, 2, 3, 4, 5)
>>> test_ptr_literal_list_slice_end()
(1, 2, 3, 4, 5)
"""
# this doesn't work - it would reassign the array address!
#
#def test_literal_list():
......@@ -63,54 +6,124 @@ ValueError: Assignment to slice of wrong length, expected 5, got 7
# return (a[0], a[1], a[2], a[3], a[4])
def test_literal_list_slice_all():
"""
>>> test_literal_list_slice_all()
(1, 2, 3, 4, 5)
"""
cdef int a[5] # = [5,4,3,2,1]
a[:] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
def test_literal_list_slice_start():
"""
>>> test_literal_list_slice_start()
(1, 2, 3, 4, 5)
"""
cdef int a[7] # = [7,6,5,4,3,2,1]
a[2:] = [1,2,3,4,5]
return (a[2], a[3], a[4], a[5], a[6])
def test_literal_list_slice_end():
"""
>>> test_literal_list_slice_end()
(1, 2, 3, 4, 5)
"""
cdef int a[7] # = [7,6,5,4,3,2,1]
a[:5] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
def test_literal_list_slice_start_end():
"""
>>> test_literal_list_slice_start_end()
(1, 2, 3, 4, 5)
"""
cdef int a[9] # = [9,8,7,6,5,4,3,2,1]
a[2:7] = [1,2,3,4,5]
return (a[2], a[3], a[4], a[5], a[6])
def test_literal_list_slice_start_param(s):
"""
>>> test_literal_list_slice_start_param(4)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_param(3)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_param(5)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
"""
cdef int a[9] # = [9,8,7,6,5,4,3,2,1]
a[s:] = [1,2,3,4,5]
return (a[4], a[5], a[6], a[7], a[8])
# return a[s:]
def test_literal_list_slice_end_param(e):
"""
>>> test_literal_list_slice_end_param(5)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_end_param(4)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_end_param(6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
"""
cdef int a[9] # = [9,8,7,6,5,4,3,2,1]
a[:e] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
# return a[:e]
def test_literal_list_slice_start_end_param(s,e):
"""
>>> test_literal_list_slice_start_end_param(2,7)
(1, 2, 3, 4, 5)
>>> test_literal_list_slice_start_end_param(3,7)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_start_end_param(1,7)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_end_param(2,6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 4
>>> test_literal_list_slice_start_end_param(2,8)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 6
>>> test_literal_list_slice_start_end_param(3,6)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 3
>>> test_literal_list_slice_start_end_param(1,8)
Traceback (most recent call last):
ValueError: Assignment to slice of wrong length, expected 5, got 7
"""
cdef int a[9] # = [9,8,7,6,5,4,3,2,1]
a[s:e] = [1,2,3,4,5]
return (a[2], a[3], a[4], a[5], a[6])
# return a[s:e]
def test_ptr_literal_list_slice_all():
"""
>>> test_ptr_literal_list_slice_all()
(1, 2, 3, 4, 5)
"""
cdef int *a = [6,5,4,3,2]
a[:] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
def test_ptr_literal_list_slice_start():
"""
>>> test_ptr_literal_list_slice_start()
(1, 2, 3, 4, 5)
"""
cdef int *a = [6,5,4,3,2,1]
a[1:] = [1,2,3,4,5]
return (a[1], a[2], a[3], a[4], a[5])
def test_ptr_literal_list_slice_end():
"""
>>> test_ptr_literal_list_slice_end()
(1, 2, 3, 4, 5)
"""
cdef int *a = [6,5,4,3,2,1]
a[:5] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
......
__doc__ = u"""
def f():
"""
>>> f()
42
"""
def f():
"""
a = 42
return a
__doc__ = u"""
def f(a, b, int i):
"""
>>> f(1, 2, 1)
>>> f(0, 2, 1)
Traceback (most recent call last):
......@@ -9,17 +10,16 @@ __doc__ = u"""
>>> f(1, 2, 0)
Traceback (most recent call last):
AssertionError
>>> g(1, "works")
>>> g(0, "fails")
Traceback (most recent call last):
AssertionError: fails
"""
def f(a, b, int i):
"""
assert a
assert a+b
assert i
def g(a, b):
"""
>>> g(1, "works")
>>> g(0, "fails")
Traceback (most recent call last):
AssertionError: fails
"""
assert a, b
......@@ -109,5 +109,3 @@ cdef class MyCdefClass:
>>> True
False
"""
__doc__ = u"""
def f(obj2):
"""
>>> f(20)
'20'
>>> f('test')
"'test'"
>>> g()
'42'
"""
def f(obj2):
"""
obj1 = `obj2`
return obj1
def g():
"""
>>> g()
'42'
"""
obj1 = `42`
return obj1
cdef cf(default=None):
return default
cpdef cpf(default=None):
"""
>>> cpf()
None
>>> cpf(1)
1
>>> cpf(default=2)
2
"""
default = cf(default)
return default
def pf(default=None):
"""
>>> pf()
None
>>> pf(1)
1
>>> pf(default=2)
2
"""
return default
cdef struct foo:
int void
int default
def test_struct():
"""
>>> test_struct()
(1, 2)
"""
cdef foo foo_struct
foo_struct.void = 1
foo_struct.default = 2
return foo_struct.void, foo_struct.default
cdef class Foo:
cdef int void
cdef int default
def test_class():
"""
>>> test_class()
(1, 2)
"""
cdef Foo foo_instance = Foo()
foo_instance.void = 1
foo_instance.default = 2
return foo_instance.void, foo_instance.default
__doc__ = u"""
>>> viking(5)
5
"""
cdef class Spam:
cdef eggs(self, a):
return a
......@@ -11,4 +6,8 @@ cdef Spam spam():
return Spam()
def viking(a):
"""
>>> viking(5)
5
"""
return spam().eggs(a)
__doc__ = u"""
def test():
"""
>>> test()
neg False
pos True
......@@ -6,9 +7,7 @@ __doc__ = u"""
pos
neg
pos
"""
def test():
"""
cdef long neg = -1
cdef unsigned long pos = -2 # will be a large positive number
......@@ -22,4 +21,3 @@ def test():
print D[neg]
print D[pos]
__doc__ = u"""
>>> call_test()
False
True
False
True
True
True
True
"""
cdef test(bint value):
print value
def call_test():
"""
>>> call_test()
False
True
False
True
True
True
True
"""
test(False)
test(True)
test(0)
......
__doc__ = u"""
def foo(obj1, obj2, obj3, obj4, obj5):
"""
>>> foo(True, False, 23, 'test', 1)
(0.0, 1.0, False, False)
"""
def foo(obj1, obj2, obj3, obj4, obj5):
"""
cdef int bool1, bool2
cdef float bool3, bool4
cdef char *ptr1, *ptr2, *ptr0
......
......@@ -1392,4 +1392,3 @@ def buffer_nogil():
with nogil:
buf[1] = 10
return buf[1]
......@@ -4,11 +4,13 @@ __doc__ = u"""
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'append'
>>> append_to_none()
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'append'
"""
def append_to_none():
"""
>>> append_to_none()
Traceback (most recent call last):
AttributeError: 'NoneType' object has no attribute 'append'
"""
cdef list l = None
l.append(2)
__doc__ = u"""
>>> test_c('abc')
fileabc
typeabc
>>> print(test_file_py('abc'))
abc
>>> print(range('abc'))
rangeabc
"""
def test_file_py(file):
assert isinstance(file, (str, unicode)), \
u"not a string, found '%s' instead" % file.__class__.__name__
......@@ -28,5 +17,14 @@ cdef type(arg):
def test_c(arg):
"""
>>> test_c('abc')
fileabc
typeabc
>>> print(test_file_py('abc'))
abc
>>> print(range('abc'))
rangeabc
"""
print test_file_c(arg)
print type(arg)
__doc__ = u"""
cdef class A:
"""
>>> A().test(3)
9
"""
cdef class A:
"""
cdef int (*func_ptr)(int)
......
__doc__ = u"""
>>> test_pos_args(h)
1 2 3 * 0 0
1 2 9 * 2 0
1 2 7 * 2 0
9 8 7 * 0 0
7 8 9 * 0 0
>>> test_kw_args(h)
1 2 3 * 0 0
1 2 9 * 2 1
1 2 7 * 2 1
1 2 9 * 2 2
1 2 9 * 2 2
1 2 9 * 2 3
>>> test_kw_args(e)
2 1
5 1
5 1
5 2
5 2
5 3
>>> test_kw(e)
0 1
0 2
0 2
0 1
>>> test_kw(g)
1
2
2
1
>>> test_pos_args(f)
3
5
5
3
3
>>> test_noargs(e)
0 0
>>> test_noargs(f)
0
>>> test_noargs(g)
0
# and some errors:
>>> test_noargs(h)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (0 given)
>>> h(1,2, d=5)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (2 given)
>>> f(1,2, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(1, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> g(1,2, d=5)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (1 given)
>>> test_int_kwargs(e)
Traceback (most recent call last):
TypeError: e() keywords must be strings
>>> test_int_kwargs(f)
Traceback (most recent call last):
TypeError: f() keywords must be strings
>>> test_int_kwargs(g)
Traceback (most recent call last):
TypeError: g() keywords must be strings
>>> test_int_kwargs(h)
Traceback (most recent call last):
TypeError: h() keywords must be strings
>>> d()
Traceback (most recent call last):
TypeError: d() takes at least 1 positional argument (0 given)
>>> d(1)
1 1 0 0
>>> d(1,2)
1 2 0 0
>>> d(1,2,3)
1 2 1 0
>>> d(key=None)
Traceback (most recent call last):
TypeError: d() takes at least 1 positional argument (0 given)
>>> d(1, key=None)
1 1 0 1
>>> d(1,2, key=None)
1 2 0 1
>>> d(1,2,3, key=None)
1 2 1 1
>>> c()
10 20 0
>>> c(1)
1 20 0
>>> c(1,2)
1 2 0
>>> c(key=None)
10 20 1
>>> c(1, key=None)
1 20 1
>>> c(1,2, key=None)
1 2 1
"""
def c(a=10, b=20, **kwds):
"""
>>> c()
10 20 0
>>> c(1)
1 20 0
>>> c(1,2)
1 2 0
>>> c(key=None)
10 20 1
>>> c(1, key=None)
1 20 1
>>> c(1,2, key=None)
1 2 1
"""
print a, b, len(kwds)
def d(a, b=1, *args, **kwds):
"""
>>> d()
Traceback (most recent call last):
TypeError: d() takes at least 1 positional argument (0 given)
>>> d(1)
1 1 0 0
>>> d(1,2)
1 2 0 0
>>> d(1,2,3)
1 2 1 0
>>> d(key=None)
Traceback (most recent call last):
TypeError: d() takes at least 1 positional argument (0 given)
>>> d(1, key=None)
1 1 0 1
>>> d(1,2, key=None)
1 2 0 1
>>> d(1,2,3, key=None)
1 2 1 1
"""
print a, b, len(args), len(kwds)
def e(*args, **kwargs):
print len(args), len(kwargs)
def f(*args):
"""
>>> f(1,2, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(1, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
"""
print len(args)
def g(**kwargs):
"""
>>> g(1,2, d=5)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (1 given)
"""
print len(kwargs)
def h(a, b, c, *args, **kwargs):
"""
>>> h(1,2, d=5)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (2 given)
"""
print a, b, c, u'*', len(args), len(kwargs)
args = (9,8,7)
......@@ -153,6 +86,22 @@ else:
kwargs = {"test" : u"toast"}
def test_kw_args(f):
"""
>>> test_kw_args(h)
1 2 3 * 0 0
1 2 9 * 2 1
1 2 7 * 2 1
1 2 9 * 2 2
1 2 9 * 2 2
1 2 9 * 2 3
>>> test_kw_args(e)
2 1
5 1
5 1
5 2
5 2
5 3
"""
f(1,2, c=3)
f(1,2, d=3, *args)
f(1,2, d=3, *(7,8,9))
......@@ -161,6 +110,20 @@ def test_kw_args(f):
f(1,2, d=3, *args, e=5, **kwargs)
def test_pos_args(f):
"""
>>> test_pos_args(h)
1 2 3 * 0 0
1 2 9 * 2 0
1 2 7 * 2 0
9 8 7 * 0 0
7 8 9 * 0 0
>>> test_pos_args(f)
3
5
5
3
3
"""
f(1,2,3)
f(1,2, *args)
f(1,2, *(7,8,9))
......@@ -168,13 +131,52 @@ def test_pos_args(f):
f(*(7,8,9))
def test_kw(f):
"""
>>> test_kw(e)
0 1
0 2
0 2
0 1
>>> test_kw(g)
1
2
2
1
"""
f(c=3)
f(d=3, e=5)
f(d=3, **kwargs)
f(**kwargs)
def test_noargs(f):
"""
>>> test_noargs(e)
0 0
>>> test_noargs(f)
0
>>> test_noargs(g)
0
# and some errors:
>>> test_noargs(h)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (0 given)
"""
f()
def test_int_kwargs(f):
"""
>>> test_int_kwargs(e)
Traceback (most recent call last):
TypeError: e() keywords must be strings
>>> test_int_kwargs(f)
Traceback (most recent call last):
TypeError: f() keywords must be strings
>>> test_int_kwargs(g)
Traceback (most recent call last):
TypeError: g() keywords must be strings
>>> test_int_kwargs(h)
Traceback (most recent call last):
TypeError: h() keywords must be strings
"""
f(a=1,b=2,c=3, **{10:20,30:40})
cimport cython
############################################################
# tests for char* slicing
cdef char* cstring = "abcABCqtp"
def slice_charptr_end():
"""
>>> print(str(slice_charptr_end()).replace("b'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return cstring[:1], cstring[:3], cstring[:9]
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode():
"""
>>> print(str(slice_charptr_decode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8'),
cstring[:3].decode('UTF-8'),
cstring[:9].decode('UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_unbound():
"""
>>> print(str(slice_charptr_decode_unbound()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (bytes.decode(cstring[:1], 'UTF-8'),
bytes.decode(cstring[:3], 'UTF-8', 'replace'),
bytes.decode(cstring[:9], 'UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_errormode():
"""
>>> print(str(slice_charptr_decode_errormode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8', 'strict'),
cstring[:3].decode('UTF-8', 'replace'),
cstring[:9].decode('UTF-8', 'unicode_escape'))
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//SliceIndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_py():
"""
>>> slice_charptr_for_loop_py()
['a', 'b', 'c']
['b', 'c', 'A', 'B']
['B', 'C', 'q', 't', 'p']
"""
print str([ c for c in cstring[:3] ]).replace(" b'", " '").replace("[b'", "['")
print str([ c for c in cstring[1:5] ]).replace(" b'", " '").replace("[b'", "['")
print str([ c for c in cstring[4:9] ]).replace(" b'", " '").replace("[b'", "['")
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_c():
"""
>>> slice_charptr_for_loop_c()
['a', 'b', 'c']
['b', 'c', 'A', 'B']
['B', 'C', 'q', 't', 'p']
"""
cdef char c
print [ chr(c) for c in cstring[:3] ]
print [ chr(c) for c in cstring[1:5] ]
print [ chr(c) for c in cstring[4:9] ]
## @cython.test_assert_path_exists("//ForFromStatNode",
## "//ForFromStatNode//IndexNode")
## @cython.test_fail_if_path_exists("//ForInStatNode")
## def slice_charptr_for_loop_c_step():
## """
## >>> slice_charptr_for_loop_c()
## ['c', 'b', 'a']
## ['b', 'c', 'A', 'B']
## ['p', 't', 'q', 'C', 'B']
## """
## cdef char c
## print [ chr(c) for c in cstring[:3:-1] ]
## print [ chr(c) for c in cstring[1:5:2] ]
## print [ chr(c) for c in cstring[4:9:-1] ]
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_c_dynamic_bounds():
"""
>>> slice_charptr_for_loop_c()
['a', 'b', 'c']
['b', 'c', 'A', 'B']
['B', 'C', 'q', 't', 'p']
"""
cdef char c
print [ chr(c) for c in cstring[0:return3()] ]
print [ chr(c) for c in cstring[return1():return5()] ]
print [ chr(c) for c in cstring[return4():return9()] ]
cdef return1(): return 1
cdef return3(): return 3
cdef return4(): return 4
cdef return5(): return 5
cdef return9(): return 9
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//SliceIndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_py_enumerate():
"""
>>> slice_charptr_for_loop_py_enumerate()
[(0, 'a'), (1, 'b'), (2, 'c')]
[(0, 'b'), (1, 'c'), (2, 'A'), (3, 'B')]
[(0, 'B'), (1, 'C'), (2, 'q'), (3, 't'), (4, 'p')]
"""
print str([ (i,c) for i,c in enumerate(cstring[:3]) ]).replace(" b'", " '")
print str([ (i,c) for i,c in enumerate(cstring[1:5]) ]).replace(" b'", " '")
print str([ (i,c) for i,c in enumerate(cstring[4:9]) ]).replace(" b'", " '")
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//IndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_c_enumerate():
"""
>>> slice_charptr_for_loop_c_enumerate()
[(0, 97), (1, 98), (2, 99)]
[(0, 98), (1, 99), (2, 65), (3, 66)]
[(0, 66), (1, 67), (2, 113), (3, 116), (4, 112)]
"""
cdef int c,i
print [ (i,c) for i,c in enumerate(cstring[:3]) ]
print [ (i,c) for i,c in enumerate(cstring[1:5]) ]
print [ (i,c) for i,c in enumerate(cstring[4:9]) ]
############################################################
# tests for int* slicing
## cdef int cints[6]
## for i in range(6):
## cints[i] = i
## @cython.test_assert_path_exists("//ForFromStatNode",
## "//ForFromStatNode//IndexNode")
## @cython.test_fail_if_path_exists("//ForInStatNode")
## def slice_intptr_for_loop_c():
## """
## >>> slice_intptr_for_loop_c()
## [0, 1, 2]
## [1, 2, 3, 4]
## [4, 5]
## """
## cdef int i
## print [ i for i in cints[:3] ]
## print [ i for i in cints[1:5] ]
## print [ i for i in cints[4:6] ]
__doc__ = u"""
>>> test1()
2
>>> test2()
0
>>> test3()
(2, 3)
"""
def test1():
"""
>>> test1()
2
"""
cdef int x[2][2]
x[0][0] = 1
x[0][1] = 2
......@@ -20,6 +15,10 @@ cdef int* f(int x[2][2]):
def test2():
"""
>>> test2()
0
"""
cdef int a1[5]
cdef int a2[2+3]
return sizeof(a1) - sizeof(a2)
......@@ -29,6 +28,10 @@ cdef enum:
MY_SIZE_B = 3
def test3():
"""
>>> test3()
(2, 3)
"""
cdef int a[MY_SIZE_A]
cdef int b[MY_SIZE_B]
return sizeof(a)/sizeof(int), sizeof(b)/sizeof(int)
__doc__ = u"""
>>> foo(True)
True
>>> foo(False)
False
>>> foo('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
>>> call_cfoo(True)
True
>>> call_cfoo(False)
False
>>> call_cfoo('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
def foo(bool a):
"""
>>> foo(True)
True
>>> foo(False)
False
>>> foo('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
return a == True
def call_cfoo(a):
"""
>>> call_cfoo(True)
True
>>> call_cfoo(False)
False
>>> call_cfoo('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
"""
return cfoo(a)
cdef cfoo(bool a):
......
__doc__ = u"""
>>> cdiv_decorator(-12, 5)
-2
>>> pydiv_decorator(-12, 5)
-3
"""
cimport cython
@cython.cdivision(True)
cpdef cdiv_decorator(int a, int b):
"""
>>> cdiv_decorator(-12, 5)
-2
"""
return a / b
@cython.cdivision(False)
cpdef pydiv_decorator(int a, int b):
"""
>>> pydiv_decorator(-12, 5)
-3
"""
return a / b
......@@ -7,12 +7,6 @@ __doc__ = u"""
>>> a.foo(10, u'yes')
(True, u'yes')
>>> call0()
(True, u'yo')
>>> call1()
(False, u'yo')
>>> call2()
(False, u'go')
"""
import sys
......@@ -25,13 +19,25 @@ cdef class A:
return a, b
def call0():
"""
>>> call0()
(True, u'yo')
"""
a = A()
return a.foo()
def call1():
"""
>>> call1()
(False, u'yo')
"""
a = A()
return a.foo(False)
def call2():
"""
>>> call2()
(False, u'go')
"""
a = A()
return a.foo(False, u"go")
__doc__ = u'''
>>> no_cdef()
>>> with_cdef()
>>> test_list(list(range(11)), -2, None)
[0, 1, 2, 3, 4, 5, 6, 7, 8, None, 10]
>>> test_list(list(range(11)), "invalid index", None) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: list indices must be integers...
'''
def no_cdef():
"""
>>> no_cdef()
"""
lst = list(range(11))
ob = 10L
lst[ob] = -10
......@@ -17,6 +9,9 @@ def no_cdef():
dd[ob] = -10
def with_cdef():
"""
>>> with_cdef()
"""
cdef list lst = list(range(11))
ob = 10L
lst[ob] = -10
......@@ -24,5 +19,13 @@ def with_cdef():
dd[ob] = -10
def test_list(list L, object i, object a):
"""
>>> test_list(list(range(11)), -2, None)
[0, 1, 2, 3, 4, 5, 6, 7, 8, None, 10]
>>> test_list(list(range(11)), "invalid index", None) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: list indices must be integers...
"""
L[i] = a
return L
__doc__ = u"""
>>> test(1, 2)
4 1 2 2 0 7 8
"""
cdef int g = 7
def test(x, int y):
"""
>>> test(1, 2)
4 1 2 2 0 7 8
"""
if True:
before = 0
cdef int a = 4, b = x, c = y, *p = &y
......
__doc__ = u"""
>>> call2()
>>> call3()
>>> call4()
>>> test_foo()
2
3
7
26
"""
# the calls:
def call2():
"""
>>> call2()
"""
b(1,2)
def call3():
"""
>>> call3()
"""
b(1,2,3)
def call4():
"""
>>> call4()
"""
b(1,2,3,4)
# the called function:
......@@ -30,6 +28,13 @@ cdef int foo(int a, int b=1, int c=1):
return a+b*c
def test_foo():
"""
>>> test_foo()
2
3
7
26
"""
print foo(1)
print foo(1, 2)
print foo(1, 2, 3)
......
......@@ -36,46 +36,20 @@ True
>>> import warnings
>>> warnings.showwarning = simple_warn
>>> mod_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-7
>>> div_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-1
>>> 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
>>> mod_div_zero_int(25, 10, 2)
verbose_call(5)
2
>>> print(mod_div_zero_int(25, 10, 0))
verbose_call(5)
integer division or modulo by zero
>>> print(mod_div_zero_int(25, 0, 0))
integer division or modulo by zero
>>> mod_div_zero_float(25, 10, 2)
2.5
>>> print(mod_div_zero_float(25, 10, 0))
float division
>>> print(mod_div_zero_float(25, 0, 0))
float divmod()
>>> py_div_long(-5, -1)
5
>>> 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):
...
OverflowError: value too large to perform division
"""
def _all(seq):
for x in seq:
if not x:
return False
return True
try:
all
except NameError:
all = _all
cimport cython
@cython.cdivision(False)
......@@ -125,16 +99,34 @@ def test_cdiv_cmod(short a, short b):
@cython.cdivision(True)
@cython.cdivision_warnings(True)
def mod_int_c_warn(int a, int b):
"""
>>> mod_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-7
"""
return a % b
@cython.cdivision(True)
@cython.cdivision_warnings(True)
def div_int_c_warn(int a, int b):
"""
>>> div_int_c_warn(-17, 10)
division with oppositely signed operands, C and Python semantics differ
-1
"""
return a // b
@cython.cdivision(False)
@cython.cdivision_warnings(True)
def complex_expression(int a, int b, int c, int d):
"""
>>> 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
"""
return (a // verbose_call(b)) % (verbose_call(c) // d)
cdef int verbose_call(int x):
......@@ -146,6 +138,16 @@ cdef int verbose_call(int x):
@cython.cdivision(False)
def mod_div_zero_int(int a, int b, int c):
"""
>>> mod_div_zero_int(25, 10, 2)
verbose_call(5)
2
>>> print(mod_div_zero_int(25, 10, 0))
verbose_call(5)
integer division or modulo by zero
>>> print(mod_div_zero_int(25, 0, 0))
integer division or modulo by zero
"""
try:
return verbose_call(a % b) / c
except ZeroDivisionError, ex:
......@@ -153,6 +155,14 @@ def mod_div_zero_int(int a, int b, int c):
@cython.cdivision(False)
def mod_div_zero_float(float a, float b, float c):
"""
>>> mod_div_zero_float(25, 10, 2)
2.5
>>> print(mod_div_zero_float(25, 10, 0))
float division
>>> print(mod_div_zero_float(25, 0, 0))
float divmod()
"""
try:
return (a % b) / c
except ZeroDivisionError, ex:
......@@ -160,4 +170,14 @@ def mod_div_zero_float(float a, float b, float c):
@cython.cdivision(False)
def py_div_long(long a, long b):
"""
>>> py_div_long(-5, -1)
5
>>> 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):
...
OverflowError: value too large to perform division
"""
return a / b
__doc__ = u"""
>>> test()
"""
cdef void ftang():
cdef int x
x = 0
......@@ -16,6 +12,9 @@ cdef spam(int i, obj, object object):
c = 0
def test():
"""
>>> test()
"""
ftang()
foo(0, c'f')
spam(25, None, None)
__doc__ = u"""
>>> global_c_and_s()
99
abcdef
>>> local_c_and_s()
98
bcdefg
"""
cdef char c = 'c'
cdef char* s = 'abcdef'
def global_c_and_s():
"""
>>> global_c_and_s()
99
abcdef
"""
pys = s
print c
print (pys.decode(u'ASCII'))
def local_c_and_s():
"""
>>> local_c_and_s()
98
bcdefg
"""
cdef char c = 'b'
cdef char* s = 'bcdefg'
pys = s
......
......@@ -13,11 +13,13 @@ __doc__ = u"""
>>> (int1, long1) == f()
True
>>> f()
(45, 111)
"""
def f():
"""
>>> f()
(45, 111)
"""
cdef int int1, int2, int3
cdef char char1
cdef long long1, long2
......
__doc__ = u"""
def single_py(a, b):
"""
>>> single_py(1, 2)
True
>>> single_py(2, 1)
False
"""
return a < b
def cascaded_py(a, b, c):
"""
>>> cascaded_py(1, 2, 3)
True
>>> cascaded_py(1, 2, -1)
False
>>> cascaded_py(10, 2, 3)
False
"""
return a < b < c
def single_c(int a, int b):
"""
>>> single_c(1, 2)
True
>>> single_c(2, 1)
False
"""
return a < b
def cascaded_c(double a, double b, double c):
"""
>>> cascaded_c(1, 2, 3)
True
>>> cascaded_c(1, 2, -1)
False
>>> cascaded_c(10, 2, 3)
False
"""
def single_py(a, b):
return a < b
def cascaded_py(a, b, c):
return a < b < c
def single_c(int a, int b):
return a < b
def cascaded_c(double a, double b, double c):
"""
return a < b < c
def typed_cmp(list L):
......
cdef char* cstring = "abcdefg"
cdef void spam(char *target):
cdef char* s = cstring
while s[0]:
target[0] = s[0]
s += 1
target += 1
target[0] = c'\0'
cdef struct Grail:
char silly[42]
def eggs():
"""
>>> print(str(eggs()).replace("b'", "'"))
('abcdefg', 'abcdefg')
"""
cdef char silly[42]
cdef Grail grail
spam(silly)
spam(grail.silly)
return silly, grail.silly
__doc__ = u"""
#cdef extern from "complex.h":
# pass
cimport cython
def test_object_conversion(o):
"""
>>> test_object_conversion(2)
((2+0j), (2+0j), (2+0j))
>>> test_object_conversion(2j - 0.5)
((-0.5+2j), (-0.5+2j), (-0.5+2j))
"""
cdef float complex a = o
cdef double complex b = o
cdef long double complex c = o
return (a, b, c)
def test_arithmetic(double complex z, double complex w):
"""
>>> test_arithmetic(2j, 4j)
(2j, -2j, 6j, -2j, (-8+0j), (0.5+0j))
>>> test_arithmetic(6+12j, 3j)
((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
## >>> test_div_by_zero(4j)
## -0.25j
## >>> test_div_by_zero(0)
## Traceback (most recent call last):
## ...
## ZeroDivisionError: float division
## @cython.cdivision(False)
## def test_div_by_zero(double complex z):
## return 1/z
def test_coercion(int a, float b, double c, float complex d, double complex e):
"""
>>> test_coercion(1, 1.5, 2.5, 4+1j, 10j)
(1+0j)
(1.5+0j)
......@@ -26,7 +48,17 @@ __doc__ = u"""
(4+1j)
10j
(9+21j)
"""
cdef double complex z
z = a; print z
z = b; print z
z = c; print z
z = d; print z
z = e; print z
return z + a + b + c + d + e
def test_compare(double complex a, double complex b):
"""
>>> test_compare(3, 3)
(True, False)
>>> test_compare(3j, 3j)
......@@ -35,89 +67,79 @@ __doc__ = u"""
(False, True)
>>> test_compare(3, 4)
(False, True)
"""
return a == b, a != b
def test_compare_coerce(double complex a, int b):
"""
>>> test_compare_coerce(3, 4)
(False, True)
>>> test_compare_coerce(4+1j, 4)
(False, True)
>>> test_compare_coerce(4, 4)
(True, False)
"""
return a == b, a != b
def test_literal():
"""
>>> test_literal()
(5j, (1-2.5j))
"""
return 5j, 1-2.5j
def test_real_imag(double complex z):
"""
>>> test_real_imag(1-3j)
(1.0, -3.0)
>>> test_real_imag(5)
(5.0, 0.0)
>>> test_real_imag(1.5j)
(0.0, 1.5)
"""
return z.real, z.imag
def test_real_imag_assignment(object a, double b):
"""
>>> test_real_imag_assignment(1, 2)
(1+2j)
>>> test_real_imag_assignment(1.5, -3.5)
(1.5-3.5j)
>>> test_conjugate(2+3j)
(2-3j)
>>> test_conjugate_double(2+3j)
(2-3j)
"""
#cdef extern from "complex.h":
# pass
cimport cython
def test_object_conversion(o):
cdef float complex a = o
cdef double complex b = o
cdef long double complex c = o
return (a, b, c)
def test_arithmetic(double complex z, double complex w):
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
def test_coercion(int a, float b, double c, float complex d, double complex e):
cdef double complex z
z = a; print z
z = b; print z
z = c; print z
z = d; print z
z = e; print z
return z + a + b + c + d + e
def test_compare(double complex a, double complex b):
return a == b, a != b
def test_compare_coerce(double complex a, int b):
return a == b, a != b
def test_literal():
return 5j, 1-2.5j
def test_real_imag(double complex z):
return z.real, z.imag
def test_real_imag_assignment(object a, double b):
"""
cdef double complex z
z.real = a
z.imag = b
return z
def test_conjugate(float complex z):
"""
>>> test_conjugate(2+3j)
(2-3j)
"""
return z.conjugate()
def test_conjugate_double(double complex z):
"""
>>> test_conjugate_double(2+3j)
(2-3j)
"""
return z.conjugate()
ctypedef double complex cdouble
def test_conjugate_typedef(cdouble z):
return z.conjugate()
ctypedef double mydouble
def test_coerce_typedef_multiply(mydouble x, double complex z):
"""
>>> test_coerce_typedef_multiply(3, 1j)
(3j)
"""
return x * z
cpdef double complex complex_retval():
"""
>>> complex_retval()
1j
"""
return 1j
......@@ -8,4 +8,3 @@ if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
spam = u"C string 1" + u"C string 2"
__doc__ = u"""
>>> add() == 1+2+3+4
True
>>> add_var(10) == 1+2+10+3+4
True
>>> neg() == -1 -2 - (-3+4)
True
>>> long_int_mix() == 1 + (2 * 3) // 2
True
>>> if IS_PY3: type(long_int_mix()) is int
... else: type(long_int_mix()) is long
True
>>> char_int_mix() == 1 + (ord(' ') * 3) // 2 + ord('A')
True
>>> int_cast() == 1 + 2 * 6000
True
>>> mul() == 1*60*1000
True
>>> arithm() == 9*2+3*8//6-10
True
>>> parameters() == _func(-1 -2, - (-3+4), 1*2*3)
True
>>> lists() == [1,2,3] + [4,5,6]
True
"""
import sys
IS_PY3 = sys.version_info[0] >= 3
......@@ -31,31 +5,74 @@ def _func(a,b,c):
return a+b+c
def add():
"""
>>> add() == 1+2+3+4
True
"""
return 1+2+3+4
def add_var(a):
"""
>>> add_var(10) == 1+2+10+3+4
True
"""
return 1+2 +a+ 3+4
def neg():
"""
>>> neg() == -1 -2 - (-3+4)
True
"""
return -1 -2 - (-3+4)
def long_int_mix():
"""
>>> long_int_mix() == 1 + (2 * 3) // 2
True
>>> if IS_PY3: type(long_int_mix()) is int
... else: type(long_int_mix()) is long
True
"""
return 1L + (2 * 3L) // 2
def char_int_mix():
"""
>>> char_int_mix() == 1 + (ord(' ') * 3) // 2 + ord('A')
True
"""
return 1L + (c' ' * 3L) // 2 + c'A'
def int_cast():
"""
>>> int_cast() == 1 + 2 * 6000
True
"""
return <int>(1 + 2 * 6000)
def mul():
"""
>>> mul() == 1*60*1000
True
"""
return 1*60*1000
def arithm():
"""
>>> arithm() == 9*2+3*8//6-10
True
"""
return 9*2+3*8//6-10
def parameters():
"""
>>> parameters() == _func(-1 -2, - (-3+4), 1*2*3)
True
"""
return _func(-1 -2, - (-3+4), 1*2*3)
def lists():
"""
>>> lists() == [1,2,3] + [4,5,6]
True
"""
return [1,2,3] + [4,5,6]
__doc__ = """
cdef class A:
"""
>>> A().is_True()
True
>>> A().is_False()
False
>>> B().is_True()
True
>>> B().is_False()
False
"""
cdef class A:
"""
cpdef is_True(self):
return True
cpdef is_False(self):
return not self.is_True()
class B(A):
"""
>>> B().is_True()
True
>>> B().is_False()
False
"""
def is_True(self):
return True
__doc__ = """
>>> f()
{'x': 1}
"""
cimport crashT245_pxd
def f():
"""
>>> f()
{'x': 1}
"""
cdef crashT245_pxd.MyStruct s
s.x = 1
print s
__doc__ = u"""
>>> test_i()
>>> test_c()
>>> test_p()
>>> test_g()
"""
cdef struct Grail
cdef struct Spam:
......@@ -41,19 +34,31 @@ cdef void eggs_g(Spam s):
spam = ham
def test_i():
"""
>>> test_i()
"""
spam.i = 1
eggs_i(spam)
def test_c():
"""
>>> test_c()
"""
spam.c = c'a'
eggs_c(spam)
def test_p():
"""
>>> test_p()
"""
cdef float f
spam.p[0] = &f
eggs_p(spam)
def test_g():
"""
>>> test_g()
"""
cdef Grail l
spam.g = &l
eggs_g(spam)
__doc__ = u"""
>>> f()
1
>>> g()
2
>>> h()
3
"""
DEF NO = 0
DEF YES = 1
def f():
"""
>>> f()
1
"""
cdef int i
IF YES:
i = 1
......@@ -21,6 +16,10 @@ def f():
return i
def g():
"""
>>> g()
2
"""
cdef int i
IF NO:
i = 1
......@@ -31,6 +30,10 @@ def g():
return i
def h():
"""
>>> h()
3
"""
cdef int i
IF NO:
i = 1
......
This diff is collapsed.
This diff is collapsed.
__doc__ = u"""
>>> f()
"""
def f():
"""
>>> f()
"""
cdef char a_char
cdef short a_short
cdef int i1, i2
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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