Commit ba35eb82 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

merge

parents 7d5a4f98 479590be
...@@ -368,12 +368,13 @@ def init_builtins(): ...@@ -368,12 +368,13 @@ def init_builtins():
init_builtin_funcs() init_builtin_funcs()
init_builtin_types() init_builtin_types()
init_builtin_structs() init_builtin_structs()
global list_type, tuple_type, dict_type, set_type, unicode_type, type_type global list_type, tuple_type, dict_type, set_type, bytes_type, unicode_type, type_type
type_type = builtin_scope.lookup('type').type type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type dict_type = builtin_scope.lookup('dict').type
set_type = builtin_scope.lookup('set').type set_type = builtin_scope.lookup('set').type
bytes_type = builtin_scope.lookup('bytes').type
unicode_type = builtin_scope.lookup('unicode').type unicode_type = builtin_scope.lookup('unicode').type
init_builtins() init_builtins()
...@@ -13,7 +13,7 @@ import Nodes ...@@ -13,7 +13,7 @@ import Nodes
from Nodes import Node from Nodes import Node
import PyrexTypes import PyrexTypes
from PyrexTypes import py_object_type, c_long_type, typecast, error_type from PyrexTypes import py_object_type, c_long_type, typecast, error_type
from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type
import Builtin import Builtin
import Symtab import Symtab
import Options import Options
...@@ -1705,8 +1705,6 @@ class IndexNode(ExprNode): ...@@ -1705,8 +1705,6 @@ class IndexNode(ExprNode):
if self.indices: if self.indices:
indices = self.indices indices = self.indices
else: else:
# On cloning, indices is cloned. Otherwise, unpack index into indices
assert not isinstance(self.index, CloneNode)
if isinstance(self.index, TupleNode): if isinstance(self.index, TupleNode):
indices = self.index.args indices = self.index.args
else: else:
...@@ -1719,6 +1717,9 @@ class IndexNode(ExprNode): ...@@ -1719,6 +1717,9 @@ class IndexNode(ExprNode):
if not x.type.is_int: if not x.type.is_int:
buffer_access = False buffer_access = False
# On cloning, indices is cloned. Otherwise, unpack index into indices
assert not (buffer_access and isinstance(self.index, CloneNode))
if buffer_access: if buffer_access:
self.indices = indices self.indices = indices
self.index = None self.index = None
...@@ -1998,22 +1999,32 @@ class SliceIndexNode(ExprNode): ...@@ -1998,22 +1999,32 @@ class SliceIndexNode(ExprNode):
def analyse_target_declaration(self, env): def analyse_target_declaration(self, env):
pass pass
def analyse_target_types(self, env):
self.analyse_types(env)
# when assigning, we must accept any Python type
if self.type.is_pyobject:
self.type = py_object_type
def analyse_types(self, env): def analyse_types(self, env):
self.base.analyse_types(env) self.base.analyse_types(env)
if self.start: if self.start:
self.start.analyse_types(env) self.start.analyse_types(env)
if self.stop: if self.stop:
self.stop.analyse_types(env) self.stop.analyse_types(env)
if self.base.type.is_string: base_type = self.base.type
self.type = py_object_type if base_type.is_string:
elif self.base.type.is_array or self.base.type.is_ptr: self.type = bytes_type
elif base_type.is_array or base_type.is_ptr:
# we need a ptr type here instead of an array type, as # we need a ptr type here instead of an array type, as
# array types can result in invalid type casts in the C # array types can result in invalid type casts in the C
# code # code
self.type = PyrexTypes.CPtrType(self.base.type.base_type) self.type = PyrexTypes.CPtrType(base_type.base_type)
else: else:
self.base = self.base.coerce_to_pyobject(env) self.base = self.base.coerce_to_pyobject(env)
self.type = py_object_type self.type = py_object_type
if base_type.is_builtin_type:
# slicing builtin types returns something of the same type
self.type = base_type
c_int = PyrexTypes.c_py_ssize_t_type c_int = PyrexTypes.c_py_ssize_t_type
if self.start: if self.start:
self.start = self.start.coerce_to(c_int, env) self.start = self.start.coerce_to(c_int, env)
...@@ -3003,11 +3014,12 @@ class SequenceNode(NewTempExprNode): ...@@ -3003,11 +3014,12 @@ class SequenceNode(NewTempExprNode):
def allocate_target_temps(self, env, rhs): def allocate_target_temps(self, env, rhs):
self.iterator.allocate_temps(env) self.iterator.allocate_temps(env)
for arg, node in zip(self.args, self.coerced_unpacked_items): for node in self.coerced_unpacked_items:
node.allocate_temps(env) node.allocate_temps(env)
arg.allocate_target_temps(env, None)
#arg.release_target_temp(env) #arg.release_target_temp(env)
#node.release_temp(env) #node.release_temp(env)
for arg in self.args:
arg.allocate_target_temps(env, None)
if rhs: if rhs:
rhs.release_temp(env) rhs.release_temp(env)
self.iterator.release_temp(env) self.iterator.release_temp(env)
......
...@@ -2471,7 +2471,11 @@ static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL; ...@@ -2471,7 +2471,11 @@ static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
main_method = UtilityCode( main_method = UtilityCode(
impl = """ impl = """
#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
int main(int argc, char** argv) { int main(int argc, char** argv) {
#else
int wmain(int argc, wchar_t **argv) {
#endif
int r = 0; int r = 0;
PyObject* m = NULL; PyObject* m = NULL;
Py_SetProgramName(argv[0]); Py_SetProgramName(argv[0]);
......
...@@ -1691,9 +1691,11 @@ class DefNode(FuncDefNode): ...@@ -1691,9 +1691,11 @@ class DefNode(FuncDefNode):
def analyse_signature(self, env): def analyse_signature(self, env):
any_type_tests_needed = 0 any_type_tests_needed = 0
if self.entry.is_special:
self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
# Use the simpler calling signature for zero- and one-argument functions. # Use the simpler calling signature for zero- and one-argument functions.
if not self.entry.is_special and not self.star_arg and not self.starstar_arg: if self.entry.signature is TypeSlots.pyfunction_signature:
if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
if len(self.args) == 0: if len(self.args) == 0:
self.entry.signature = TypeSlots.pyfunction_noargs self.entry.signature = TypeSlots.pyfunction_noargs
elif len(self.args) == 1: elif len(self.args) == 1:
...@@ -1705,8 +1707,6 @@ class DefNode(FuncDefNode): ...@@ -1705,8 +1707,6 @@ class DefNode(FuncDefNode):
elif len(self.args) == 2: elif len(self.args) == 2:
if self.args[1].default is None and not self.args[1].kw_only: if self.args[1].default is None and not self.args[1].kw_only:
self.entry.signature = TypeSlots.ibinaryfunc self.entry.signature = TypeSlots.ibinaryfunc
elif self.entry.is_special:
self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
sig = self.entry.signature sig = self.entry.signature
nfixed = sig.num_fixed_args() nfixed = sig.num_fixed_args()
for i in range(nfixed): for i in range(nfixed):
......
...@@ -45,11 +45,6 @@ lookup_module_cpdef = 0 ...@@ -45,11 +45,6 @@ lookup_module_cpdef = 0
# WARNING: This is a work in progress, may currently segfault. # WARNING: This is a work in progress, may currently segfault.
init_local_none = 1 init_local_none = 1
# Optimize no argument and one argument methods by using the METH_O and METH_NOARGS
# calling conventions. These are faster calling conventions, but disallow the use of
# keywords (which, admittedly, are of little use in these cases).
optimize_simple_methods = 1
# Append the c file and line number to the traceback for exceptions. # Append the c file and line number to the traceback for exceptions.
c_line_in_traceback = 1 c_line_in_traceback = 1
...@@ -68,6 +63,7 @@ option_defaults = { ...@@ -68,6 +63,7 @@ option_defaults = {
'auto_cpdef': False, 'auto_cpdef': False,
'cdivision': True, # Will be False in 0.12 'cdivision': True, # Will be False in 0.12
'cdivision_warnings': False, 'cdivision_warnings': False,
'always_allow_keywords': False,
} }
# Override types possibilities above, if needed # Override types possibilities above, if needed
......
...@@ -1498,6 +1498,9 @@ def p_statement(s, ctx, first_statement = 0): ...@@ -1498,6 +1498,9 @@ def p_statement(s, ctx, first_statement = 0):
decorators = p_decorators(s) decorators = p_decorators(s)
if s.sy not in ('def', 'cdef', 'cpdef'): if s.sy not in ('def', 'cdef', 'cpdef'):
s.error("Decorators can only be followed by functions ") s.error("Decorators can only be followed by functions ")
elif s.sy == 'pass' and cdef_flag:
# empty cdef block
return p_pass_statement(s, with_newline = 1)
overridable = 0 overridable = 0
if s.sy == 'cdef': if s.sy == 'cdef':
...@@ -1691,6 +1694,8 @@ def p_c_simple_base_type(s, self_flag, nonempty): ...@@ -1691,6 +1694,8 @@ def p_c_simple_base_type(s, self_flag, nonempty):
longness = 0 longness = 0
module_path = [] module_path = []
pos = s.position() pos = s.position()
if not s.sy == 'IDENT':
error(pos, "Expected an identifier, found '%s'" % s.sy)
if looking_at_base_type(s): if looking_at_base_type(s):
#print "p_c_simple_base_type: looking_at_base_type at", s.position() #print "p_c_simple_base_type: looking_at_base_type at", s.position()
is_basic = 1 is_basic = 1
...@@ -2068,31 +2073,30 @@ def p_cdef_statement(s, ctx): ...@@ -2068,31 +2073,30 @@ def p_cdef_statement(s, ctx):
elif s.sy == 'import': elif s.sy == 'import':
s.next() s.next()
return p_cdef_extern_block(s, pos, ctx) return p_cdef_extern_block(s, pos, ctx)
if p_nogil(s): elif p_nogil(s):
ctx.nogil = 1 ctx.nogil = 1
if s.sy == ':': if ctx.overridable:
error(pos, "cdef blocks cannot be declared cpdef")
return p_cdef_block(s, ctx)
elif s.sy == ':':
if ctx.overridable:
error(pos, "cdef blocks cannot be declared cpdef")
return p_cdef_block(s, ctx) return p_cdef_block(s, ctx)
elif s.sy == 'class': elif s.sy == 'class':
if ctx.level not in ('module', 'module_pxd'): if ctx.level not in ('module', 'module_pxd'):
error(pos, "Extension type definition not allowed here") error(pos, "Extension type definition not allowed here")
#if ctx.api: if ctx.overridable:
# error(pos, "'api' not allowed with extension class") error(pos, "Extension types cannot be declared cpdef")
return p_c_class_definition(s, pos, ctx) return p_c_class_definition(s, pos, ctx)
elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"): elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"):
if ctx.level not in ('module', 'module_pxd'): if ctx.level not in ('module', 'module_pxd'):
error(pos, "C struct/union/enum definition not allowed here") error(pos, "C struct/union/enum definition not allowed here")
#if ctx.visibility == 'public': if ctx.overridable:
# error(pos, "Public struct/union/enum definition not implemented") error(pos, "C struct/union/enum cannot be declared cpdef")
#if ctx.api:
# error(pos, "'api' not allowed with '%s'" % s.systring)
if s.systring == "enum": if s.systring == "enum":
return p_c_enum_definition(s, pos, ctx) return p_c_enum_definition(s, pos, ctx)
else: else:
return p_c_struct_or_union_definition(s, pos, ctx) return p_c_struct_or_union_definition(s, pos, ctx)
elif s.sy == 'pass':
node = p_pass_statement(s)
s.expect_newline('Expected a newline')
return node
else: else:
return p_c_func_or_var_declaration(s, pos, ctx) return p_c_func_or_var_declaration(s, pos, ctx)
...@@ -2100,6 +2104,8 @@ def p_cdef_block(s, ctx): ...@@ -2100,6 +2104,8 @@ def p_cdef_block(s, ctx):
return p_suite(s, ctx(cdef_flag = 1)) return p_suite(s, ctx(cdef_flag = 1))
def p_cdef_extern_block(s, pos, ctx): def p_cdef_extern_block(s, pos, ctx):
if ctx.overridable:
error(pos, "cdef extern blocks cannot be declared cpdef")
include_file = None include_file = None
s.expect('from') s.expect('from')
if s.sy == '*': if s.sy == '*':
......
...@@ -280,8 +280,14 @@ class BuiltinObjectType(PyObjectType): ...@@ -280,8 +280,14 @@ class BuiltinObjectType(PyObjectType):
base_type = None base_type = None
module_name = '__builtin__' module_name = '__builtin__'
alternative_name = None # used for str/bytes duality
def __init__(self, name, cname): def __init__(self, name, cname):
self.name = name self.name = name
if name == 'str':
self.alternative_name = 'bytes'
elif name == 'bytes':
self.alternative_name = 'str'
self.cname = cname self.cname = cname
self.typeptr_cname = "&" + cname self.typeptr_cname = "&" + cname
...@@ -298,7 +304,9 @@ class BuiltinObjectType(PyObjectType): ...@@ -298,7 +304,9 @@ class BuiltinObjectType(PyObjectType):
def assignable_from(self, src_type): def assignable_from(self, src_type):
if isinstance(src_type, BuiltinObjectType): if isinstance(src_type, BuiltinObjectType):
return src_type.name == self.name return src_type.name == self.name or (
src_type.name == self.alternative_name and
src_type.name is not None)
else: else:
return not src_type.is_extension_type return not src_type.is_extension_type
......
...@@ -642,7 +642,7 @@ if __name__ == '__main__': ...@@ -642,7 +642,7 @@ if __name__ == '__main__':
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors, filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir, options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, True, options.cleanup_sharedlibs, True,
options.cython_only, languages) options.cython_only, languages, test_bugs)
test_suite.addTest( test_suite.addTest(
filetests.handle_directory( filetests.handle_directory(
os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'), os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'),
......
cdef pass
cdef void
cdef nogil class test: pass
_ERRORS = u"""
2: 5: Expected an identifier, found 'pass'
3: 9: Empty declarator
4:11: Expected ':'
"""
cpdef nogil: pass
cpdef nogil class test: pass
_ERRORS = u"""
2: 6: cdef blocks cannot be declared cpdef
3: 6: cdef blocks cannot be declared cpdef
3:12: Expected ':'
"""
__doc__ = """
>>> 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):
pass
@cython.always_allow_keywords(False)
def func2(arg):
pass
@cython.always_allow_keywords(True)
def func3(arg):
pass
cdef class A:
def meth1(self, arg):
pass
@cython.always_allow_keywords(False)
def meth2(self, arg):
pass
@cython.always_allow_keywords(True)
def meth3(self, arg):
pass
...@@ -6,7 +6,7 @@ __doc__ = u''' ...@@ -6,7 +6,7 @@ __doc__ = u'''
>>> test_list(range(11), "invalid index", None) >>> test_list(range(11), "invalid index", None)
Traceback (most recent call last): Traceback (most recent call last):
... ...
TypeError: list indices must be integers TypeError: list indices must be integers, not str
''' '''
def no_cdef(): def no_cdef():
lst = range(11) lst = range(11)
......
"""
>>> myfunc()
0.5
"""
cimport numpy as np
import numpy as np
def myfunc():
cdef np.ndarray[float, ndim=2] A = np.ones((1,1), dtype=np.float32)
cdef int i
for i from 0 <= i < A.shape[0]:
A[i, :] /= 2
return A[0,0]
"""
>>> func()
0 0
0
0
1 1
1
1
2 2
2
2
>>> func2()
"""
def g():
return ((3, 2), 1, 0)
def func2():
(a, b), c, d = g()
def func():
for (a, b),c ,d in zip(zip(range(3), range(3)), range(3), range(3)):
print a, b
print c
print d
__doc__ = u"""
>>> l = [1,2,3,4]
>>> slice_list(l)
[2, 3]
>>> slice_tuple(tuple(l))
(2, 3)
>>> l2 = l[:]
>>> slice_list_assign_list(l2)
[1, 1, 2, 3, 4, 4]
>>> l2 = l[:]
>>> slice_list_assign_tuple(l2)
[1, 1, 2, 3, 4, 4]
>>> l2 = l[:]
>>> slice_list_assign(l2, (1,2,3,4))
[1, 1, 2, 3, 4, 4]
>>> l2 = l[:]
>>> slice_list_assign(l2, dict(zip(l,l)))
[1, 1, 2, 3, 4, 4]
>>> slice_charp('abcdefg')
'bc'
>>> slice_charp_repeat('abcdefg')
'cd'
"""
def slice_list(list l):
return l[1:3]
def slice_list_copy(list l):
cdef list retlist = l[1:3]
return retlist
def slice_tuple(tuple t):
return t[1:3]
def slice_list_assign_list(list l):
l[1:3] = [1,2,3,4]
return l
def slice_list_assign_tuple(list l):
l[1:3] = (1,2,3,4)
return l
def slice_list_assign(list l, value):
l[1:3] = value
return l
def slice_charp(str py_string):
cdef char* s = py_string
return s[1:3]
def slice_charp_repeat(str py_string):
cdef char* s = py_string
cdef str slice_val = s[1:6]
s = slice_val
return s[1:3]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment