Commit 6d2165ee authored by Vitja Makarov's avatar Vitja Makarov

Merge remote branch 'upstream/master'

parents 3cae35ea 11fd96e0
*.pyc
*.pyo
__pycache__
Cython/Compiler/*.c
Cython/Plex/*.c
Cython/Runtime/refnanny.c
BUILD/
build/
dist/
.gitrev
.coverage
*.orig
*.rej
*.dep
*.swp
*~
tags
TAGS
syntax: glob syntax: glob
*.pyc *.pyc
*.swp *.pyo
__pycache__
Cython/Compiler/*.c
Cython/Plex/*.c
Cython/Runtime/refnanny.c
Cython/Compiler/Lexicon.pickle
BUILD/ BUILD/
build/ build/
dist/ dist/
.gitrev
.coverage .coverage
*~
*.orig *.orig
*.rej *.rej
*.dep *.dep
*.swp
*~
tags tags
TAGS
import os, tempfile
from Cython.Shadow import inline from Cython.Shadow import inline
from Cython.Build.Inline import safe_type from Cython.Build.Inline import safe_type
from Cython.TestUtils import CythonTest from Cython.TestUtils import CythonTest
...@@ -13,23 +14,31 @@ test_kwds = dict(force=True, quiet=True) ...@@ -13,23 +14,31 @@ test_kwds = dict(force=True, quiet=True)
global_value = 100 global_value = 100
class TestInline(CythonTest): class TestInline(CythonTest):
def setUp(self):
CythonTest.setUp(self)
self.test_kwds = dict(test_kwds)
if os.path.isdir('BUILD'):
lib_dir = os.path.join('BUILD','inline')
else:
lib_dir = tempfile.mkdtemp(prefix='cython_inline_')
self.test_kwds['lib_dir'] = lib_dir
def test_simple(self): def test_simple(self):
self.assertEquals(inline("return 1+2", **test_kwds), 3) self.assertEquals(inline("return 1+2", **self.test_kwds), 3)
def test_types(self): def test_types(self):
self.assertEquals(inline(""" self.assertEquals(inline("""
cimport cython cimport cython
return cython.typeof(a), cython.typeof(b) return cython.typeof(a), cython.typeof(b)
""", a=1.0, b=[], **test_kwds), ('double', 'list object')) """, a=1.0, b=[], **self.test_kwds), ('double', 'list object'))
def test_locals(self): def test_locals(self):
a = 1 a = 1
b = 2 b = 2
self.assertEquals(inline("return a+b", **test_kwds), 3) self.assertEquals(inline("return a+b", **self.test_kwds), 3)
def test_globals(self): def test_globals(self):
self.assertEquals(inline("return global_value + 1", **test_kwds), global_value + 1) self.assertEquals(inline("return global_value + 1", **self.test_kwds), global_value + 1)
if has_numpy: if has_numpy:
...@@ -38,4 +47,4 @@ class TestInline(CythonTest): ...@@ -38,4 +47,4 @@ class TestInline(CythonTest):
a = numpy.ndarray((10, 20)) a = numpy.ndarray((10, 20))
a[0,0] = 10 a[0,0] = 10
self.assertEquals(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]') self.assertEquals(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]')
self.assertEquals(inline("return a[0,0]", a=a, **test_kwds), 10.0) self.assertEquals(inline("return a[0,0]", a=a, **self.test_kwds), 10.0)
...@@ -527,8 +527,7 @@ def use_py2_buffer_functions(env): ...@@ -527,8 +527,7 @@ def use_py2_buffer_functions(env):
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
#if PY_VERSION_HEX >= 0x02060000 #if PY_VERSION_HEX >= 0x02060000
if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER) if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
return PyObject_GetBuffer(obj, view, flags);
#endif #endif
""") """)
if len(types) > 0: if len(types) > 0:
...@@ -548,11 +547,15 @@ def use_py2_buffer_functions(env): ...@@ -548,11 +547,15 @@ def use_py2_buffer_functions(env):
static void __Pyx_ReleaseBuffer(Py_buffer *view) { static void __Pyx_ReleaseBuffer(Py_buffer *view) {
PyObject* obj = view->obj; PyObject* obj = view->obj;
if (obj) { if (obj) {
#if PY_VERSION_HEX >= 0x02060000
if (PyObject_CheckBuffer(obj)) {PyBuffer_Release(view); return;}
#endif
""") """)
if len(types) > 0: if len(types) > 0:
clause = "if" clause = "if"
for t, get, release in types: for t, get, release in types:
if release: if release:
code += " "
code += "%s (PyObject_TypeCheck(obj, %s)) %s(obj, view);" % (clause, t, release) code += "%s (PyObject_TypeCheck(obj, %s)) %s(obj, view);" % (clause, t, release)
clause = "else if" clause = "else if"
code += dedent(""" code += dedent("""
...@@ -1114,6 +1117,11 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -1114,6 +1117,11 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
ctx->new_count = 1; ctx->new_count = 1;
got_Z = 0; got_Z = 0;
break; break;
case ':':
++ts;
while(*ts != ':') ++ts;
++ts;
break;
default: default:
{ {
ctx->new_count = __Pyx_BufFmt_ParseNumber(&ts); ctx->new_count = __Pyx_BufFmt_ParseNumber(&ts);
......
...@@ -34,7 +34,7 @@ Options: ...@@ -34,7 +34,7 @@ Options:
-a, --annotate Produce a colorized HTML version of the source. -a, --annotate Produce a colorized HTML version of the source.
--line-directives Produce #line directives pointing to the .pyx source --line-directives Produce #line directives pointing to the .pyx source
--cplus Output a C++ rather than C file. --cplus Output a C++ rather than C file.
--embed Generate a main() function that embeds the Python interpreter. --embed[=<method_name>] Generate a main() function that embeds the Python interpreter.
-2 Compile based on Python-2 syntax and code semantics. -2 Compile based on Python-2 syntax and code semantics.
-3 Compile based on Python-3 syntax and code semantics. -3 Compile based on Python-3 syntax and code semantics.
--fast-fail Abort the compilation on the first error --fast-fail Abort the compilation on the first error
...@@ -84,8 +84,12 @@ def parse_command_line(args): ...@@ -84,8 +84,12 @@ def parse_command_line(args):
options.use_listing_file = 1 options.use_listing_file = 1
elif option in ("-+", "--cplus"): elif option in ("-+", "--cplus"):
options.cplus = 1 options.cplus = 1
elif option == "--embed": elif option.startswith("--embed"):
Options.embed = True ix = option.find('=')
if ix == -1:
Options.embed = "main"
else:
Options.embed = option[ix+1:]
elif option.startswith("-I"): elif option.startswith("-I"):
options.include_path.append(get_param(option)) options.include_path.append(get_param(option))
elif option == "--include-dir": elif option == "--include-dir":
......
...@@ -1681,20 +1681,22 @@ class NameNode(AtomicExprNode): ...@@ -1681,20 +1681,22 @@ class NameNode(AtomicExprNode):
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
if self.entry is None: if self.entry is None:
return # There was an error earlier return # There was an error earlier
if not self.entry.is_pyglobal: elif self.entry.is_pyglobal:
error(self.pos, "Deletion of local or C global name not supported") code.put_error_if_neg(self.pos,
return '__Pyx_DelAttrString(%s, "%s")' % (
if self.entry.is_pyclass_attr: Naming.module_cname,
self.entry.name))
elif self.entry.is_pyclass_attr:
namespace = self.entry.scope.namespace_cname namespace = self.entry.scope.namespace_cname
code.put_error_if_neg(self.pos, code.put_error_if_neg(self.pos,
'PyMapping_DelItemString(%s, "%s")' % ( 'PyMapping_DelItemString(%s, "%s")' % (
namespace, namespace,
self.entry.name)) self.entry.name))
elif self.entry.type.is_pyobject:
# Fake it until we can do it for real...
self.generate_assignment_code(NoneNode(self.pos), code)
else: else:
code.put_error_if_neg(self.pos, error(self.pos, "Deletion of C names not supported")
'__Pyx_DelAttrString(%s, "%s")' % (
Naming.module_cname,
self.entry.name))
def annotate(self, code): def annotate(self, code):
if hasattr(self, 'is_called') and self.is_called: if hasattr(self, 'is_called') and self.is_called:
......
...@@ -6,6 +6,7 @@ For now this only covers parse tree to value conversion of ...@@ -6,6 +6,7 @@ For now this only covers parse tree to value conversion of
compile-time values. compile-time values.
""" """
import sys
from Nodes import * from Nodes import *
from ExprNodes import * from ExprNodes import *
from Errors import CompileError from Errors import CompileError
...@@ -44,6 +45,10 @@ def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=()) ...@@ -44,6 +45,10 @@ def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=())
else: else:
raise CompileError(node.pos, "Type not allowed here.") raise CompileError(node.pos, "Type not allowed here.")
else: else:
if (sys.version_info[0] >=3 and
isinstance(node, StringNode) and
node.unicode_value is not None):
return (node.unicode_value, node.pos)
return (node.compile_time_value(empty_scope), node.pos) return (node.compile_time_value(empty_scope), node.pos)
if optlist: if optlist:
...@@ -52,6 +57,7 @@ def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=()) ...@@ -52,6 +57,7 @@ def interpret_compiletime_options(optlist, optdict, type_env=None, type_args=())
assert isinstance(optdict, DictNode) assert isinstance(optdict, DictNode)
new_optdict = {} new_optdict = {}
for item in optdict.key_value_pairs: for item in optdict.key_value_pairs:
new_optdict[item.key.value] = interpret(item.value, item.key.value) new_key, dummy = interpret(item.key, None)
new_optdict[new_key] = interpret(item.value, item.key.value)
optdict = new_optdict optdict = new_optdict
return (optlist, new_optdict) return (optlist, new_optdict)
...@@ -272,7 +272,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -272,7 +272,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code = globalstate['before_global_var'] code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
code.putln("static int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
code.putln("") code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name) code.putln("/* Implementation of %s */" % env.qualified_name)
...@@ -1897,7 +1897,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1897,7 +1897,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_main_method(self, env, code): def generate_main_method(self, env, code):
module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name, module_is_main=module_is_main)) if Options.embed == "main":
wmain = "wmain"
else:
wmain = Options.embed
code.globalstate.use_utility_code(
main_method.specialize(
module_name = env.module_name,
module_is_main = module_is_main,
main_method = Options.embed,
wmain_method = wmain))
def generate_pymoduledef_struct(self, env, code): def generate_pymoduledef_struct(self, env, code):
if env.doc: if env.doc:
...@@ -2648,9 +2657,9 @@ impl = """ ...@@ -2648,9 +2657,9 @@ impl = """
#endif #endif
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
int main(int argc, char** argv) { int %(main_method)s(int argc, char** argv) {
#elif defined(WIN32) || defined(MS_WINDOWS) #elif defined(WIN32) || defined(MS_WINDOWS)
int wmain(int argc, wchar_t **argv) { int %(wmain_method)s(int argc, wchar_t **argv) {
#else #else
static int __Pyx_main(int argc, wchar_t **argv) { static int __Pyx_main(int argc, wchar_t **argv) {
#endif #endif
...@@ -2667,9 +2676,13 @@ static int __Pyx_main(int argc, wchar_t **argv) { ...@@ -2667,9 +2676,13 @@ static int __Pyx_main(int argc, wchar_t **argv) {
m = fpgetmask(); m = fpgetmask();
fpsetmask(m & ~FP_X_OFL); fpsetmask(m & ~FP_X_OFL);
#endif #endif
if (argc) {
Py_SetProgramName(argv[0]); Py_SetProgramName(argv[0]);
}
Py_Initialize(); Py_Initialize();
if (argc) {
PySys_SetArgv(argc, argv); PySys_SetArgv(argc, argv);
}
%(module_is_main)s = 1; %(module_is_main)s = 1;
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
init%(module_name)s(); init%(module_name)s();
...@@ -2796,8 +2809,12 @@ oom: ...@@ -2796,8 +2809,12 @@ oom:
} }
int int
main(int argc, char **argv) %(main_method)s(int argc, char **argv)
{ {
if (!argc) {
return __Pyx_main(0, NULL);
}
else {
wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
/* We need a second copies, as Python might modify the first one. */ /* We need a second copies, as Python might modify the first one. */
wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
...@@ -2823,6 +2840,7 @@ main(int argc, char **argv) ...@@ -2823,6 +2840,7 @@ main(int argc, char **argv)
free(argv_copy); free(argv_copy);
free(argv_copy2); free(argv_copy2);
return res; return res;
}
} }
#endif #endif
""") """)
......
...@@ -44,9 +44,9 @@ lookup_module_cpdef = 0 ...@@ -44,9 +44,9 @@ lookup_module_cpdef = 0
init_local_none = 1 init_local_none = 1
# Whether or not to embed the Python interpreter, for use in making a # Whether or not to embed the Python interpreter, for use in making a
# standalone executable. This will provide a main() method which simply # standalone executable or calling from external libraries.
# executes the body of this module. # This will provide a method which simply executes the body of this module.
embed = False embed = None
# Disables function redefinition, allowing all functions to be declared at # Disables function redefinition, allowing all functions to be declared at
# module creation time. For legacy code only. # module creation time. For legacy code only.
......
...@@ -121,6 +121,12 @@ class MarkAssignments(CythonTransform): ...@@ -121,6 +121,12 @@ class MarkAssignments(CythonTransform):
self.visitchildren(node) self.visitchildren(node)
return node return node
def visit_DelStatNode(self, node):
for arg in node.args:
self.mark_assignment(arg, arg)
self.visitchildren(node)
return node
class MarkOverflowingArithmetic(CythonTransform): class MarkOverflowingArithmetic(CythonTransform):
# It may be possible to integrate this with the above for # It may be possible to integrate this with the above for
......
...@@ -29,9 +29,57 @@ cdef extern from "math.h": ...@@ -29,9 +29,57 @@ cdef extern from "math.h":
double asinh(double x) double asinh(double x)
double atanh(double x) double atanh(double x)
double hypot(double x, double y)
double exp(double x) double exp(double x)
double exp2(double x)
double expm1(double x)
double log(double x) double log(double x)
double logb(double x)
double log2(double x)
double log10(double x) double log10(double x)
double log1p(double x)
int ilogb(double x)
double lgamma(double x)
double tgamma(double x)
double frexp(double x, double* exponent)
double ldexp(double x, double exponent)
double modf(double x, double* iptr)
double fmod(double x, double y)
double remainder(double x, double y)
double remquo(double x, double y, int *quot)
double pow(double x, double y) double pow(double x, double y)
double sqrt(double x) double sqrt(double x)
double cbrt(double x)
double fabs(double x)
double ceil(double x)
double floor(double x)
double trunc(double x)
double rint(double x)
double round(double x)
double nearbyint(double x)
double nextafter(double, double)
double nexttoward(double, long double)
long long llrint(double)
long lrint(double)
long long llround(double)
long lround(double)
double copysign(double, double)
double erf(double)
double erfc(double)
double fdim(double x, double y)
double fma(double x, double y)
double fmax(double x, double y)
double fmin(double x, double y)
double scalbln(double x, long n)
double scalbn(double x, int n)
double nan(char*) # const char*
...@@ -737,11 +737,14 @@ ctypedef double complex complex128_t ...@@ -737,11 +737,14 @@ ctypedef double complex complex128_t
# numpy.int corresponds to 'l' and numpy.long to 'q' # numpy.int corresponds to 'l' and numpy.long to 'q'
ctypedef npy_long int_t ctypedef npy_long int_t
ctypedef npy_longlong long_t ctypedef npy_longlong long_t
ctypedef npy_intp intp_t ctypedef npy_longlong longlong_t
ctypedef npy_uintp uintp_t
ctypedef npy_ulong uint_t ctypedef npy_ulong uint_t
ctypedef npy_ulonglong ulong_t ctypedef npy_ulonglong ulong_t
ctypedef npy_ulonglong ulonglong_t
ctypedef npy_intp intp_t
ctypedef npy_uintp uintp_t
ctypedef npy_double float_t ctypedef npy_double float_t
ctypedef npy_double double_t ctypedef npy_double double_t
......
...@@ -5,7 +5,7 @@ PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])") ...@@ -5,7 +5,7 @@ PYVERSION=$(shell $(PYTHON) -c "import sys; print(sys.version[:3])")
INCDIR=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc())") INCDIR=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc())")
LIBDIR1=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") LIBDIR1=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
LIBDIR2=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBPL'))") LIBDIR2=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBPL'))")
STATIC_PYLIB=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBRARY'))") PYLIB=$(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBRARY')[3:-2])")
CC=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('CC'))") CC=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('CC'))")
LINKCC=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKCC'))") LINKCC=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKCC'))")
...@@ -14,13 +14,14 @@ LIBS=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig ...@@ -14,13 +14,14 @@ LIBS=$(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig
SYSLIBS= $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SYSLIBS'))") SYSLIBS= $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SYSLIBS'))")
embedded: embedded.o embedded: embedded.o
$(LINKCC) -o $@ $^ $(LIBDIR1)/$(STATIC_PYLIB) $(LINKFORSHARED) -L$(LIBDIR1) -L$(LIBDIR2) $(LIBS) $(SYSLIBS) $(LINKCC) -o $@ $^ -L$(LIBDIR1) -L$(LIBDIR2) -l$(PYLIB) $(LIBS) $(SYSLIBS) $(LINKFORSHARED)
embedded.o: embedded.c embedded.o: embedded.c
$(CC) -c $^ -I$(INCDIR) $(CC) -c $^ -I$(INCDIR)
CYTHON=../../cython.py
embedded.c: embedded.pyx embedded.c: embedded.pyx
@$(PYTHON) ../../cython.py --embed embedded.pyx @$(PYTHON) $(CYTHON) --embed embedded.pyx
all: embedded all: embedded
......
import sys import sys
if open(sys.argv[1]).read() != open(sys.argv[2]).read(): f1 = open(sys.argv[1])
print "Files differ" f2 = open(sys.argv[2])
try:
if f1.read() != f2.read():
print ("Files differ")
sys.exit(1) sys.exit(1)
else: else:
print "Files identical" print ("Files identical")
finally:
f1.close()
f2.close()
...@@ -28,6 +28,7 @@ except ImportError: # No threads, no problems ...@@ -28,6 +28,7 @@ except ImportError: # No threads, no problems
threading = None threading = None
WITH_CYTHON = True WITH_CYTHON = True
CY3_DIR = None
from distutils.dist import Distribution from distutils.dist import Distribution
from distutils.core import Extension from distutils.core import Extension
...@@ -176,8 +177,8 @@ class TestBuilder(object): ...@@ -176,8 +177,8 @@ class TestBuilder(object):
continue continue
suite.addTest( suite.addTest(
self.handle_directory(path, filename)) self.handle_directory(path, filename))
if sys.platform not in ['win32'] and sys.version_info[0] < 3: if sys.platform not in ['win32']:
# Non-Windows makefile, can't run Cython under Py3. # Non-Windows makefile.
if [1 for selector in self.selectors if selector("embedded")] \ if [1 for selector in self.selectors if selector("embedded")] \
and not [1 for selector in self.exclude_selectors if selector("embedded")]: and not [1 for selector in self.exclude_selectors if selector("embedded")]:
suite.addTest(unittest.makeSuite(EmbedTest)) suite.addTest(unittest.makeSuite(EmbedTest))
...@@ -193,7 +194,7 @@ class TestBuilder(object): ...@@ -193,7 +194,7 @@ class TestBuilder(object):
filenames = os.listdir(path) filenames = os.listdir(path)
filenames.sort() filenames.sort()
for filename in filenames: for filename in filenames:
if context == "build" and filename.endswith(".srctree"): if filename.endswith(".srctree"):
if not [ 1 for match in self.selectors if match(filename) ]: if not [ 1 for match in self.selectors if match(filename) ]:
continue continue
if self.exclude_selectors: if self.exclude_selectors:
...@@ -892,8 +893,12 @@ class EmbedTest(unittest.TestCase): ...@@ -892,8 +893,12 @@ class EmbedTest(unittest.TestCase):
if not os.path.isdir(libdir) or libname not in os.listdir(libdir): if not os.path.isdir(libdir) or libname not in os.listdir(libdir):
# report the error for the original directory # report the error for the original directory
libdir = sysconfig.get_config_var('LIBDIR') libdir = sysconfig.get_config_var('LIBDIR')
cython = 'cython.py'
if sys.version_info[0] >=3:
cython = os.path.join(CY3_DIR, cython)
cython = os.path.abspath(os.path.join('..', '..', cython))
self.assert_(os.system( self.assert_(os.system(
"make PYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, libdir)) == 0) "make PYTHON='%s' CYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, cython, libdir)) == 0)
try: try:
os.remove('make.output') os.remove('make.output')
except OSError: except OSError:
...@@ -967,6 +972,7 @@ def refactor_for_py3(distdir, cy3_dir): ...@@ -967,6 +972,7 @@ def refactor_for_py3(distdir, cy3_dir):
recursive-include Cython *.py *.pyx *.pxd recursive-include Cython *.py *.pyx *.pxd
recursive-include Cython/Debugger/Tests * recursive-include Cython/Debugger/Tests *
include runtests.py include runtests.py
include cython.py
''') ''')
sys.path.insert(0, cy3_dir) sys.path.insert(0, cy3_dir)
...@@ -1105,7 +1111,8 @@ def main(): ...@@ -1105,7 +1111,8 @@ def main():
for name in cy_modules: for name in cy_modules:
del sys.modules[name] del sys.modules[name]
# hasn't been refactored yet - do it now # hasn't been refactored yet - do it now
cy3_dir = os.path.join(WORKDIR, 'Cy3') global CY3_DIR
CY3_DIR = cy3_dir = os.path.join(WORKDIR, 'Cy3')
if sys.version_info >= (3,1): if sys.version_info >= (3,1):
refactor_for_py3(DISTDIR, cy3_dir) refactor_for_py3(DISTDIR, cy3_dir)
elif os.path.isdir(cy3_dir): elif os.path.isdir(cy3_dir):
......
# Errors reported during code generation.
cdef int i
def f(a):
del a # error: deletion of local name not supported
del i # error: deletion of local name not supported
_ERRORS = u"""
6:52: Deletion of local or C global name not supported
7:52: Deletion of local or C global name not supported
"""
...@@ -93,10 +93,10 @@ def test_char(char x): ...@@ -93,10 +93,10 @@ def test_char(char x):
Traceback (most recent call last): Traceback (most recent call last):
... ...
OverflowError: ... OverflowError: ...
>>> if CHAR_MIN < 0:
... assert test_char(-1) == -1
>>> test_char(CHAR_MIN) == CHAR_MIN >>> test_char(CHAR_MIN) == CHAR_MIN
True True
>>> test_char(-1)
-1
>>> test_char(0) >>> test_char(0)
0 0
>>> test_char(1) >>> test_char(1)
......
PYTHON setup.py build_ext --inplace
PYTHON -c "import a"
######## setup.py ########
from Cython.Build import cythonize
from distutils.core import setup
setup(
ext_modules = cythonize("*.pyx"),
)
######## other.pxd ########
cdef class A:
pass
cdef int foo(int)
######## other.pyx ########
cdef class A:
pass
cdef int foo(int a):
return a**2
######## a.pyx ########
from other cimport A, foo
print A, foo(10)
cimport other
print other.A, other.foo(10)
...@@ -80,3 +80,10 @@ def del_temp_slice(a): ...@@ -80,3 +80,10 @@ def del_temp_slice(a):
while a.attr: while a.attr:
del a.attr[:] del a.attr[:]
return a.attr return a.attr
def del_local(a):
"""
>>> del_local(object())
"""
del a
assert a is None # Until we have unbound locals...
...@@ -4,7 +4,10 @@ def test_get_char_neg(): ...@@ -4,7 +4,10 @@ def test_get_char_neg():
0 0
""" """
cdef char key = -1 cdef char key = -1
if <char>-1 < 0:
d = {-1:0} d = {-1:0}
else:
d = {255:0}
return d[key] return d[key]
def test_get_char_zero(): def test_get_char_zero():
""" """
......
...@@ -72,23 +72,23 @@ try: ...@@ -72,23 +72,23 @@ try:
Write to slices Write to slices
>>> b = a.copy() >>> b = a.copy()
>>> put_range_long_1d(b[:, 3]) >>> put_range_long_1d(b[:, 3])
>>> print b >>> print (b)
[[0 1 2 0 4] [[0 1 2 0 4]
[5 6 7 1 9]] [5 6 7 1 9]]
>>> put_range_long_1d(b[::-1, 3]) >>> put_range_long_1d(b[::-1, 3])
>>> print b >>> print (b)
[[0 1 2 1 4] [[0 1 2 1 4]
[5 6 7 0 9]] [5 6 7 0 9]]
>>> a = np.zeros(9, dtype='l') >>> a = np.zeros(9, dtype='l')
>>> put_range_long_1d(a[1::3]) >>> put_range_long_1d(a[1::3])
>>> print a >>> print (a)
[0 0 0 0 1 0 0 2 0] [0 0 0 0 1 0 0 2 0]
Write to picked subarrays. This should NOT change the original Write to picked subarrays. This should NOT change the original
array as picking creates a new mutable copy. array as picking creates a new mutable copy.
>>> a = np.zeros(10, dtype='l').reshape(2, 5) >>> a = np.zeros(10, dtype='l').reshape(2, 5)
>>> put_range_long_1d(a[[0, 0, 1, 1, 0], [0, 1, 2, 4, 3]]) >>> put_range_long_1d(a[[0, 0, 1, 1, 0], [0, 1, 2, 4, 3]])
>>> print a >>> print (a)
[[0 0 0 0 0] [[0 0 0 0 0]
[0 0 0 0 0]] [0 0 0 0 0]]
...@@ -103,18 +103,18 @@ try: ...@@ -103,18 +103,18 @@ try:
0 1 2 3 0 1 2 3
4 5 6 7 4 5 6 7
8 9 10 11 8 9 10 11
>>> test_c_contig(f_arr) >>> test_c_contig(f_arr) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: ndarray is not C contiguous ValueError: ndarray is not C...contiguous
>>> test_f_contig(c_arr) >>> test_f_contig(c_arr) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: ndarray is not Fortran contiguous ValueError: ndarray is not Fortran contiguous
>>> test_c_contig(c_arr[::2,::2]) >>> test_c_contig(c_arr[::2,::2]) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: ndarray is not C contiguous ValueError: ndarray is not C...contiguous
>>> test_dtype('b', inc1_byte) >>> test_dtype('b', inc1_byte)
>>> test_dtype('B', inc1_ubyte) >>> test_dtype('B', inc1_ubyte)
...@@ -137,7 +137,7 @@ try: ...@@ -137,7 +137,7 @@ try:
>>> test_dtype('G', inc1_clongdouble_struct) >>> test_dtype('G', inc1_clongdouble_struct)
>>> test_dtype(np.int, inc1_int_t) >>> test_dtype(np.int, inc1_int_t)
>>> test_dtype(np.long, inc1_long_t) >>> test_dtype(np.longlong, inc1_longlong_t)
>>> test_dtype(np.float, inc1_float_t) >>> test_dtype(np.float, inc1_float_t)
>>> test_dtype(np.double, inc1_double_t) >>> test_dtype(np.double, inc1_double_t)
>>> test_dtype(np.intp, inc1_intp_t) >>> test_dtype(np.intp, inc1_intp_t)
...@@ -150,10 +150,10 @@ try: ...@@ -150,10 +150,10 @@ try:
Endian tests: Endian tests:
>>> test_dtype('%si' % my_endian, inc1_int) >>> test_dtype('%si' % my_endian, inc1_int)
>>> test_dtype('%si' % other_endian, inc1_int) >>> test_dtype('%si' % other_endian, inc1_int) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Non-native byte order not supported ValueError: ...
...@@ -181,15 +181,15 @@ try: ...@@ -181,15 +181,15 @@ try:
array([(22, 23)], array([(22, 23)],
dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')]) dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')])
>>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) >>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Buffer dtype mismatch; next field is at offset 4 but 1 expected ValueError: ...
>>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) >>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected ValueError: ...
>>> test_good_cast() >>> test_good_cast()
...@@ -235,17 +235,17 @@ def ndarray_str(arr): ...@@ -235,17 +235,17 @@ def ndarray_str(arr):
return unicode(arr).replace(u'\n\n', u'\n<_BLANKLINE_>\n') return unicode(arr).replace(u'\n\n', u'\n<_BLANKLINE_>\n')
def basic(): def basic():
cdef object[int, ndim=2] buf = np.arange(10, dtype=b'i').reshape((2, 5)) cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5))
print buf print buf
print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0] print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0]
def three_dim(): def three_dim():
cdef object[double, ndim=3] buf = np.arange(24, dtype=b'd').reshape((3,2,4)) cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4))
print ndarray_str(buf) print ndarray_str(buf)
print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0] print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0]
def obj_array(): def obj_array():
cdef object[object, ndim=1] buf = np.array([b"a", 1, {}]) cdef object[object, ndim=1] buf = np.array(["a", 1, {}])
print buf print buf
print buf[0], buf[1], buf[2] print buf[0], buf[1], buf[2]
...@@ -262,12 +262,12 @@ def put_range_long_1d(np.ndarray[long] arr): ...@@ -262,12 +262,12 @@ def put_range_long_1d(np.ndarray[long] arr):
arr[i] = value arr[i] = value
value += 1 value += 1
def test_c_contig(np.ndarray[int, ndim=2, mode=b'c'] arr): def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr):
cdef int i, j cdef int i, j
for i in range(arr.shape[0]): for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
def test_f_contig(np.ndarray[int, ndim=2, mode=b'fortran'] arr): def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr):
cdef int i, j cdef int i, j
for i in range(arr.shape[0]): for i in range(arr.shape[0]):
print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
...@@ -314,6 +314,7 @@ def inc1_object(np.ndarray[object] arr): ...@@ -314,6 +314,7 @@ def inc1_object(np.ndarray[object] arr):
def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1 def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1
def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1 def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1
def inc1_longlong_t(np.ndarray[np.longlong_t] arr): arr[1] += 1
def inc1_float_t(np.ndarray[np.float_t] arr): arr[1] += 1 def inc1_float_t(np.ndarray[np.float_t] arr): arr[1] += 1
def inc1_double_t(np.ndarray[np.double_t] arr): arr[1] += 1 def inc1_double_t(np.ndarray[np.double_t] arr): arr[1] += 1
def inc1_longdouble_t(np.ndarray[np.longdouble_t] arr): arr[1] += 1 def inc1_longdouble_t(np.ndarray[np.longdouble_t] arr): arr[1] += 1
...@@ -330,7 +331,7 @@ def test_dtype(dtype, inc1): ...@@ -330,7 +331,7 @@ def test_dtype(dtype, inc1):
"G", np.clongdouble): "G", np.clongdouble):
if sizeof(double) == sizeof(long double): # MSVC if sizeof(double) == sizeof(long double): # MSVC
return return
if dtype in (b'F', b'D', b'G'): if dtype in ('F', 'D', 'G'):
a = np.array([0, 10+10j], dtype=dtype) a = np.array([0, 10+10j], dtype=dtype)
inc1(a) inc1(a)
if a[1] != (11 + 11j): print u"failed!", a[1] if a[1] != (11 + 11j): print u"failed!", a[1]
...@@ -344,7 +345,7 @@ cdef struct DoubleInt: ...@@ -344,7 +345,7 @@ cdef struct DoubleInt:
def test_recordarray(): def test_recordarray():
cdef object[DoubleInt] arr cdef object[DoubleInt] arr
arr = np.array([(5,5), (4, 6)], dtype=np.dtype(b'i,i')) arr = np.array([(5,5), (4, 6)], dtype=np.dtype('i,i'))
cdef DoubleInt rec cdef DoubleInt rec
rec = arr[0] rec = arr[0]
if rec.x != 5: print u"failed" if rec.x != 5: print u"failed"
...@@ -384,13 +385,13 @@ def test_bad_nested_dtypes(): ...@@ -384,13 +385,13 @@ def test_bad_nested_dtypes():
def test_good_cast(): def test_good_cast():
# Check that a signed int can round-trip through casted unsigned int access # Check that a signed int can round-trip through casted unsigned int access
cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype=b'i') cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i')
cdef unsigned int data = arr[0] cdef unsigned int data = arr[0]
return -100 == <int>data return -100 == <int>data
def test_bad_cast(): def test_bad_cast():
# This should raise an exception # This should raise an exception
cdef np.ndarray[int, cast=True] arr = np.array([1], dtype=b'b') cdef np.ndarray[int, cast=True] arr = np.array([1], dtype='b')
cdef packed struct PackedStruct: cdef packed struct PackedStruct:
char a char a
......
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