Commit bd41e488 authored by Mark Florisson's avatar Mark Florisson

Merge branch 'master' of https://github.com/cython/cython

parents 98c5444d d93ea8d2
...@@ -37,3 +37,4 @@ ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1 ...@@ -37,3 +37,4 @@ ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2 7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2 7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2 8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2
a6b9f0a6d02d23fc3d3a9d0587867faa3afb2fcd 0.14.rc0
from glob import glob from glob import glob
import re, os, sys import re, os, sys
from cython import set
try:
set
except NameError:
# Python 2.3
from sets import Set as set
from distutils.extension import Extension from distutils.extension import Extension
...@@ -56,8 +52,8 @@ distutils_settings = { ...@@ -56,8 +52,8 @@ distutils_settings = {
'runtime_library_dirs': transitive_list, 'runtime_library_dirs': transitive_list,
'include_dirs': transitive_list, 'include_dirs': transitive_list,
'extra_objects': list, 'extra_objects': list,
'extra_compile_args': list, 'extra_compile_args': transitive_list,
'extra_link_args': list, 'extra_link_args': transitive_list,
'export_symbols': list, 'export_symbols': list,
'depends': transitive_list, 'depends': transitive_list,
'language': transitive_str, 'language': transitive_str,
...@@ -97,7 +93,7 @@ class DistutilsInfo(object): ...@@ -97,7 +93,7 @@ class DistutilsInfo(object):
elif exn is not None: elif exn is not None:
for key in distutils_settings: for key in distutils_settings:
if key in ('name', 'sources'): if key in ('name', 'sources'):
pass continue
value = getattr(exn, key, None) value = getattr(exn, key, None)
if value: if value:
self.values[key] = value self.values[key] = value
...@@ -168,7 +164,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): ...@@ -168,7 +164,7 @@ def strip_string_literals(code, prefix='__Pyx_L'):
# Try to close the quote. # Try to close the quote.
elif in_quote: elif in_quote:
if code[q-1] == '\\': if code[q-1] == '\\' and not raw:
k = 2 k = 2
while q >= k and code[q-k] == '\\': while q >= k and code[q-k] == '\\':
k += 1 k += 1
...@@ -177,7 +173,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): ...@@ -177,7 +173,7 @@ def strip_string_literals(code, prefix='__Pyx_L'):
continue continue
if code[q:q+len(in_quote)] == in_quote: if code[q:q+len(in_quote)] == in_quote:
counter += 1 counter += 1
label = "%s%s" % (prefix, counter) label = "%s%s_" % (prefix, counter)
literals[label] = code[start+len(in_quote):q] literals[label] = code[start+len(in_quote):q]
new_code.append("%s%s%s" % (in_quote, label, in_quote)) new_code.append("%s%s%s" % (in_quote, label, in_quote))
q += len(in_quote) q += len(in_quote)
...@@ -193,7 +189,7 @@ def strip_string_literals(code, prefix='__Pyx_L'): ...@@ -193,7 +189,7 @@ def strip_string_literals(code, prefix='__Pyx_L'):
end = None end = None
new_code.append(code[start:hash_mark+1]) new_code.append(code[start:hash_mark+1])
counter += 1 counter += 1
label = "%s%s" % (prefix, counter) label = "%s%s_" % (prefix, counter)
literals[label] = code[hash_mark+1:end] literals[label] = code[hash_mark+1:end]
new_code.append(label) new_code.append(label)
if end is None: if end is None:
...@@ -208,11 +204,11 @@ def strip_string_literals(code, prefix='__Pyx_L'): ...@@ -208,11 +204,11 @@ def strip_string_literals(code, prefix='__Pyx_L'):
in_quote = code[q]*3 in_quote = code[q]*3
else: else:
in_quote = code[q] in_quote = code[q]
end = q end = marker = q
while end>0 and code[end-1] in 'rRbBuU': while marker > 0 and code[marker-1] in 'rRbBuU':
if code[end-1] in 'rR': if code[marker-1] in 'rR':
raw = True raw = True
end -= 1 marker -= 1
new_code.append(code[start:end]) new_code.append(code[start:end])
start = q start = q
q += len(in_quote) q += len(in_quote)
...@@ -314,8 +310,8 @@ class DependencyTree(object): ...@@ -314,8 +310,8 @@ class DependencyTree(object):
self_pxd = [] self_pxd = []
a = self.cimports(filename) a = self.cimports(filename)
b = filter(None, [self.find_pxd(m, filename) for m in self.cimports(filename)]) b = filter(None, [self.find_pxd(m, filename) for m in self.cimports(filename)])
if len(a) != len(b): if len(a) - int('cython' in a) != len(b):
print(filename) print("missing cimport", filename)
print("\n\t".join(a)) print("\n\t".join(a))
print("\n\t".join(b)) print("\n\t".join(b))
return tuple(self_pxd + filter(None, [self.find_pxd(m, filename) for m in self.cimports(filename)])) return tuple(self_pxd + filter(None, [self.find_pxd(m, filename) for m in self.cimports(filename)]))
...@@ -390,9 +386,14 @@ def create_dependency_tree(ctx=None): ...@@ -390,9 +386,14 @@ def create_dependency_tree(ctx=None):
return _dep_tree return _dep_tree
# This may be useful for advanced users? # This may be useful for advanced users?
def create_extension_list(patterns, ctx=None, aliases=None): def create_extension_list(patterns, exclude=[], ctx=None, aliases=None):
seen = set() seen = set()
deps = create_dependency_tree(ctx) deps = create_dependency_tree(ctx)
to_exclude = set()
if not isinstance(exclude, list):
exclude = [exclude]
for pattern in exclude:
to_exclude.update(glob(pattern))
if not isinstance(patterns, list): if not isinstance(patterns, list):
patterns = [patterns] patterns = [patterns]
module_list = [] module_list = []
...@@ -416,27 +417,39 @@ def create_extension_list(patterns, ctx=None, aliases=None): ...@@ -416,27 +417,39 @@ def create_extension_list(patterns, ctx=None, aliases=None):
else: else:
raise TypeError(pattern) raise TypeError(pattern)
for file in glob(filepattern): for file in glob(filepattern):
if file in to_exclude:
continue
pkg = deps.package(file) pkg = deps.package(file)
if '*' in name: if '*' in name:
module_name = deps.fully_qualifeid_name(file) module_name = deps.fully_qualifeid_name(file)
else: else:
module_name = name module_name = name
if module_name not in seen: if module_name not in seen:
kwds = deps.distutils_info(file, aliases, base).values
if base is not None:
for key, value in base.values.items():
if key not in kwds:
kwds[key] = value
module_list.append(exn_type( module_list.append(exn_type(
name=module_name, name=module_name,
sources=[file], sources=[file],
**deps.distutils_info(file, aliases, base).values)) **kwds))
m = module_list[-1]
seen.add(name) seen.add(name)
return module_list return module_list
# This is the user-exposed entry point. # This is the user-exposed entry point.
def cythonize(module_list, nthreads=0, aliases=None, **options): def cythonize(module_list, exclude=[], nthreads=0, aliases=None, quiet=False, **options):
if 'include_path' not in options: if 'include_path' not in options:
options['include_path'] = ['.'] options['include_path'] = ['.']
c_options = CompilationOptions(**options) c_options = CompilationOptions(**options)
cpp_options = CompilationOptions(**options); cpp_options.cplus = True cpp_options = CompilationOptions(**options); cpp_options.cplus = True
ctx = c_options.create_context() ctx = c_options.create_context()
module_list = create_extension_list(module_list, ctx=ctx, aliases=aliases) module_list = create_extension_list(
module_list,
exclude=exclude,
ctx=ctx,
aliases=aliases)
deps = create_dependency_tree(ctx) deps = create_dependency_tree(ctx)
to_compile = [] to_compile = []
for m in module_list: for m in module_list:
...@@ -463,7 +476,11 @@ def cythonize(module_list, nthreads=0, aliases=None, **options): ...@@ -463,7 +476,11 @@ def cythonize(module_list, nthreads=0, aliases=None, **options):
dep_timestamp, dep = deps.newest_dependency(source) dep_timestamp, dep = deps.newest_dependency(source)
priority = 2 - (dep in deps.immediate_dependencies(source)) priority = 2 - (dep in deps.immediate_dependencies(source))
if c_timestamp < dep_timestamp: if c_timestamp < dep_timestamp:
print("Compiling %s because it depends on %s" % (source, dep)) if not quiet:
if source == dep:
print("Compiling %s because it changed." % source)
else:
print("Compiling %s because it depends on %s." % (source, dep))
to_compile.append((priority, source, c_file, options)) to_compile.append((priority, source, c_file, options))
new_sources.append(c_file) new_sources.append(c_file)
else: else:
......
#no doctest
print "Warning: Using prototype cython.inline code..."
import tempfile import tempfile
import sys, os, re, inspect import sys, os, re, inspect
from cython import set
try: try:
import hashlib import hashlib
...@@ -19,6 +17,16 @@ from Cython.Compiler.ParseTreeTransforms import CythonTransform, SkipDeclaration ...@@ -19,6 +17,16 @@ from Cython.Compiler.ParseTreeTransforms import CythonTransform, SkipDeclaration
from Cython.Compiler.TreeFragment import parse_from_strings from Cython.Compiler.TreeFragment import parse_from_strings
from Cython.Build.Dependencies import strip_string_literals, cythonize from Cython.Build.Dependencies import strip_string_literals, cythonize
# A utility function to convert user-supplied ASCII strings to unicode.
if sys.version_info[0] < 3:
def to_unicode(s):
if not isinstance(s, unicode):
return s.decode('ascii')
else:
return s
else:
to_unicode = lambda x: x
_code_cache = {} _code_cache = {}
...@@ -30,11 +38,10 @@ class AllSymbols(CythonTransform, SkipDeclarations): ...@@ -30,11 +38,10 @@ class AllSymbols(CythonTransform, SkipDeclarations):
self.names.add(node.name) self.names.add(node.name)
def unbound_symbols(code, context=None): def unbound_symbols(code, context=None):
code = to_unicode(code)
if context is None: if context is None:
context = Context([], default_options) context = Context([], default_options)
from Cython.Compiler.ParseTreeTransforms import AnalyseDeclarationsTransform from Cython.Compiler.ParseTreeTransforms import AnalyseDeclarationsTransform
if isinstance(code, str):
code = code.decode('ascii')
tree = parse_from_strings('(tree fragment)', code) tree = parse_from_strings('(tree fragment)', code)
for phase in context.create_pipeline(pxd=False): for phase in context.create_pipeline(pxd=False):
if phase is None: if phase is None:
...@@ -51,7 +58,14 @@ def unbound_symbols(code, context=None): ...@@ -51,7 +58,14 @@ def unbound_symbols(code, context=None):
unbound.append(name) unbound.append(name)
return unbound return unbound
def get_type(arg, context=None): def unsafe_type(arg, context=None):
py_type = type(arg)
if py_type is int:
return 'long'
else:
return safe_type(arg, context)
def safe_type(arg, context=None):
py_type = type(arg) py_type = type(arg)
if py_type in [list, tuple, dict, str]: if py_type in [list, tuple, dict, str]:
return py_type.__name__ return py_type.__name__
...@@ -61,8 +75,6 @@ def get_type(arg, context=None): ...@@ -61,8 +75,6 @@ def get_type(arg, context=None):
return 'double' return 'double'
elif py_type is bool: elif py_type is bool:
return 'bint' return 'bint'
elif py_type is int:
return 'long'
elif 'numpy' in sys.modules and isinstance(arg, sys.modules['numpy'].ndarray): elif 'numpy' in sys.modules and isinstance(arg, sys.modules['numpy'].ndarray):
return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim) return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim)
else: else:
...@@ -77,15 +89,20 @@ def get_type(arg, context=None): ...@@ -77,15 +89,20 @@ def get_type(arg, context=None):
return 'object' return 'object'
def cython_inline(code, def cython_inline(code,
types='aggressive', get_type=unsafe_type,
lib_dir=os.path.expanduser('~/.cython/inline'), lib_dir=os.path.expanduser('~/.cython/inline'),
cython_include_dirs=['.'], cython_include_dirs=['.'],
force=False,
quiet=False,
locals=None, locals=None,
globals=None, globals=None,
**kwds): **kwds):
if get_type is None:
get_type = lambda x: 'object'
code = to_unicode(code)
code, literals = strip_string_literals(code) code, literals = strip_string_literals(code)
code = strip_common_indent(code) code = strip_common_indent(code)
ctx = Context(include_dirs, default_options) ctx = Context(cython_include_dirs, default_options)
if locals is None: if locals is None:
locals = inspect.currentframe().f_back.f_back.f_locals locals = inspect.currentframe().f_back.f_back.f_locals
if globals is None: if globals is None:
...@@ -99,10 +116,11 @@ def cython_inline(code, ...@@ -99,10 +116,11 @@ def cython_inline(code,
elif symbol in globals: elif symbol in globals:
kwds[symbol] = globals[symbol] kwds[symbol] = globals[symbol]
else: else:
print "Couldn't find ", symbol print("Couldn't find ", symbol)
except AssertionError: except AssertionError:
# Parsing from strings not fully supported (e.g. cimports). if not quiet:
print "Could not parse code as a string (to extract unbound symbols)." # Parsing from strings not fully supported (e.g. cimports).
print("Could not parse code as a string (to extract unbound symbols).")
arg_names = kwds.keys() arg_names = kwds.keys()
arg_names.sort() arg_names.sort()
arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names]) arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names])
...@@ -113,8 +131,12 @@ def cython_inline(code, ...@@ -113,8 +131,12 @@ def cython_inline(code,
os.makedirs(lib_dir) os.makedirs(lib_dir)
if lib_dir not in sys.path: if lib_dir not in sys.path:
sys.path.append(lib_dir) sys.path.append(lib_dir)
__import__(module_name) if force:
raise ImportError
else:
__import__(module_name)
except ImportError: except ImportError:
cflags = []
c_include_dirs = [] c_include_dirs = []
cimports = [] cimports = []
qualified = re.compile(r'([.\w]+)[.]') qualified = re.compile(r'([.\w]+)[.]')
...@@ -126,6 +148,7 @@ def cython_inline(code, ...@@ -126,6 +148,7 @@ def cython_inline(code,
if m.groups()[0] == 'numpy': if m.groups()[0] == 'numpy':
import numpy import numpy
c_include_dirs.append(numpy.get_include()) c_include_dirs.append(numpy.get_include())
cflags.append('-Wno-unused')
module_body, func_body = extract_func_code(code) module_body, func_body = extract_func_code(code)
params = ', '.join(['%s %s' % a for a in arg_sigs]) params = ', '.join(['%s %s' % a for a in arg_sigs])
module_code = """ module_code = """
...@@ -141,10 +164,11 @@ def __invoke(%(params)s): ...@@ -141,10 +164,11 @@ def __invoke(%(params)s):
extension = Extension( extension = Extension(
name = module_name, name = module_name,
sources = [pyx_file], sources = [pyx_file],
include_dirs = c_include_dirs) include_dirs = c_include_dirs,
extra_compile_args = cflags)
build_extension = build_ext(Distribution()) build_extension = build_ext(Distribution())
build_extension.finalize_options() build_extension.finalize_options()
build_extension.extensions = cythonize([extension], ctx=ctx) build_extension.extensions = cythonize([extension], ctx=ctx, quiet=quiet)
build_extension.build_temp = os.path.dirname(pyx_file) build_extension.build_temp = os.path.dirname(pyx_file)
build_extension.build_lib = lib_dir build_extension.build_lib = lib_dir
build_extension.run() build_extension.run()
......
from Cython.Shadow import inline
from Cython.Build.Inline import safe_type
from Cython.TestUtils import CythonTest
try:
import numpy
has_numpy = True
except:
has_numpy = False
test_kwds = dict(force=True, quiet=True)
global_value = 100
class TestInline(CythonTest):
def test_simple(self):
self.assertEquals(inline("return 1+2", **test_kwds), 3)
def test_types(self):
self.assertEquals(inline("""
cimport cython
return cython.typeof(a), cython.typeof(b)
""", a=1.0, b=[], **test_kwds), ('double', 'list object'))
def test_locals(self):
a = 1
b = 2
self.assertEquals(inline("return a+b", **test_kwds), 3)
def test_globals(self):
self.assertEquals(inline("return global_value + 1", **test_kwds), global_value + 1)
if has_numpy:
def test_numpy(self):
import numpy
a = numpy.ndarray((10, 20))
a[0,0] = 10
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)
from Cython.Build.Dependencies import strip_string_literals
from Cython.TestUtils import CythonTest
class TestStripLiterals(CythonTest):
def t(self, before, expected):
actual, literals = strip_string_literals(before, prefix="_L")
self.assertEquals(expected, actual)
for key, value in literals.items():
actual = actual.replace(key, value)
self.assertEquals(before, actual)
def test_empty(self):
self.t("", "")
def test_single_quote(self):
self.t("'x'", "'_L1_'")
def test_double_quote(self):
self.t('"x"', '"_L1_"')
def test_nested_quotes(self):
self.t(""" '"' "'" """, """ '_L1_' "_L2_" """)
def test_triple_quote(self):
self.t(" '''a\n''' ", " '''_L1_''' ")
def test_backslash(self):
self.t(r"'a\'b'", "'_L1_'")
self.t(r"'a\\'", "'_L1_'")
self.t(r"'a\\\'b'", "'_L1_'")
def test_unicode(self):
self.t("u'abc'", "u'_L1_'")
def test_raw(self):
self.t(r"r'abc\'", "r'_L1_'")
def test_raw_unicode(self):
self.t(r"ru'abc\'", "ru'_L1_'")
def test_comment(self):
self.t("abc # foo", "abc #_L1_")
def test_comment_and_quote(self):
self.t("abc # 'x'", "abc #_L1_")
self.t("'abc#'", "'_L1_'")
def test_include(self):
self.t("include 'a.pxi' # something here",
"include '_L1_' #_L2_")
def test_extern(self):
self.t("cdef extern from 'a.h': # comment",
"cdef extern from '_L1_': #_L2_")
...@@ -4045,7 +4045,7 @@ class ListNode(SequenceNode): ...@@ -4045,7 +4045,7 @@ class ListNode(SequenceNode):
self.obj_conversion_errors = [] self.obj_conversion_errors = []
if not self.type.subtype_of(dst_type): if not self.type.subtype_of(dst_type):
error(self.pos, "Cannot coerce list to type '%s'" % dst_type) error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
elif dst_type.is_ptr: elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
base_type = dst_type.base_type base_type = dst_type.base_type
self.type = PyrexTypes.CArrayType(base_type, len(self.args)) self.type = PyrexTypes.CArrayType(base_type, len(self.args))
for i in range(len(self.original_args)): for i in range(len(self.original_args)):
...@@ -4181,12 +4181,13 @@ class ScopedExprNode(ExprNode): ...@@ -4181,12 +4181,13 @@ class ScopedExprNode(ExprNode):
code.put_var_declaration(entry) code.put_var_declaration(entry)
if entry.type.is_pyobject and entry.used: if entry.type.is_pyobject and entry.used:
py_entries.append(entry) py_entries.append(entry)
code.put_init_var_to_py_none(entry)
if not py_entries: if not py_entries:
# no local Python references => no cleanup required # no local Python references => no cleanup required
generate_inner_evaluation_code(code) generate_inner_evaluation_code(code)
code.putln('} /* exit inner scope */') code.putln('} /* exit inner scope */')
return return
for entry in py_entries:
code.put_init_var_to_py_none(entry)
# must free all local Python references at each exit point # must free all local Python references at each exit point
old_loop_labels = tuple(code.new_loop_labels()) old_loop_labels = tuple(code.new_loop_labels())
......
...@@ -20,12 +20,6 @@ from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform ...@@ -20,12 +20,6 @@ from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform
from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler.Errors import error, warning, CompileError, InternalError from Cython.Compiler.Errors import error, warning, CompileError, InternalError
try:
set
except NameError:
from sets import Set as set
import copy import copy
...@@ -1590,7 +1584,7 @@ class DebugTransform(CythonTransform): ...@@ -1590,7 +1584,7 @@ class DebugTransform(CythonTransform):
def __init__(self, context, options, result): def __init__(self, context, options, result):
super(DebugTransform, self).__init__(context) super(DebugTransform, self).__init__(context)
self.visited = set() self.visited = cython.set()
# our treebuilder and debug output writer # our treebuilder and debug output writer
# (see Cython.Debugger.debug_output.CythonDebugWriter) # (see Cython.Debugger.debug_output.CythonDebugWriter)
self.tb = self.context.gdb_debug_outputwriter self.tb = self.context.gdb_debug_outputwriter
......
...@@ -635,6 +635,8 @@ class CNumericType(CType): ...@@ -635,6 +635,8 @@ class CNumericType(CType):
is_numeric = 1 is_numeric = 1
default_value = "0" default_value = "0"
has_attributes = True
scope = None
sign_words = ("unsigned ", "", "signed ") sign_words = ("unsigned ", "", "signed ")
...@@ -658,6 +660,23 @@ class CNumericType(CType): ...@@ -658,6 +660,23 @@ class CNumericType(CType):
else: else:
base_code = public_decl(type_name, dll_linkage) base_code = public_decl(type_name, dll_linkage)
return self.base_declaration_code(base_code, entity_code) return self.base_declaration_code(base_code, entity_code)
def attributes_known(self):
if self.scope is None:
import Symtab
self.scope = scope = Symtab.CClassScope(
'',
None,
visibility="extern")
scope.parent_type = self
scope.directives = {}
entry = scope.declare_cfunction(
"conjugate",
CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
pos=None,
defining=1,
cname=" ")
return True
type_conversion_predeclarations = "" type_conversion_predeclarations = ""
...@@ -1080,7 +1099,7 @@ class CComplexType(CNumericType): ...@@ -1080,7 +1099,7 @@ class CComplexType(CNumericType):
scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True) scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True)
entry = scope.declare_cfunction( entry = scope.declare_cfunction(
"conjugate", "conjugate",
CFuncType(self, [CFuncTypeArg("self", self, None)]), CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True),
pos=None, pos=None,
defining=1, defining=1,
cname="__Pyx_c_conj%s" % self.funcsuffix) cname="__Pyx_c_conj%s" % self.funcsuffix)
......
...@@ -114,4 +114,4 @@ class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase): ...@@ -114,4 +114,4 @@ class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
self.assertEqual(type(frame), libpython.PyFrameObjectPtr) self.assertEqual(type(frame), libpython.PyFrameObjectPtr)
\ No newline at end of file
...@@ -188,6 +188,7 @@ except NameError: # Py3 ...@@ -188,6 +188,7 @@ except NameError: # Py3
py_float = float py_float = float
py_complex = complex py_complex = complex
try: try:
# Python 3 # Python 3
from builtins import set, frozenset from builtins import set, frozenset
......
...@@ -64,4 +64,4 @@ class TestStringIOTree(unittest.TestCase): ...@@ -64,4 +64,4 @@ class TestStringIOTree(unittest.TestCase):
if tree is None: if tree is None:
tree = self.tree tree = self.tree
tree.markers.append(lineno) tree.markers.append(lineno)
tree.write(linemap[lineno] + '\n') tree.write(linemap[lineno] + '\n')
\ No newline at end of file
__version__ = "0.14.beta2" __version__ = "0.14.rc0"
# Void cython.* directives (for case insensitive operating systems). # Void cython.* directives (for case insensitive operating systems).
from Cython.Shadow import * from Cython.Shadow import *
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
double sinc(double x) { double sinc(double x) {
return x == 0 ? 1 : sin(x)/x; return x == 0 ? 1 : sin(x)/x;
} }
\ No newline at end of file
#
# This example demonstrates how to access the internals
# of a Numeric array object.
#
cdef extern from "Numeric/arrayobject.h":
struct PyArray_Descr:
int type_num, elsize
char type
ctypedef class Numeric.ArrayType [object PyArrayObject]:
cdef char *data
cdef int nd
cdef int *dimensions, *strides
cdef object base
cdef PyArray_Descr *descr
cdef int flags
def print_2d_array(ArrayType a):
print "Type:", chr(a.descr.type)
if chr(a.descr.type) <> "f":
raise TypeError("Float array required")
if a.nd <> 2:
raise ValueError("2 dimensional array required")
cdef int nrows, ncols
cdef float *elems, x
nrows = a.dimensions[0]
ncols = a.dimensions[1]
elems = <float *>a.data
hyphen = "-"
divider = ("+" + 10 * hyphen) * ncols + "+"
print divider
for row in range(nrows):
for col in range(ncols):
x = elems[row * ncols + col]
print "| %8f" % x,
print "|"
print divider
cimport numpy
import numpy
def sum_of_squares(numpy.ndarray[double, ndim=1] arr):
cdef long N = arr.shape[0]
cdef double ss = 0
for i in range(N):
ss += arr[i]**2
return ss
import glob # Run as:
# python setup.py build_ext --inplace
from distutils.core import setup from distutils.core import setup
from distutils.extension import Extension from distutils.extension import Extension
from Cython.Distutils import build_ext from Cython.Build import cythonize
ext_modules = cythonize("*.pyx", exclude="numpy_*.pyx")
# Only compile the following if numpy is installed.
try: try:
from numpy.distutils.misc_util import get_numpy_include_dirs from numpy.distutils.misc_util import get_numpy_include_dirs
numpy_include_dirs = get_numpy_include_dirs() numpy_demo = Extension("*",
except: ["numpy_*.pyx"],
numpy_include_dirs = [] include_dirs=get_numpy_include_dirs())
ext_modules.extend(cythonize(numpy_demo))
ext_modules=[ except ImportError:
Extension("primes", ["primes.pyx"]), pass
Extension("spam", ["spam.pyx"]),
]
for file in glob.glob("*.pyx"):
if file != "numeric_demo.pyx":
ext_modules.append(Extension(file[:-4], [file], include_dirs = numpy_include_dirs))
setup( setup(
name = 'Demos', name = 'Demos',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules, ext_modules = ext_modules,
) )
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
cdef class Spam: cdef class Spam:
cdef public int amount cdef public int amount
def __new__(self): def __cinit__(self):
self.amount = 0 self.amount = 0
def __dealloc__(self): def __dealloc__(self):
......
#include "Python.h" static PyObject *__Pyx_UnpackItem(PyObject *, int); static int __Pyx_EndUnpack(PyObject *, int); static int __Pyx_PrintItem(PyObject *); static int __Pyx_PrintNewline(void); static void __Pyx_ReRaise(void); static void __Pyx_RaiseWithTraceback(PyObject *, PyObject *, PyObject *); static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); static PyObject *__Pyx_GetExcValue(void); static PyObject *__Pyx_GetName(PyObject *dict, char *name); static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args); /*proto*/ PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args) { int __pyx_v_kmax; int __pyx_v_n; int __pyx_v_k; int __pyx_v_i; int (__pyx_v_p[1000]); PyObject *__pyx_v_result; PyObject *__pyx_r; PyObject *__pyx_1 = 0; int __pyx_2; int __pyx_3; int __pyx_4; PyObject *__pyx_5 = 0; PyObject *__pyx_6 = 0; if (!PyArg_ParseTuple(__pyx_args, "i", &__pyx_v_kmax)) return 0; __pyx_v_result = Py_None; Py_INCREF(__pyx_v_result); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":2 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":3 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":4 */ __pyx_1 = PyList_New(0); if (!__pyx_1) goto __pyx_L1; Py_DECREF(__pyx_v_result); __pyx_v_result = __pyx_1; __pyx_1 = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":5 */ __pyx_2 = (__pyx_v_kmax > 1000); if (__pyx_2) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":6 */ __pyx_v_kmax = 1000; goto __pyx_L2; } __pyx_L2:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":7 */ __pyx_v_k = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":8 */ __pyx_v_n = 2; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":9 */ while (1) { __pyx_L3:; __pyx_2 = (__pyx_v_k < __pyx_v_kmax); if (!__pyx_2) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":10 */ __pyx_v_i = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":11 */ while (1) { __pyx_L5:; if (__pyx_3 = (__pyx_v_i < __pyx_v_k)) { __pyx_3 = ((__pyx_v_n % (__pyx_v_p[__pyx_v_i])) != 0); } if (!__pyx_3) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":12 */ __pyx_v_i = (__pyx_v_i + 1); } __pyx_L6:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":13 */ __pyx_4 = (__pyx_v_i == __pyx_v_k); if (__pyx_4) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":14 */ (__pyx_v_p[__pyx_v_k]) = __pyx_v_n; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":15 */ __pyx_v_k = (__pyx_v_k + 1); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":16 */ __pyx_1 = PyObject_GetAttrString(__pyx_v_result, "append"); if (!__pyx_1) goto __pyx_L1; __pyx_5 = PyInt_FromLong(__pyx_v_n); if (!__pyx_5) goto __pyx_L1; __pyx_6 = PyTuple_New(1); if (!__pyx_6) goto __pyx_L1; PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5); __pyx_5 = 0; __pyx_5 = PyObject_CallObject(__pyx_1, __pyx_6); if (!__pyx_5) goto __pyx_L1; Py_DECREF(__pyx_6); __pyx_6 = 0; Py_DECREF(__pyx_5); __pyx_5 = 0; goto __pyx_L7; } __pyx_L7:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":17 */ __pyx_v_n = (__pyx_v_n + 1); } __pyx_L4:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":18 */ Py_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L0; __pyx_r = Py_None; Py_INCREF(__pyx_r); goto __pyx_L0; __pyx_L1:; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_5); Py_XDECREF(__pyx_6); __pyx_r = 0; __pyx_L0:; Py_DECREF(__pyx_v_result); return __pyx_r; } static struct PyMethodDef __pyx_methods[] = { {"primes", (PyCFunction)__pyx_f_primes, METH_VARARGS, 0}, {0, 0, 0, 0} }; void initprimes(void); /*proto*/ void initprimes(void) { __pyx_m = Py_InitModule4("primes", __pyx_methods, 0, 0, PYTHON_API_VERSION); __pyx_d = PyModule_GetDict(__pyx_m); __pyx_b = PyImport_AddModule("__builtin__"); PyDict_SetItemString(__pyx_d, "__builtins__", __pyx_b); }/* Runtime support code */ #include "Python.h" static PyObject *__Pyx_UnpackItem(PyObject *, int); static int __Pyx_EndUnpack(PyObject *, int); static int __Pyx_PrintItem(PyObject *); static int __Pyx_PrintNewline(void); static void __Pyx_ReRaise(void); static void __Pyx_RaiseWithTraceback(PyObject *, PyObject *, PyObject *); static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); static PyObject *__Pyx_GetExcValue(void); static PyObject *__Pyx_GetName(PyObject *dict, char *name); static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args); /*proto*/ PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args) { int __pyx_v_kmax; int __pyx_v_n; int __pyx_v_k; int __pyx_v_i; int (__pyx_v_p[1000]); PyObject *__pyx_v_result; PyObject *__pyx_r; PyObject *__pyx_1 = 0; int __pyx_2; int __pyx_3; int __pyx_4; PyObject *__pyx_5 = 0; PyObject *__pyx_6 = 0; if (!PyArg_ParseTuple(__pyx_args, "i", &__pyx_v_kmax)) return 0; __pyx_v_result = Py_None; Py_INCREF(__pyx_v_result); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":2 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":3 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":4 */ __pyx_1 = PyList_New(0); if (!__pyx_1) goto __pyx_L1; Py_DECREF(__pyx_v_result); __pyx_v_result = __pyx_1; __pyx_1 = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":5 */ __pyx_2 = (__pyx_v_kmax > 1000); if (__pyx_2) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":6 */ __pyx_v_kmax = 1000; goto __pyx_L2; } __pyx_L2:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":7 */ __pyx_v_k = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":8 */ __pyx_v_n = 2; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":9 */ while (1) { __pyx_L3:; __pyx_2 = (__pyx_v_k < __pyx_v_kmax); if (!__pyx_2) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":10 */ __pyx_v_i = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":11 */ while (1) { __pyx_L5:; if (__pyx_3 = (__pyx_v_i < __pyx_v_k)) { __pyx_3 = ((__pyx_v_n % (__pyx_v_p[__pyx_v_i])) != 0); } if (!__pyx_3) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":12 */ __pyx_v_i = (__pyx_v_i + 1); } __pyx_L6:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":13 */ __pyx_4 = (__pyx_v_i == __pyx_v_k); if (__pyx_4) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":14 */ (__pyx_v_p[__pyx_v_k]) = __pyx_v_n; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":15 */ __pyx_v_k = (__pyx_v_k + 1); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":16 */ __pyx_1 = PyObject_GetAttrString(__pyx_v_result, "append"); if (!__pyx_1) goto __pyx_L1; __pyx_5 = PyInt_FromLong(__pyx_v_n); if (!__pyx_5) goto __pyx_L1; __pyx_6 = PyTuple_New(1); if (!__pyx_6) goto __pyx_L1; PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5); __pyx_5 = 0; __pyx_5 = PyObject_CallObject(__pyx_1, __pyx_6); if (!__pyx_5) goto __pyx_L1; Py_DECREF(__pyx_6); __pyx_6 = 0; Py_DECREF(__pyx_5); __pyx_5 = 0; goto __pyx_L7; } __pyx_L7:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":17 */ __pyx_v_n = (__pyx_v_n + 1); } __pyx_L4:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":18 */ Py_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L0; __pyx_r = Py_None; Py_INCREF(__pyx_r); goto __pyx_L0; __pyx_L1:; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_5); Py_XDECREF(__pyx_6); __pyx_r = 0; __pyx_L0:; Py_DECREF(__pyx_v_result); return __pyx_r; } static struct PyMethodDef __pyx_methods[] = { {"primes", (PyCFunction)__pyx_f_primes, METH_VARARGS, 0}, {0, 0, 0, 0} }; void initprimes(void); /*proto*/ void initprimes(void) { __pyx_m = Py_InitModule4("primes", __pyx_methods, 0, 0, PYTHON_API_VERSION); __pyx_d = PyModule_GetDict(__pyx_m); __pyx_b = PyImport_AddModule("__builtin__"); PyDict_SetItemString(__pyx_d, "__builtins__", __pyx_b); }/* Runtime support code */
\ No newline at end of file
......
...@@ -645,7 +645,11 @@ class CythonUnitTestCase(CythonCompileTestCase): ...@@ -645,7 +645,11 @@ class CythonUnitTestCase(CythonCompileTestCase):
pass pass
include_debugger = sys.version_info[:2] > (2, 5) try:
import gdb
include_debugger = sys.version_info[:2] > (2, 5)
except:
include_debugger = False
def collect_unittests(path, module_prefix, suite, selectors): def collect_unittests(path, module_prefix, suite, selectors):
def file_matches(filename): def file_matches(filename):
...@@ -703,26 +707,26 @@ def collect_doctests(path, module_prefix, suite, selectors): ...@@ -703,26 +707,26 @@ def collect_doctests(path, module_prefix, suite, selectors):
filename in blacklist) filename in blacklist)
import doctest, types import doctest, types
for dirpath, dirnames, filenames in os.walk(path): for dirpath, dirnames, filenames in os.walk(path):
parentname = os.path.split(dirpath)[-1] for dir in list(dirnames):
if package_matches(parentname): if not package_matches(dir):
for f in filenames: dirnames.remove(dir)
if file_matches(f): for f in filenames:
if not f.endswith('.py'): continue if file_matches(f):
filepath = os.path.join(dirpath, f) if not f.endswith('.py'): continue
if os.path.getsize(filepath) == 0: continue filepath = os.path.join(dirpath, f)
if 'no doctest' in open(filepath).next(): continue if os.path.getsize(filepath) == 0: continue
filepath = filepath[:-len(".py")] filepath = filepath[:-len(".py")]
modulename = module_prefix + filepath[len(path)+1:].replace(os.path.sep, '.') modulename = module_prefix + filepath[len(path)+1:].replace(os.path.sep, '.')
if not [ 1 for match in selectors if match(modulename) ]: if not [ 1 for match in selectors if match(modulename) ]:
continue continue
module = __import__(modulename) module = __import__(modulename)
for x in modulename.split('.')[1:]: for x in modulename.split('.')[1:]:
module = getattr(module, x) module = getattr(module, x)
if hasattr(module, "__doc__") or hasattr(module, "__test__"): if hasattr(module, "__doc__") or hasattr(module, "__test__"):
try: try:
suite.addTest(doctest.DocTestSuite(module)) suite.addTest(doctest.DocTestSuite(module))
except ValueError: # no tests except ValueError: # no tests
pass pass
class EndToEndTest(unittest.TestCase): class EndToEndTest(unittest.TestCase):
......
...@@ -264,6 +264,7 @@ packages = [ ...@@ -264,6 +264,7 @@ packages = [
'Cython.Distutils', 'Cython.Distutils',
'Cython.Plex', 'Cython.Plex',
'Cython.Tests', 'Cython.Tests',
'Cython.Build.Tests',
'Cython.Compiler.Tests', 'Cython.Compiler.Tests',
] ]
......
...@@ -162,6 +162,11 @@ def test_conjugate_typedef(cdouble z): ...@@ -162,6 +162,11 @@ def test_conjugate_typedef(cdouble z):
""" """
return z.conjugate() return z.conjugate()
cdef cdouble test_conjugate_nogil(cdouble z) nogil:
# Really just a compile test.
return z.conjugate()
test_conjugate_nogil(0) # use it
## cdef extern from "complex_numbers_T305.h": ## cdef extern from "complex_numbers_T305.h":
## ctypedef double double_really_float "myfloat" ## ctypedef double double_really_float "myfloat"
## ctypedef float float_really_double "mydouble" ## ctypedef float float_really_double "mydouble"
......
from d cimport d from d cimport d
\ No newline at end of file
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