Commit 9a80574b authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'master' into cpdef-enums

Conflicts:
	CHANGES.rst
parents 148fe039 0f339147
......@@ -16,9 +16,15 @@ Features added
* Cpdef enums are now first-class iterable, callable types in Python.
* Posix declarations for DLL loading and stdio extensions were added.
Patch by Lars Buitinck.
Bugs fixed
----------
* C++ exceptions raised by overloaded C++ operators were not always
handled. Patch by Ian Henriksen.
* C string literals were previously always stored as non-const global
variables in the module. They are now stored as global constants
when possible, and otherwise as non-const C string literals in the
......@@ -26,6 +32,11 @@ Bugs fixed
strict C compiler options and prevents non-const strings literals
with the same content from being incorrectly merged.
* Compile time evaluated ``str`` expressions (``DEF``) now behave in a
more useful way by turning into Unicode strings when compiling under
Python 3. This allows using them as intermediate values in expressions.
Previously, they always evaluated to bytes objects.
* ``isinf()`` declarations in ``libc/math.pxd`` and ``numpy/math.pxd`` now
reflect the actual tristate ``int`` return value instead of using ``bint``.
......@@ -36,18 +47,33 @@ Other changes
-------------
0.23.2 (2015-0x-yy)
0.23.3 (2015-??-??)
===================
Bugs fixed
----------
* Invalid C code for some builtin methods. This fixes ticket 856 again.
* Incorrect C code in helper functions for PyLong conversion and string
decoding. This fixes ticket 863, ticket 864 and ticket 865.
Original patch by Nikolaus Rath.
0.23.2 (2015-09-11)
===================
Bugs fixed
----------
* Compiler crash when analysing some optimised expressions.
* Coverage plugin was adapted to coverage.py 4.0 beta 2.
* C++ destructor calls could fail when '&' operator is overwritten.
* Large integers in compile-time evaluated DEF expressions were
incorrectly handled under Python 2.x.
* Incorrect C literal generation for large integers in compile-time
evaluated DEF expressions and constant folded expressions.
* Byte string constants could end up as Unicode strings when originating
from compile-time evaluated DEF expressions.
......@@ -57,6 +83,11 @@ Bugs fixed
* ``ino_t`` in ``posix.types`` was not declared as ``unsigned``.
* Declarations in ``libcpp/memory.pxd`` were missing ``operator!()``.
Patch by Leo Razoumov.
* Static cdef methods can now be declared in .pxd files.
0.23.1 (2015-08-22)
===================
......
......@@ -201,7 +201,13 @@ class BufferEntry(object):
self.type = entry.type
self.cname = entry.buffer_aux.buflocal_nd_var.cname
self.buf_ptr = "%s.rcbuffer->pybuffer.buf" % self.cname
self.buf_ptr_type = self.entry.type.buffer_ptr_type
self.buf_ptr_type = entry.type.buffer_ptr_type
self.init_attributes()
def init_attributes(self):
self.shape = self.get_buf_shapevars()
self.strides = self.get_buf_stridevars()
self.suboffsets = self.get_buf_suboffsetvars()
def get_buf_suboffsetvars(self):
return self._for_all_ndim("%s.diminfo[%d].suboffsets")
......
......@@ -702,6 +702,8 @@ class FunctionState(object):
"""
if type.is_const and not type.is_reference:
type = type.const_base_type
elif type.is_reference and not type.is_fake_reference:
type = type.ref_base_type
if not type.is_pyobject and not type.is_memoryviewslice:
# Make manage_ref canonical, so that manage_ref will always mean
# a decref is needed.
......
This diff is collapsed.
......@@ -200,7 +200,7 @@ class FusedCFuncDefNode(StatListNode):
if arg.type.is_fused:
arg.type = arg.type.specialize(fused_to_specific)
if arg.type.is_memoryviewslice:
MemoryView.validate_memslice_dtype(arg.pos, arg.type.dtype)
arg.type.validate_memslice_dtype(arg.pos)
def create_new_local_scope(self, node, env, f2s):
"""
......
This diff is collapsed.
......@@ -1054,8 +1054,8 @@ class MemoryViewSliceTypeNode(CBaseTypeNode):
if not MemoryView.validate_axes(self.pos, axes_specs):
self.type = error_type
else:
MemoryView.validate_memslice_dtype(self.pos, base_type)
self.type = PyrexTypes.MemoryViewSliceType(base_type, axes_specs)
self.type.validate_memslice_dtype(self.pos)
self.use_memview_utilities(env)
return self.type
......@@ -1327,13 +1327,13 @@ class CVarDefNode(StatNode):
error(declarator.pos, "Missing name in declaration.")
return
if type.is_cfunction:
if 'staticmethod' in env.directives:
type.is_static_method = True
self.entry = dest_scope.declare_cfunction(name, type, declarator.pos,
cname=cname, visibility=self.visibility, in_pxd=self.in_pxd,
api=self.api, modifiers=self.modifiers, overridable=self.overridable)
if self.entry is not None:
self.entry.directive_locals = copy.copy(self.directive_locals)
if 'staticmethod' in env.directives:
type.is_static_method = True
if create_extern_wrapper:
self.entry.type.create_to_py_utility_code(env)
self.entry.create_wrapper = True
......@@ -4807,6 +4807,8 @@ class SingleAssignmentNode(AssignmentNode):
# rhs ExprNode Right hand side
# first bool Is this guaranteed the first assignment to lhs?
# is_overloaded_assignment bool Is this assignment done via an overloaded operator=
# exception_check
# exception_value
child_attrs = ["lhs", "rhs"]
first = False
......@@ -4906,36 +4908,29 @@ class SingleAssignmentNode(AssignmentNode):
if unrolled_assignment:
return unrolled_assignment
if self.lhs.memslice_broadcast or self.rhs.memslice_broadcast:
self.lhs.memslice_broadcast = True
self.rhs.memslice_broadcast = True
if (self.lhs.is_subscript and not self.rhs.type.is_memoryviewslice and
(self.lhs.memslice_slice or self.lhs.is_memslice_copy) and
(self.lhs.type.dtype.assignable_from(self.rhs.type) or
self.rhs.type.is_pyobject)):
# scalar slice assignment
self.lhs.is_memslice_scalar_assignment = True
dtype = self.lhs.type.dtype
if isinstance(self.lhs, ExprNodes.MemoryViewIndexNode):
self.lhs.analyse_broadcast_operation(self.rhs)
self.lhs = self.lhs.analyse_as_memview_scalar_assignment(self.rhs)
elif self.lhs.type.is_array:
if not isinstance(self.lhs, ExprNodes.SliceIndexNode):
# cannot assign to C array, only to its full slice
self.lhs = ExprNodes.SliceIndexNode(
self.lhs.pos, base=self.lhs, start=None, stop=None)
self.lhs = ExprNodes.SliceIndexNode(self.lhs.pos, base=self.lhs, start=None, stop=None)
self.lhs = self.lhs.analyse_target_types(env)
dtype = self.lhs.type
else:
dtype = self.lhs.type
if self.lhs.type.is_cpp_class:
op = env.lookup_operator_for_types(self.pos, '=', [self.lhs.type, self.rhs.type])
if op:
rhs = self.rhs
self.is_overloaded_assignment = True
self.exception_check = op.type.exception_check
self.exception_value = op.type.exception_value
if self.exception_check == '+' and self.exception_value is None:
env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
else:
rhs = self.rhs.coerce_to(dtype, env)
rhs = self.rhs.coerce_to(self.lhs.type, env)
else:
rhs = self.rhs.coerce_to(dtype, env)
rhs = self.rhs.coerce_to(self.lhs.type, env)
if use_temp or rhs.is_attribute or (
not rhs.is_name and not rhs.is_literal and
rhs.type.is_pyobject):
......@@ -5045,12 +5040,12 @@ class SingleAssignmentNode(AssignmentNode):
assignments = []
for lhs, rhs in zip(lhs_list, rhs_list):
assignments.append(SingleAssignmentNode(self.pos, lhs=lhs, rhs=rhs, first=self.first))
all = ParallelAssignmentNode(pos=self.pos, stats=assignments).analyse_expressions(env)
node = ParallelAssignmentNode(pos=self.pos, stats=assignments).analyse_expressions(env)
if check_node:
all = StatListNode(pos=self.pos, stats=[check_node, all])
node = StatListNode(pos=self.pos, stats=[check_node, node])
for ref in refs[::-1]:
all = UtilNodes.LetNode(ref, all)
return all
node = UtilNodes.LetNode(ref, node)
return node
def unroll_rhs(self, env):
from . import ExprNodes
......@@ -5069,7 +5064,7 @@ class SingleAssignmentNode(AssignmentNode):
if self.lhs.type.is_ctuple:
# Handled directly.
return
from . import ExprNodes, UtilNodes
from . import ExprNodes
if not isinstance(self.rhs, ExprNodes.TupleNode):
return
......@@ -5083,8 +5078,15 @@ class SingleAssignmentNode(AssignmentNode):
self.rhs.generate_evaluation_code(code)
def generate_assignment_code(self, code, overloaded_assignment=False):
self.lhs.generate_assignment_code(
self.rhs, code, overloaded_assignment=self.is_overloaded_assignment)
if self.is_overloaded_assignment:
self.lhs.generate_assignment_code(
self.rhs,
code,
overloaded_assignment=self.is_overloaded_assignment,
exception_check=self.exception_check,
exception_value=self.exception_value)
else:
self.lhs.generate_assignment_code(self.rhs, code)
def generate_function_definitions(self, env, code):
self.rhs.generate_function_definitions(env, code)
......@@ -5271,8 +5273,7 @@ class InPlaceAssignmentNode(AssignmentNode):
self.lhs = self.lhs.analyse_target_types(env)
# When assigning to a fully indexed buffer or memoryview, coerce the rhs
if (self.lhs.is_subscript and
(self.lhs.memslice_index or self.lhs.is_buffer_access)):
if self.lhs.is_memview_index or self.lhs.is_buffer_access:
self.rhs = self.rhs.coerce_to(self.lhs.type, env)
elif self.lhs.type.is_string and self.operator in '+-':
# use pointer arithmetic for char* LHS instead of string concat
......@@ -5281,28 +5282,30 @@ class InPlaceAssignmentNode(AssignmentNode):
def generate_execution_code(self, code):
code.mark_pos(self.pos)
self.rhs.generate_evaluation_code(code)
self.lhs.generate_subexpr_evaluation_code(code)
lhs, rhs = self.lhs, self.rhs
rhs.generate_evaluation_code(code)
lhs.generate_subexpr_evaluation_code(code)
c_op = self.operator
if c_op == "//":
c_op = "/"
elif c_op == "**":
error(self.pos, "No C inplace power operator")
if self.lhs.is_subscript and self.lhs.is_buffer_access:
if self.lhs.type.is_pyobject:
if lhs.is_buffer_access or lhs.is_memview_index:
if lhs.type.is_pyobject:
error(self.pos, "In-place operators not allowed on object buffers in this release.")
if (c_op in ('/', '%') and self.lhs.type.is_int
and not code.globalstate.directives['cdivision']):
if c_op in ('/', '%') and lhs.type.is_int and not code.globalstate.directives['cdivision']:
error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
lhs.generate_buffer_setitem_code(rhs, code, c_op)
elif lhs.is_memview_slice:
error(self.pos, "Inplace operators not supported on memoryview slices")
else:
# C++
# TODO: make sure overload is declared
code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
self.lhs.generate_subexpr_disposal_code(code)
self.lhs.free_subexpr_temps(code)
self.rhs.generate_disposal_code(code)
self.rhs.free_temps(code)
code.putln("%s %s= %s;" % (lhs.result(), c_op, rhs.result()))
lhs.generate_subexpr_disposal_code(code)
lhs.free_subexpr_temps(code)
rhs.generate_disposal_code(code)
rhs.free_temps(code)
def annotate(self, code):
self.lhs.annotate(code)
......@@ -6354,8 +6357,8 @@ class ForFromStatNode(LoopNode, StatNode):
"for-from loop variable must be c numeric type or Python object")
if target_type.is_numeric:
self.is_py_target = False
if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
raise error(self.pos, "Buffer indexing not allowed as for loop target.")
if isinstance(self.target, ExprNodes.BufferIndexNode):
raise error(self.pos, "Buffer or memoryview slicing/indexing not allowed as for-loop target.")
self.loopvar_node = self.target
self.py_loopvar_node = None
else:
......
......@@ -132,7 +132,7 @@ class IterationTransform(Visitor.EnvTransform):
pos = node.pos
result_ref = UtilNodes.ResultRefNode(node)
if isinstance(node.operand2, ExprNodes.IndexNode):
if node.operand2.is_subscript:
base_type = node.operand2.base.type.base_type
else:
base_type = node.operand2.type.base_type
......@@ -442,7 +442,7 @@ class IterationTransform(Visitor.EnvTransform):
error(slice_node.pos, "C array iteration requires known end index")
return node
elif isinstance(slice_node, ExprNodes.IndexNode):
elif slice_node.is_subscript:
assert isinstance(slice_node.index, ExprNodes.SliceNode)
slice_base = slice_node.base
index = slice_node.index
......@@ -564,7 +564,6 @@ class IterationTransform(Visitor.EnvTransform):
constant_result=0,
type=PyrexTypes.c_int_type),
base=counter_temp,
is_buffer_access=False,
type=ptr_type.base_type)
if target_value.type != node.target.type:
......@@ -1334,20 +1333,20 @@ class DropRefcountingTransform(Visitor.VisitorTransform):
node = node.arg
name_path = []
obj_node = node
while isinstance(obj_node, ExprNodes.AttributeNode):
while obj_node.is_attribute:
if obj_node.is_py_attr:
return False
name_path.append(obj_node.member)
obj_node = obj_node.obj
if isinstance(obj_node, ExprNodes.NameNode):
if obj_node.is_name:
name_path.append(obj_node.name)
names.append( ('.'.join(name_path[::-1]), node) )
elif isinstance(node, ExprNodes.IndexNode):
elif node.is_subscript:
if node.base.type != Builtin.list_type:
return False
if not node.index.type.is_int:
return False
if not isinstance(node.base, ExprNodes.NameNode):
if not node.base.is_name:
return False
indices.append(node)
else:
......@@ -1979,7 +1978,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
elif isinstance(arg, ExprNodes.SimpleCallNode):
if node.type.is_int or node.type.is_float:
return self._optimise_numeric_cast_call(node, arg)
elif isinstance(arg, ExprNodes.IndexNode) and not arg.is_buffer_access:
elif arg.is_subscript:
index_node = arg.index
if isinstance(index_node, ExprNodes.CoerceToPyTypeNode):
index_node = index_node.arg
......@@ -4213,6 +4212,10 @@ class FinalOptimizePhase(Visitor.CythonTransform, Visitor.NodeRefCleanupMixin):
assignment.rhs and not isinstance(assignment.rhs, non_method_nodes)
for assignment in entry.cf_assignments)
if may_be_a_method:
if (node.self and function.is_attribute and
isinstance(function.obj, ExprNodes.CloneNode) and function.obj.arg is node.self):
# function self object was moved into a CloneNode => undo
function.obj = function.obj.arg
node = self.replace(node, ExprNodes.PyMethodCallNode.from_node(
node, function=function, arg_tuple=node.arg_tuple, type=node.type))
return node
......
......@@ -17,7 +17,7 @@ from . import Builtin
from .Visitor import VisitorTransform, TreeVisitor
from .Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform
from .UtilNodes import LetNode, LetRefNode, ResultRefNode
from .UtilNodes import LetNode, LetRefNode
from .TreeFragment import TreeFragment
from .StringEncoding import EncodedString, _unicode
from .Errors import error, warning, CompileError, InternalError
......@@ -1307,6 +1307,7 @@ class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations):
node.decorator_indirection = reassignment
return [node, reassignment]
class CnameDirectivesTransform(CythonTransform, SkipDeclarations):
"""
Only part of the CythonUtilityCode pipeline. Must be run before
......@@ -1340,7 +1341,7 @@ class CnameDirectivesTransform(CythonTransform, SkipDeclarations):
raise AssertionError(
"argument to cname decorator must be a string literal")
cname = args[0].compile_time_value(None).decode('UTF-8')
cname = args[0].compile_time_value(None)
del node.decorators[i]
node = Nodes.CnameDecoratorNode(pos=node.pos, node=node,
cname=cname)
......@@ -1931,13 +1932,8 @@ class AnalyseExpressionsTransform(CythonTransform):
re-analyse the types.
"""
self.visit_Node(node)
if node.is_fused_index and not node.type.is_error:
node = node.base
elif node.memslice_ellipsis_noop:
# memoryviewslice[...] expression, drop the IndexNode
node = node.base
return node
......@@ -1971,26 +1967,26 @@ class ExpandInplaceOperators(EnvTransform):
if lhs.type.is_cpp_class:
# No getting around this exact operator here.
return node
if isinstance(lhs, ExprNodes.IndexNode) and lhs.is_buffer_access:
# There is code to handle this case.
if isinstance(lhs, ExprNodes.BufferIndexNode):
# There is code to handle this case in InPlaceAssignmentNode
return node
env = self.current_env()
def side_effect_free_reference(node, setting=False):
if isinstance(node, ExprNodes.NameNode):
if node.is_name:
return node, []
elif node.type.is_pyobject and not setting:
node = LetRefNode(node)
return node, [node]
elif isinstance(node, ExprNodes.IndexNode):
if node.is_buffer_access:
raise ValueError("Buffer access")
elif node.is_subscript:
base, temps = side_effect_free_reference(node.base)
index = LetRefNode(node.index)
return ExprNodes.IndexNode(node.pos, base=base, index=index), temps + [index]
elif isinstance(node, ExprNodes.AttributeNode):
elif node.is_attribute:
obj, temps = side_effect_free_reference(node.obj)
return ExprNodes.AttributeNode(node.pos, obj=obj, attribute=node.attribute), temps
elif isinstance(node, ExprNodes.BufferIndexNode):
raise ValueError("Don't allow things like attributes of buffer indexing operations")
else:
node = LetRefNode(node)
return node, [node]
......
......@@ -762,8 +762,7 @@ def wrap_compile_time_constant(pos, value):
elif isinstance(value, bool):
return ExprNodes.BoolNode(pos, value=value)
elif isinstance(value, int):
return ExprNodes.IntNode(
pos, value=rep, constant_result=value, unsigned='U' if value > 0 else '')
return ExprNodes.IntNode(pos, value=rep, constant_result=value)
elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value=rep, constant_result=value)
elif isinstance(value, _unicode):
......@@ -780,9 +779,7 @@ def wrap_compile_time_constant(pos, value):
# error already reported
return None
elif not _IS_PY3 and isinstance(value, long):
return ExprNodes.IntNode(
pos, value=rep.rstrip('L'), longness="L", constant_result=value,
unsigned='U' if value > 0 else '')
return ExprNodes.IntNode(pos, value=rep.rstrip('L'), constant_result=value)
error(pos, "Invalid type for compile-time constant: %r (type %s)"
% (value, value.__class__.__name__))
return None
......
......@@ -541,7 +541,7 @@ class MemoryViewSliceType(PyrexType):
the *first* axis' packing spec and 'follow' for all other packing
specs.
"""
from . import MemoryView
from . import Buffer, MemoryView
self.dtype = base_dtype
self.axes = axes
......@@ -555,7 +555,7 @@ class MemoryViewSliceType(PyrexType):
self.writable_needed = False
if not self.dtype.is_fused:
self.dtype_name = MemoryView.mangle_dtype_name(self.dtype)
self.dtype_name = Buffer.mangle_dtype_name(self.dtype)
def __hash__(self):
return hash(self.__class__) ^ hash(self.dtype) ^ hash(tuple(self.axes))
......@@ -638,25 +638,28 @@ class MemoryViewSliceType(PyrexType):
elif attribute in ("copy", "copy_fortran"):
ndim = len(self.axes)
to_axes_c = [('direct', 'contig')]
to_axes_f = [('direct', 'contig')]
if ndim - 1:
to_axes_c = [('direct', 'follow')]*(ndim-1) + to_axes_c
to_axes_f = to_axes_f + [('direct', 'follow')]*(ndim-1)
follow_dim = [('direct', 'follow')]
contig_dim = [('direct', 'contig')]
to_axes_c = follow_dim * (ndim - 1) + contig_dim
to_axes_f = contig_dim + follow_dim * (ndim -1)
to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c)
to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f)
for to_memview, cython_name in [(to_memview_c, "copy"),
(to_memview_f, "copy_fortran")]:
entry = scope.declare_cfunction(cython_name,
CFuncType(self, [CFuncTypeArg("memviewslice", self, None)]),
pos=pos,
defining=1,
cname=MemoryView.copy_c_or_fortran_cname(to_memview))
copy_func_type = CFuncType(
to_memview,
[CFuncTypeArg("memviewslice", self, None)])
copy_cname = MemoryView.copy_c_or_fortran_cname(to_memview)
entry = scope.declare_cfunction(
cython_name,
copy_func_type, pos=pos, defining=1,
cname=copy_cname)
#entry.utility_code_definition = \
env.use_utility_code(MemoryView.get_copy_new_utility(pos, self, to_memview))
utility = MemoryView.get_copy_new_utility(pos, self, to_memview)
env.use_utility_code(utility)
MemoryView.use_cython_array_utility_code(env)
......@@ -684,9 +687,102 @@ class MemoryViewSliceType(PyrexType):
return True
def get_entry(self, node, cname=None, type=None):
from . import MemoryView, Symtab
if cname is None:
assert node.is_simple() or node.is_temp or node.is_elemental
cname = node.result()
if type is None:
type = node.type
entry = Symtab.Entry(cname, cname, type, node.pos)
return MemoryView.MemoryViewSliceBufferEntry(entry)
def conforms_to(self, dst, broadcast=False, copying=False):
"""
Returns True if src conforms to dst, False otherwise.
If conformable, the types are the same, the ndims are equal, and each axis spec is conformable.
Any packing/access spec is conformable to itself.
'direct' and 'ptr' are conformable to 'full'.
'contig' and 'follow' are conformable to 'strided'.
Any other combo is not conformable.
"""
from . import MemoryView
src = self
if src.dtype != dst.dtype:
return False
if src.ndim != dst.ndim:
if broadcast:
src, dst = MemoryView.broadcast_types(src, dst)
else:
return False
for src_spec, dst_spec in zip(src.axes, dst.axes):
src_access, src_packing = src_spec
dst_access, dst_packing = dst_spec
if src_access != dst_access and dst_access != 'full':
return False
if src_packing != dst_packing and dst_packing != 'strided' and not copying:
return False
return True
def valid_dtype(self, dtype, i=0):
"""
Return whether type dtype can be used as the base type of a
memoryview slice.
We support structs, numeric types and objects
"""
if dtype.is_complex and dtype.real_type.is_int:
return False
if dtype.is_struct and dtype.kind == 'struct':
for member in dtype.scope.var_entries:
if not self.valid_dtype(member.type):
return False
return True
return (
dtype.is_error or
# Pointers are not valid (yet)
# (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or
(dtype.is_array and i < 8 and self.valid_dtype(dtype.base_type, i + 1)) or
dtype.is_numeric or
dtype.is_pyobject or
dtype.is_fused or # accept this as it will be replaced by specializations later
(dtype.is_typedef and self.valid_dtype(dtype.typedef_base_type))
)
def validate_memslice_dtype(self, pos):
if not self.valid_dtype(self.dtype):
error(pos, "Invalid base type for memoryview slice: %s" % self.dtype)
def assert_direct_dims(self, pos):
for access, packing in self.axes:
if access != 'direct':
error(pos, "All dimensions must be direct")
return False
return True
def transpose(self, pos):
if not self.assert_direct_dims(pos):
return error_type
return MemoryViewSliceType(self.dtype, self.axes[::-1])
def specialization_name(self):
return super(MemoryViewSliceType,self).specialization_name() \
+ '_' + self.specialization_suffix()
return '%s_%s' % (
super(MemoryViewSliceType,self).specialization_name(),
self.specialization_suffix())
def specialization_suffix(self):
return "%s_%s" % (self.axes_to_name(), self.dtype_name)
......@@ -874,6 +970,11 @@ class BufferType(BaseType):
self.negative_indices, self.cast)
return self
def get_entry(self, node):
from . import Buffer
assert node.is_name
return Buffer.BufferEntry(node.entry)
def __getattr__(self, name):
return getattr(self.base, name)
......
......@@ -103,13 +103,17 @@ def initial_compile_time_env():
except ImportError:
import builtins
names = ('False', 'True',
'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes',
'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate', 'filter',
'float', 'format', 'frozenset', 'hash', 'hex', 'int', 'len',
'list', 'long', 'map', 'max', 'min', 'oct', 'ord', 'pow', 'range',
'repr', 'reversed', 'round', 'set', 'slice', 'sorted', 'str',
'sum', 'tuple', 'xrange', 'zip')
names = (
'False', 'True',
'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes',
'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate', 'filter',
'float', 'format', 'frozenset', 'hash', 'hex', 'int', 'len',
'list', 'map', 'max', 'min', 'oct', 'ord', 'pow', 'range',
'repr', 'reversed', 'round', 'set', 'slice', 'sorted', 'str',
'sum', 'tuple', 'zip',
### defined below in a platform independent way
# 'long', 'unicode', 'reduce', 'xrange'
)
for name in names:
try:
......@@ -117,6 +121,14 @@ def initial_compile_time_env():
except AttributeError:
# ignore, likely Py3
pass
# Py2/3 adaptations
from functools import reduce
benv.declare('reduce', reduce)
benv.declare('unicode', getattr(builtins, 'unicode', getattr(builtins, 'str')))
benv.declare('long', getattr(builtins, 'long', getattr(builtins, 'int')))
benv.declare('xrange', getattr(builtins, 'xrange', getattr(builtins, 'range')))
denv = CompileTimeScope(benv)
return denv
......
......@@ -155,6 +155,11 @@ class ResultRefNode(AtomicExprNode):
else:
return ()
def update_expression(self, expression):
self.expression = expression
if hasattr(expression, "type"):
self.type = expression.type
def analyse_types(self, env):
if self.expression is not None:
self.type = self.expression.type
......@@ -256,6 +261,7 @@ class LetNodeMixin:
code.put_decref_clear(self.temp, self.temp_type)
code.funcstate.release_temp(self.temp)
class EvalWithTempExprNode(ExprNodes.ExprNode, LetNodeMixin):
# A wrapper around a subexpression that moves an expression into a
# temp variable and provides it to the subexpression.
......@@ -277,6 +283,7 @@ class EvalWithTempExprNode(ExprNodes.ExprNode, LetNodeMixin):
def analyse_types(self, env):
self.temp_expression = self.temp_expression.analyse_types(env)
self.lazy_temp.update_expression(self.temp_expression) # overwrite in case it changed
self.subexpression = self.subexpression.analyse_types(env)
self.type = self.subexpression.type
return self
......@@ -292,8 +299,10 @@ class EvalWithTempExprNode(ExprNodes.ExprNode, LetNodeMixin):
self.subexpression.generate_evaluation_code(code)
self.teardown_temp_expr(code)
LetRefNode = ResultRefNode
class LetNode(Nodes.StatNode, LetNodeMixin):
# Implements a local temporary variable scope. Imagine this
# syntax being present:
......
......@@ -416,8 +416,7 @@ class NodeRefCleanupMixin(object):
def visit_CloneNode(self, node):
arg = node.arg
if arg not in self._replacements:
self.visitchildren(node)
arg = node.arg
self.visitchildren(arg)
node.arg = self._replacements.get(arg, arg)
return node
......@@ -679,6 +678,13 @@ class RecursiveNodeReplacer(VisitorTransform):
super(RecursiveNodeReplacer, self).__init__()
self.orig_node, self.new_node = orig_node, new_node
def visit_CloneNode(self, node):
if node is self.orig_node:
return self.new_node
if node.arg is self.orig_node:
node.arg = self.new_node
return node
def visit_Node(self, node):
self.visitchildren(node)
if node is self.orig_node:
......@@ -725,6 +731,7 @@ def replace_node(ptr, value):
else:
getattr(parent, attrname)[listidx] = value
class PrintTree(TreeVisitor):
"""Prints a representation of the tree to standard output.
Subclass and override repr_of to provide more information
......@@ -753,6 +760,25 @@ class PrintTree(TreeVisitor):
# under the parent-node, not displaying the list itself in
# the hierarchy.
def visit_Node(self, node):
self._print_node(node)
self.indent()
self.visitchildren(node)
self.unindent()
return node
def visit_CloneNode(self, node):
self._print_node(node)
self.indent()
line = node.pos[1]
if self._line_range is None or self._line_range[0] <= line <= self._line_range[1]:
print("%s- %s: %s" % (self._indent, 'arg', self.repr_of(node.arg)))
self.indent()
self.visitchildren(node.arg)
self.unindent()
self.unindent()
return node
def _print_node(self, node):
line = node.pos[1]
if self._line_range is None or self._line_range[0] <= line <= self._line_range[1]:
if len(self.access_path) == 0:
......@@ -764,10 +790,6 @@ class PrintTree(TreeVisitor):
else:
name = attr
print("%s- %s: %s" % (self._indent, name, self.repr_of(node)))
self.indent()
self.visitchildren(node)
self.unindent()
return node
def repr_of(self, node):
if node is None:
......
......@@ -126,7 +126,7 @@ def main(path_to_debug_info=None, gdb_argv=None, no_import=False):
logging_level = logging.WARN
if options.verbosity == 1:
logging_level = logging.INFO
if options.verbosity == 2:
if options.verbosity >= 2:
logging_level = logging.DEBUG
logging.basicConfig(level=logging_level)
......
......@@ -2,42 +2,42 @@
cdef extern from "float.h":
enum: FLT_RADIX
const float FLT_RADIX
enum: FLT_MANT_DIG
enum: DBL_MANT_DIG
enum: LDBL_MANT_DIG
const float FLT_MANT_DIG
const double DBL_MANT_DIG
const long double LDBL_MANT_DIG
enum: DECIMAL_DIG
const double DECIMAL_DIG
enum: FLT_DIG
enum: DBL_DIG
enum: LDBL_DIG
const float FLT_DIG
const double DBL_DIG
const long double LDBL_DIG
enum: FLT_MIN_EXP
enum: DBL_MIN_EXP
enum: LDBL_MIN_EXP
const float FLT_MIN_EXP
const double DBL_MIN_EXP
const long double LDBL_MIN_EXP
enum: FLT_MIN_10_EXP
enum: DBL_MIN_10_EXP
enum: LDBL_MIN_10_EXP
const float FLT_MIN_10_EXP
const double DBL_MIN_10_EXP
const long double LDBL_MIN_10_EXP
enum: FLT_MAX_EXP
enum: DBL_MAX_EXP
enum: LDBL_MAX_EXP
const float FLT_MAX_EXP
const double DBL_MAX_EXP
const long double LDBL_MAX_EXP
enum: FLT_MAX_10_EXP
enum: DBL_MAX_10_EXP
enum: LDBL_MAX_10_EXP
const float FLT_MAX_10_EXP
const double DBL_MAX_10_EXP
const long double LDBL_MAX_10_EXP
enum: FLT_MAX
enum: DBL_MAX
enum: LDBL_MAX
const float FLT_MAX
const double DBL_MAX
const long double LDBL_MAX
enum: FLT_EPSILON
enum: DBL_EPSILON
enum: LDBL_EPSILON
const float FLT_EPSILON
const double DBL_EPSILON
const long double LDBL_EPSILON
enum: FLT_MIN
enum: DBL_MIN
enum: LDBL_MIN
const float FLT_MIN
const double DBL_MIN
const long double LDBL_MIN
......@@ -3,3 +3,8 @@ cdef extern from "setjmp.h" nogil:
pass
int setjmp(jmp_buf state)
void longjmp(jmp_buf state, int value)
ctypedef struct sigjmp_buf:
pass
int sigsetjmp(sigjmp_buf state, int savesigs)
void siglongjmp(sigjmp_buf state, int value)
# POSIX dynamic linking/loading interface.
# http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dlfcn.h.html
cdef extern from "dlfcn.h" nogil:
void *dlopen(const char *, int)
char *dlerror()
void *dlsym(void *, const char *)
int dlclose(void *)
enum:
RTLD_LAZY
RTLD_NOW
RTLD_GLOBAL
RTLD_LOCAL
from .types cimport sigset_t
from .time cimport timeval, timespec
cdef extern from "sys/select.h" nogil:
ctypedef struct fd_set:
pass
int FD_SETSIZE
void FD_SET(int, fd_set*)
void FD_CLR(int, fd_set*)
bint FD_ISSET(int, fd_set*)
void FD_ZERO(fd_set*)
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const timeval *timeout)
int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const timespec *timeout,
const sigset_t *sigmask)
......@@ -12,7 +12,7 @@ cdef extern from "signal.h" nogil:
int sigev_notify
int sigev_signo
sigval sigev_value
void *sigev_notify_function(sigval)
void sigev_notify_function(sigval)
ctypedef struct siginfo_t:
int si_signo
......@@ -26,10 +26,10 @@ cdef extern from "signal.h" nogil:
sigval si_value
cdef struct sigaction_t "sigaction":
void *sa_handler(int)
void sa_handler(int)
void sa_sigaction(int, siginfo_t *, void *)
sigset_t sa_mask
int sa_flags
void sa_sigaction(int, siginfo_t *, void *)
enum: SA_NOCLDSTOP
enum: SIG_BLOCK
......
# POSIX additions to <stdio.h>.
# http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html
from libc.stdio cimport FILE
from libc.stddef cimport wchar_t
from posix.types cimport off_t
cdef extern from "stdio.h" nogil:
# File descriptors
FILE *fdopen(int, const char *)
int fileno(FILE *)
# Pipes
FILE *popen(const char *, const char *)
int pclose(FILE *)
# Memory streams (POSIX.2008)
FILE *fmemopen(void *, size_t, const char *)
FILE *open_memstream(char **, size_t *)
FILE *open_wmemstream(wchar_t **, size_t *)
# Seek and tell with off_t
int fseeko(FILE *, off_t, int)
off_t ftello(FILE *)
# Locking (for multithreading)
void flockfile(FILE *)
int ftrylockfile(FILE *)
void funlockfile(FILE *)
int getc_unlocked(FILE *)
int getchar_unlocked()
int putc_unlocked(int, FILE *)
int putchar_unlocked(int)
# Reading lines and records (POSIX.2008)
ssize_t getline(char **, size_t *, FILE *)
ssize_t getdelim(char **, size_t *, int, FILE *)
# cython.* namespace for pure mode.
from __future__ import absolute_import
__version__ = "0.23.1"
__version__ = "0.24.0a0"
try:
from __builtin__ import basestring
......
......@@ -79,7 +79,7 @@ cdef extern from *:
size_t sizeof_dtype, int contig_flag,
bint dtype_is_object) nogil except *
bint slice_is_contig "__pyx_memviewslice_is_contig" (
{{memviewslice_name}} *mvs, char order, int ndim) nogil
{{memviewslice_name}} mvs, char order, int ndim) nogil
bint slices_overlap "__pyx_slices_overlap" ({{memviewslice_name}} *slice1,
{{memviewslice_name}} *slice2,
int ndim, size_t itemsize) nogil
......@@ -578,13 +578,13 @@ cdef class memoryview(object):
cdef {{memviewslice_name}} *mslice
cdef {{memviewslice_name}} tmp
mslice = get_slice_from_memview(self, &tmp)
return slice_is_contig(mslice, 'C', self.view.ndim)
return slice_is_contig(mslice[0], 'C', self.view.ndim)
def is_f_contig(self):
cdef {{memviewslice_name}} *mslice
cdef {{memviewslice_name}} tmp
mslice = get_slice_from_memview(self, &tmp)
return slice_is_contig(mslice, 'F', self.view.ndim)
return slice_is_contig(mslice[0], 'F', self.view.ndim)
def copy(self):
cdef {{memviewslice_name}} mslice
......@@ -1195,7 +1195,7 @@ cdef void *copy_data_to_temp({{memviewslice_name}} *src,
if tmpslice.shape[i] == 1:
tmpslice.strides[i] = 0
if slice_is_contig(src, order, ndim):
if slice_is_contig(src[0], order, ndim):
memcpy(result, src.data, size)
else:
copy_strided_to_strided(src, tmpslice, ndim, itemsize)
......@@ -1258,7 +1258,7 @@ cdef int memoryview_copy_contents({{memviewslice_name}} src,
if slices_overlap(&src, &dst, ndim, itemsize):
# slices overlap, copy to temp, copy temp to dst
if not slice_is_contig(&src, order, ndim):
if not slice_is_contig(src, order, ndim):
order = get_best_order(&dst, ndim)
tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
......@@ -1267,10 +1267,10 @@ cdef int memoryview_copy_contents({{memviewslice_name}} src,
if not broadcasting:
# See if both slices have equal contiguity, in that case perform a
# direct copy. This only works when we are not broadcasting.
if slice_is_contig(&src, 'C', ndim):
direct_copy = slice_is_contig(&dst, 'C', ndim)
elif slice_is_contig(&src, 'F', ndim):
direct_copy = slice_is_contig(&dst, 'F', ndim)
if slice_is_contig(src, 'C', ndim):
direct_copy = slice_is_contig(dst, 'C', ndim)
elif slice_is_contig(src, 'F', ndim):
direct_copy = slice_is_contig(dst, 'F', ndim)
if direct_copy:
# Contiguous slices with same order
......
......@@ -692,29 +692,29 @@ __pyx_slices_overlap({{memviewslice_name}} *slice1,
////////// MemviewSliceIsCContig.proto //////////
#define __pyx_memviewslice_is_c_contig{{ndim}}(slice) \
__pyx_memviewslice_is_contig(&slice, 'C', {{ndim}})
__pyx_memviewslice_is_contig(slice, 'C', {{ndim}})
////////// MemviewSliceIsFContig.proto //////////
#define __pyx_memviewslice_is_f_contig{{ndim}}(slice) \
__pyx_memviewslice_is_contig(&slice, 'F', {{ndim}})
__pyx_memviewslice_is_contig(slice, 'F', {{ndim}})
////////// MemviewSliceIsContig.proto //////////
static int __pyx_memviewslice_is_contig(const {{memviewslice_name}} *mvs,
static int __pyx_memviewslice_is_contig(const {{memviewslice_name}} mvs,
char order, int ndim);
////////// MemviewSliceIsContig //////////
static int
__pyx_memviewslice_is_contig(const {{memviewslice_name}} *mvs,
__pyx_memviewslice_is_contig(const {{memviewslice_name}} mvs,
char order, int ndim)
{
int i, index, step, start;
Py_ssize_t itemsize = mvs->memview->view.itemsize;
Py_ssize_t itemsize = mvs.memview->view.itemsize;
if (order == 'F') {
step = 1;
......@@ -726,10 +726,10 @@ __pyx_memviewslice_is_contig(const {{memviewslice_name}} *mvs,
for (i = 0; i < ndim; i++) {
index = start + step * i;
if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
if (mvs.suboffsets[index] >= 0 || mvs.strides[index] != itemsize)
return 0;
itemsize *= mvs->shape[index];
itemsize *= mvs.shape[index];
}
return 1;
......
......@@ -45,6 +45,10 @@
#endif
#if CYTHON_USE_PYLONG_INTERNALS
#include "longintrepr.h"
/* These short defines can easily conflict with other code */
#undef SHIFT
#undef BASE
#undef MASK
#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
......
......@@ -659,7 +659,7 @@ static PyObject* __Pyx_PyInt_{{op}}{{order}}(PyObject *op1, PyObject *op2, CYTHO
x = a % b;
x += ((x != 0) & ((x ^ b) < 0)) * b;
{{elif op == 'TrueDivide'}}
if (8 * sizeof(long) <= 53 || (abs(size) <= 52 / PyLong_SHIFT) || likely(labs({{ival}}) <= (1L << 53))) {
if (8 * sizeof(long) <= 53 || (__Pyx_sst_abs(size) <= 52 / PyLong_SHIFT) || likely(labs({{ival}}) <= (1L << 53))) {
return PyFloat_FromDouble((double)a / (double)b);
}
return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
......
......@@ -395,14 +395,19 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
//@requires: IncludeStringH
/* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */
static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
const char* cstring, Py_ssize_t start, Py_ssize_t stop,
const char* encoding, const char* errors,
PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
Py_ssize_t length;
if (unlikely((start < 0) | (stop < 0))) {
length = strlen(cstring);
size_t slen = strlen(cstring);
if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) {
PyErr_SetString(PyExc_OverflowError,
"c-string too long to convert to Python");
return NULL;
}
length = (Py_ssize_t) slen;
if (start < 0) {
start += length;
if (start < 0)
......
......@@ -6,8 +6,8 @@ def pylong_join(count, digits_ptr='digits', join_type='unsigned long'):
(((d[2] << n) | d[1]) << n) | d[0]
"""
return ('(' * (count * 2) + "(%s)" % join_type + ' | '.join(
"%s[%d])%s)" % (digits_ptr, _i, " << PyLong_SHIFT" if _i else '')
return ('(' * (count * 2) + ' | '.join(
"(%s)%s[%d])%s)" % (join_type, digits_ptr, _i, " << PyLong_SHIFT" if _i else '')
for _i in range(count-1, -1, -1)))
......
......@@ -21,7 +21,7 @@ include Demos/Makefile*
recursive-include Cython/Debugger/Tests *.pyx *.pxd *.c *.h
recursive-include Cython/Utility *.pyx *.pxd *.c *.h *.cpp
recursive-include Tools *
recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt
recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.hpp *.BROKEN bugs.txt
recursive-include tests *_lib.cpp *.srctree
recursive-include docs *
include runtests.py
......
......@@ -102,7 +102,7 @@ Properties
* The ``__get__()``, ``__set__()``, and ``__del__()`` methods are all optional.
* If they are ommitted, An exception is raised when an access attempt is made.
* If they are omitted, an exception is raised on attribute access.
* Below, is a full example that defines a property which can..
......@@ -364,7 +364,7 @@ Extension Types and None
* When accessing an extension type's C-attributes, **make sure** it is not ``None``.
* Cython does not check this for reasons of efficency.
* Cython does not check this for reasons of efficiency.
* Be very aware of exposing Python functions that take extension types as arguments::
......@@ -418,7 +418,7 @@ External and Public Types
Public
======
* When an extention type is declared ``public``, Cython will generate a C-header (".h") file.
* When an extension type is declared ``public``, Cython will generate a C-header (".h") file.
* The header file will contain the declarations for it's **object-struct** and it's **type-object**.
* External C-code can now access the attributes of the extension type.
......@@ -459,7 +459,7 @@ External
#. When declaring an external extension type...
* Don't declare any methods, because they are Python method class the are not needed.
* Similiar to **structs** and **unions**, extension classes declared inside a ``cdef extern from`` block only need to declare the C members which you will actually need to access in your module.
* Similar to **structs** and **unions**, extension classes declared inside a ``cdef extern from`` block only need to declare the C members which you will actually need to access in your module.
Name Specification Clause
......
......@@ -299,7 +299,7 @@ Optional Arguments
Keyword-only Arguments
=======================
* As in Python 3, ``def`` functions can have keyword-only argurments listed after a ``"*"`` parameter and before a ``"**"`` parameter if any::
* As in Python 3, ``def`` functions can have keyword-only arguments listed after a ``"*"`` parameter and before a ``"**"`` parameter if any::
def f(a, b, *args, c, d = 42, e, **kwds):
...
......
......@@ -3,7 +3,7 @@ Working with NumPy
=======================
You can use NumPy from Cython exactly the same as in regular Python, but by
doing so you are loosing potentially high speedups because Cython has support
doing so you are losing potentially high speedups because Cython has support
for fast access to NumPy arrays. Let's see how this works with a simple
example.
......
......@@ -531,15 +531,18 @@ declare that it is safe to call without the GIL.::
cdef void my_gil_free_func(int spam) nogil:
...
If you are implementing such a function in Cython, it cannot have any Python
arguments, Python local variables, or Python return type, and cannot
manipulate Python objects in any way or call any function that does so without
acquiring the GIL first. Some of these restrictions are currently checked by
Cython, but not all. It is possible that more stringent checking will be
performed in the future.
.. NOTE:: This declaration declares that it is safe to call the function without the GIL,
it does not in itself release the GIL.
When you implement such a function in Cython, it cannot have any Python
arguments or Python object return type. Furthermore, any operation
that involves Python objects (including calling Python functions) must
explicitly acquire the GIL first, e.g. by using a ``with gil`` block
or by calling a function that has been defined ``with gil``. These
restrictions are checked by Cython and you will get a compile error
if it finds any Python interaction inside of a ``nogil`` code section.
.. NOTE:: The ``nogil`` function annotation declares that it is safe
to call the function without the GIL. It is perfectly allowed
to execute it while holding the GIL. The function does not in
itself release the GIL if it is held by the caller.
Declaring a function ``with gil`` (i.e. as acquiring the GIL on entry) also
implicitly makes its signature :keyword:`nogil`.
......@@ -569,7 +569,7 @@ Compile-Time Definitions
A compile-time constant can be defined using the DEF statement::
DEF FavouriteFood = "spam"
DEF FavouriteFood = u"spam"
DEF ArraySize = 42
DEF OtherArraySize = 2 * ArraySize + 17
......@@ -586,16 +586,21 @@ returned by :func:`os.uname`.
The following selection of builtin constants and functions are also available:
None, True, False,
abs, bool, chr, cmp, complex, dict, divmod, enumerate,
float, hash, hex, int, len, list, long, map, max, min,
oct, ord, pow, range, reduce, repr, round, slice, str,
sum, tuple, xrange, zip
abs, all, any, ascii, bin, bool, bytearray, bytes, chr, cmp, complex, dict,
divmod, enumerate, filter, float, format, frozenset, hash, hex, int, len,
list, long, map, max, min, oct, ord, pow, range, reduce, repr, reversed,
round, set, slice, sorted, str, sum, tuple, xrange, zip
Note that some of these builtins may not be available when compiling under
Python 2.x or 3.x, or may behave differently in both.
A name defined using ``DEF`` can be used anywhere an identifier can appear,
and it is replaced with its compile-time value as though it were written into
the source at that point as a literal. For this to work, the compile-time
expression must evaluate to a Python value of type ``int``, ``long``,
``float`` or ``str``.::
``float``, ``bytes`` or ``unicode`` (``str`` in Py3).
::
cdef int a1[ArraySize]
cdef int a2[OtherArraySize]
......
......@@ -310,7 +310,7 @@ Synonyms
Source code encoding
======================
.. TODO: add the links to the relevent PEPs
.. TODO: add the links to the relevant PEPs
Cython supports PEP 3120 and PEP 263, i.e. you can start your Cython source
file with an encoding comment and generally write your source code in UTF-8.
......
......@@ -26,7 +26,7 @@ platform for generating an extension module. For these options look at the
official Python documentation.
The other, and probably better, way is to use the :mod:`distutils` extension
provided with Cython. The benifit of this method is that it will give the
provided with Cython. The benefit of this method is that it will give the
platform specific compilation options, acting like a stripped down autotools.
......
......@@ -23,6 +23,10 @@ cimport posix.stat
from posix cimport stat
from posix.stat cimport *
cimport posix.stdio
from posix cimport stdio
from posix.stdio cimport *
cimport posix.stdlib
from posix cimport stdlib
from posix.stdlib cimport *
......@@ -42,3 +46,7 @@ from posix.wait cimport *
cimport posix.mman
from posix cimport mman
from posix.mman cimport *
cimport posix.dlfcn
from posix cimport dlfcn
from posix.dlfcn cimport *
......@@ -1022,3 +1022,14 @@ def test_cpython_offbyone_issue_23349():
cdef unsigned char[:] v = bytearray(b"testing")
# the following returns 'estingt' without the workaround
return bytearray(v).decode('ascii')
cdef int min_max_tree_restructuring():
"""
>>> min_max_tree_restructuring()
"""
cdef char a[5]
a = [1, 2, 3, 4, 5]
cdef char[:] aview = a
return max(<char>1, aview[0])
......@@ -14,6 +14,7 @@ from cython.view cimport array
import numpy as np
cimport numpy as np
@testcase
def test_shape_stride_suboffset():
u'''
......@@ -47,6 +48,7 @@ def test_shape_stride_suboffset():
print c_contig.strides[0], c_contig.strides[1], c_contig.strides[2]
print c_contig.suboffsets[0], c_contig.suboffsets[1], c_contig.suboffsets[2]
@testcase
def test_copy_to():
u'''
......@@ -57,15 +59,19 @@ def test_copy_to():
'''
cdef int[:, :, :] from_mvs, to_mvs
from_mvs = np.arange(8, dtype=np.int32).reshape(2,2,2)
cdef int *from_data = <int *> from_mvs._data
print ' '.join(str(from_data[i]) for i in range(2*2*2))
to_mvs = array((2,2,2), sizeof(int), 'i')
to_mvs[...] = from_mvs
# TODO Mark: remove this _data attribute
cdef int *to_data = <int*>to_mvs._data
print ' '.join(str(from_data[i]) for i in range(2*2*2))
print ' '.join(str(to_data[i]) for i in range(2*2*2))
@testcase
def test_overlapping_copy():
"""
......@@ -81,6 +87,22 @@ def test_overlapping_copy():
for i in range(10):
assert slice[i] == 10 - 1 - i
@testcase
def test_copy_return_type():
"""
>>> test_copy_return_type()
60.0
60.0
"""
cdef double[:, :, :] a = np.arange(5 * 5 * 5, dtype=np.float64).reshape(5, 5, 5)
cdef double[:, ::1] c_contig = a[..., 0].copy()
cdef double[::1, :] f_contig = a[..., 0].copy_fortran()
print(c_contig[2, 2])
print(f_contig[2, 2])
@testcase
def test_partly_overlapping():
"""
......@@ -170,30 +192,34 @@ def test_copy_mismatch():
mv1[...] = mv2
@testcase
def test_is_contiguous():
u'''
u"""
>>> test_is_contiguous()
True True
False True
True False
True False
<BLANKLINE>
False True
True False
'''
one sized is_c/f_contig True True
is_c/f_contig False True
f_contig.copy().is_c/f_contig True False
f_contig.copy_fortran().is_c/f_contig False True
one sized strided contig True True
strided False
"""
cdef int[::1, :, :] fort_contig = array((1,1,1), sizeof(int), 'i', mode='fortran')
print fort_contig.is_c_contig() , fort_contig.is_f_contig()
fort_contig = array((200,100,100), sizeof(int), 'i', mode='fortran')
print fort_contig.is_c_contig(), fort_contig.is_f_contig()
fort_contig = fort_contig.copy()
print fort_contig.is_c_contig(), fort_contig.is_f_contig()
cdef int[:,:,:] strided = fort_contig
print strided.is_c_contig(), strided.is_f_contig()
print
fort_contig = fort_contig.copy_fortran()
print fort_contig.is_c_contig(), fort_contig.is_f_contig()
print strided.is_c_contig(), strided.is_f_contig()
print 'one sized is_c/f_contig', fort_contig.is_c_contig(), fort_contig.is_f_contig()
fort_contig = array((2,2,2), sizeof(int), 'i', mode='fortran')
print 'is_c/f_contig', fort_contig.is_c_contig(), fort_contig.is_f_contig()
print 'f_contig.copy().is_c/f_contig', fort_contig.copy().is_c_contig(), \
fort_contig.copy().is_f_contig()
print 'f_contig.copy_fortran().is_c/f_contig', \
fort_contig.copy_fortran().is_c_contig(), \
fort_contig.copy_fortran().is_f_contig()
print 'one sized strided contig', strided.is_c_contig(), strided.is_f_contig()
print 'strided', strided[::2].is_c_contig()
@testcase
......@@ -272,6 +298,7 @@ def two_dee():
print (<long*>mv3._data)[0] , (<long*>mv3._data)[1] , (<long*>mv3._data)[2] , (<long*>mv3._data)[3]
@testcase
def fort_two_dee():
u'''
......@@ -283,7 +310,8 @@ def fort_two_dee():
1 2 3 -4
'''
cdef array arr = array((2,2), sizeof(long), 'l', mode='fortran')
cdef long[::1,:] mv1, mv2, mv3
cdef long[::1,:] mv1, mv2, mv4
cdef long[:, ::1] mv3
cdef long *arr_data
arr_data = <long*>arr.data
......@@ -311,6 +339,6 @@ def fort_two_dee():
print (<long*>mv3._data)[0], (<long*>mv3._data)[1], (<long*>mv3._data)[2], (<long*>mv3._data)[3]
mv3 = mv3.copy_fortran()
mv4 = mv3.copy_fortran()
print (<long*>mv3._data)[0], (<long*>mv3._data)[1], (<long*>mv3._data)[2], (<long*>mv3._data)[3]
print (<long*>mv4._data)[0], (<long*>mv4._data)[1], (<long*>mv4._data)[2], (<long*>mv4._data)[3]
# mode: compile
# tag: memoryview
cdef double[::1] contig
# see if we can assign a strided value to a contiguous one
contig[:] = contig[::2]
......@@ -163,6 +163,7 @@ def test_ellipsis_memoryview(array):
ae(e.shape[0], e_obj.shape[0])
ae(e.strides[0], e_obj.strides[0])
@testcase
def test_transpose():
"""
......@@ -193,6 +194,20 @@ def test_transpose():
print a[3, 2], a.T[2, 3], a_obj[3, 2], a_obj.T[2, 3], numpy_obj[3, 2], numpy_obj.T[2, 3]
@testcase
def test_transpose_type(a):
"""
>>> a = np.zeros((5, 10), dtype=np.float64)
>>> a[4, 6] = 9
>>> test_transpose_type(a)
9.0
"""
cdef double[:, ::1] m = a
cdef double[::1, :] m_transpose = a.T
print m_transpose[6, 4]
@testcase_numpy_1_5
def test_numpy_like_attributes(cyarray):
"""
......
# mode: run
# tag: cpp, werror
from cython.operator import (preincrement, predecrement,
postincrement, postdecrement)
from libcpp cimport bool
cdef extern from "cpp_operator_exc_handling_helper.hpp" nogil:
cppclass wrapped_int:
long long val
wrapped_int()
wrapped_int(long long val)
wrapped_int(long long v1, long long v2) except +
wrapped_int operator+(wrapped_int &other) except +ValueError
wrapped_int operator+() except +RuntimeError
wrapped_int operator-(wrapped_int &other) except +
wrapped_int operator-() except +
wrapped_int operator*(wrapped_int &other) except +OverflowError
wrapped_int operator/(wrapped_int &other) except +
wrapped_int operator%(wrapped_int &other) except +
long long operator^(wrapped_int &other) except +
long long operator&(wrapped_int &other) except +
long long operator|(wrapped_int &other) except +
wrapped_int operator~() except +
long long operator&() except +
long long operator==(wrapped_int &other) except +
long long operator!=(wrapped_int &other) except +
long long operator<(wrapped_int &other) except +
long long operator<=(wrapped_int &other) except +
long long operator>(wrapped_int &other) except +
long long operator>=(wrapped_int &other) except +
wrapped_int operator<<(long long shift) except +
wrapped_int operator>>(long long shift) except +
wrapped_int &operator++() except +
wrapped_int &operator--() except +
wrapped_int operator++(int) except +
wrapped_int operator--(int) except +
wrapped_int operator!() except +
bool operator bool() except +
wrapped_int &operator[](long long &index) except +IndexError
long long &operator()() except +AttributeError
wrapped_int &operator=(const wrapped_int &other) except +ArithmeticError
wrapped_int &operator=(const long long &vao) except +
def assert_raised(f, *args, **kwargs):
err = kwargs.get('err', None)
if err is None:
try:
f(*args)
raised = False
except:
raised = True
else:
try:
f(*args)
raised = False
except err:
raised = True
assert raised
def initialization(long long a, long long b):
cdef wrapped_int w = wrapped_int(a, b)
return w.val
def addition(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa + wb).val
def subtraction(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa - wb).val
def multiplication(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa * wb).val
def division(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa / wb).val
def mod(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return (wa % wb).val
def minus(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (-wa).val
def plus(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (+wa).val
def xor(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa ^ wb
def bitwise_and(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa & wb
def bitwise_or(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa | wb
def bitwise_not(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (~a).val
def address(long long a):
cdef wrapped_int wa = wrapped_int(a)
return &wa
def iseq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa == wb
def neq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa != wb
def less(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa < wb
def leq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa <= wb
def greater(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa > wb
def geq(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
return wa < wb
def left_shift(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return (wa << b).val
def right_shift(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return (wa >> b).val
def cpp_preincrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return preincrement(wa).val
def cpp_predecrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return predecrement(wa).val
def cpp_postincrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return postincrement(wa).val
def cpp_postdecrement(long long a):
cdef wrapped_int wa = wrapped_int(a)
return postdecrement(wa).val
def negate(long long a):
cdef wrapped_int wa = wrapped_int(a)
return (not wa).val
def bool_cast(long long a):
cdef wrapped_int wa = wrapped_int(a)
if wa:
return True
else:
return False
def index(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
return wa[b].val
def assign_index(long long a, long long b, long long c):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
wb[c] = wa
return wb.val
def call(long long a):
cdef wrapped_int wa = wrapped_int(a)
return wa()
def assign_same(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
cdef wrapped_int wb = wrapped_int(b)
wa = wb
return wa.val
def assign_different(long long a, long long b):
cdef wrapped_int wa = wrapped_int(a)
wa = b
return wa.val
def cascaded_assign(long long a, long long b, long long c):
cdef wrapped_int wa = wrapped_int(a)
a = b = c
return a.val
def separate_exceptions(long long a, long long b, long long c, long long d, long long e):
cdef:
wrapped_int wa = wrapped_int(a)
wrapped_int wc = wrapped_int(c)
wrapped_int wd = wrapped_int(d)
wrapped_int we = wrapped_int(e)
wa[b] = (+wc) * wd + we
return a.val
def call_temp_separation(long long a, long long b, long long c):
cdef:
wrapped_int wa = wrapped_int(a)
wrapped_int wc = wrapped_int(c)
wa[b] = wc()
return wa.val
def test_operator_exception_handling():
"""
>>> test_operator_exception_handling()
"""
assert_raised(initialization, 1, 4)
assert_raised(addition, 1, 4)
assert_raised(subtraction, 1, 4)
assert_raised(multiplication, 1, 4)
assert_raised(division, 1, 4)
assert_raised(mod, 1, 4)
assert_raised(minus, 4)
assert_raised(plus, 4)
assert_raised(xor, 1, 4)
assert_raised(address, 4)
assert_raised(iseq, 1, 4)
assert_raised(neq, 1, 4)
assert_raised(left_shift, 1, 4)
assert_raised(right_shift, 1, 4)
assert_raised(cpp_preincrement, 4)
assert_raised(cpp_predecrement, 4)
assert_raised(cpp_postincrement, 4)
assert_raised(cpp_postdecrement, 4)
assert_raised(negate, 4)
assert_raised(bool_cast, 4)
assert_raised(index, 1, 4)
assert_raised(assign_index, 1, 4, 4)
assert_raised(call, 4)
assert_raised(assign_same, 4, 4)
assert_raised(assign_different, 4, 4)
assert_raised(cascaded_assign, 4, 4, 1)
assert_raised(cascaded_assign, 4, 1, 4)
assert_raised(separate_exceptions, 1, 1, 1, 1, 4, err=ValueError)
assert_raised(separate_exceptions, 1, 1, 1, 4, 1, err=OverflowError)
assert_raised(separate_exceptions, 1, 1, 4, 1, 1, err=RuntimeError)
assert_raised(separate_exceptions, 1, 4, 1, 1, 1, err=IndexError)
assert_raised(separate_exceptions, 4, 1, 1, 1, 3, err=ArithmeticError)
assert_raised(call_temp_separation, 2, 1, 4, err=AttributeError)
assert_raised(call_temp_separation, 2, 4, 1, err=IndexError)
#pragma once
#include <stdexcept>
class wrapped_int {
public:
long long val;
wrapped_int() { val = 0; }
wrapped_int(long long val) { this->val = val; }
wrapped_int(long long v1, long long v2) {
if (v2 == 4) {
throw std::domain_error("4 isn't good for initialization!");
}
this->val = v1;
}
wrapped_int operator+(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("tried to add 4");
}
return wrapped_int(this->val + other.val);
}
wrapped_int operator+() {
if (this->val == 4) {
throw std::domain_error("'4' not in valid domain.");
}
return *this;
}
wrapped_int operator-(wrapped_int &other) {
if (other.val == 4) {
throw std::overflow_error("Value '4' is no good.");
}
return *this;
}
wrapped_int operator-() {
if (this->val == 4) {
throw std::range_error("Can't take the negative of 4.");
}
return wrapped_int(-this->val);
}
wrapped_int operator*(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val * other.val);
}
wrapped_int operator/(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val / other.val);
}
wrapped_int operator%(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return wrapped_int(this->val % other.val);
}
long long operator^(wrapped_int &other) {
if (other.val == 4) {
throw std::out_of_range("Multiplying by 4 isn't going to work.");
}
return this->val ^ other.val;
}
long long operator&(wrapped_int &other) {
if (other.val == 4) {
throw std::underflow_error("Can't do this with 4!");
}
return this->val & other.val;
}
long long operator|(wrapped_int &other) {
if (other.val == 4) {
throw std::underflow_error("Can't do this with 4!");
}
return this->val & other.val;
}
wrapped_int operator~() {
if (this->val == 4) {
throw std::range_error("4 is really just no good for this!");
}
return *this;
}
long long operator&() {
if (this->val == 4) {
throw std::out_of_range("4 cannot be located!");
}
return this->val;
}
long long operator==(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("4 isn't logical and can't be equal to anything!");
}
return this->val == other.val;
}
long long operator!=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("4 isn't logical and can'd be not equal to anything either!");
}
return this->val != other.val;
}
long long operator<(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val < other.val;
}
long long operator<=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val <= other.val;
}
long long operator>(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val > other.val;
}
long long operator>=(wrapped_int &other) {
if (other.val == 4) {
throw std::invalid_argument("Can't compare with 4!");
}
return this->val >= other.val;
}
wrapped_int operator<<(long long &shift) {
if (shift == 4) {
throw std::overflow_error("Shifting by 4 is just bad.");
}
return wrapped_int(this->val << shift);
}
wrapped_int operator>>(long long &shift) {
if (shift == 4) {
throw std::underflow_error("Shifting by 4 is just bad.");
}
return wrapped_int(this->val >> shift);
}
wrapped_int &operator++() {
if (this->val == 4) {
throw std::out_of_range("Can't increment 4!");
}
this->val += 1;
return *this;
}
wrapped_int &operator--() {
if (this->val == 4) {
throw std::out_of_range("Can't decrement 4!");
}
this->val -= 1;
return *this;
}
wrapped_int operator++(int) {
if (this->val == 4) {
throw std::out_of_range("Can't increment 4!");
}
wrapped_int t = *this;
this->val += 1;
return t;
}
wrapped_int operator--(int) {
if (this->val == 4) {
throw std::out_of_range("Can't decrement 4!");
}
wrapped_int t = *this;
this->val -= 1;
return t;
}
wrapped_int operator!() {
if (this->val == 4) {
throw std::out_of_range("Can't negate 4!");
}
return wrapped_int(!this->val);
}
operator bool() {
if (this->val == 4) {
throw std::invalid_argument("4 can't be cast to a boolean value!");
}
return (this->val != 0);
}
wrapped_int &operator[](long long &idx) {
if (idx == 4) {
throw std::invalid_argument("Index of 4 not allowed.");
}
return *this;
}
long long &operator()() {
if (this->val == 4) {
throw std::range_error("Can't call 4!");
}
return this->val;
}
wrapped_int &operator=(const wrapped_int &other) {
if ((other.val == 4) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = other.val;
return *this;
}
wrapped_int &operator=(const long long &v) {
if ((v == 4) && (this->val == 4)) {
throw std::overflow_error("Can't assign 4 to 4!");
}
this->val = v;
return *this;
}
};
......@@ -42,6 +42,7 @@ DEF INT_TUPLE1 = TUPLE[:2]
DEF INT_TUPLE2 = TUPLE[1:4:2]
DEF ELLIPSIS = ...
DEF EXPRESSION = int(float(2*2)) + int(str(2)) + int(max(1,2,3)) + sum([TWO, FIVE])
DEF UNICODE_EXPRESSION = unicode(BYTES.decode('utf8')).encode('ascii').decode('latin1')
def c():
......@@ -94,15 +95,21 @@ def l():
def large_nums():
"""
>>> l32, l64 = large_nums()
>>> print_large_number(l32)
>>> ul32, ul64, l64, n64 = large_nums()
>>> print_large_number(ul32)
4294967295
>>> print_large_number(l64)
>>> print_large_number(ul64)
18446744073709551615
>>> print_large_number(l64)
4294967295
>>> print_large_number(n64)
-4294967295
"""
cdef unsigned long l32 = LARGE_NUM32
cdef unsigned long long l64 = LARGE_NUM64
return l32, l64
cdef unsigned long ul32 = LARGE_NUM32
cdef unsigned long long ul64 = LARGE_NUM64
cdef long long l64 = LARGE_NUM32
cdef long long n64 = -LARGE_NUM32
return ul32, ul64, l64, n64
def f():
"""
......@@ -210,6 +217,16 @@ def expression():
cdef int i = EXPRESSION
return i
def unicode_expression():
"""
>>> print(unicode_expression())
spam
"""
s = UNICODE_EXPRESSION
return s
def none():
"""
>>> none()
......
......@@ -150,3 +150,10 @@ def infer_division_type():
v = (10000**2 - 1) / 12
print(cython.typeof(v))
return v
def int_int(int a, int b):
"""
>>> int_int(1, 2)
(0.5, 2.0)
"""
return a/b, b/a
......@@ -527,3 +527,31 @@ def iteritems_of_expression(*args, **kwargs):
[('a', 3), ('b', 4)]
"""
return [item for item in dict(*args, **kwargs).iteritems()]
def for_in_items_of_expression(*args, **kwargs):
"""
>>> sorted(for_in_items_of_expression(a=3, b=4))
[('a', 3), ('b', 4)]
>>> sorted(for_in_items_of_expression([('a', 3)], b=4))
[('a', 3), ('b', 4)]
"""
result = []
for k, v in dict(*args, **kwargs).items():
result.append((k, v))
return result
def for_in_iteritems_of_expression(*args, **kwargs):
"""
>>> sorted(for_in_iteritems_of_expression(a=3, b=4))
[('a', 3), ('b', 4)]
>>> sorted(for_in_iteritems_of_expression([('a', 3)], b=4))
[('a', 3), ('b', 4)]
"""
result = []
for k, v in dict(*args, **kwargs).iteritems():
result.append((k, v))
return result
......@@ -136,3 +136,10 @@ def float_mix_rev(float a):
(0.25, 0.0, 1.25, 1.0, 1.25, 1.0)
"""
return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a
def int_int(int a, int b):
"""
>>> int_int(1, 2)
(0, 2)
"""
return a/b, b/a
cdef class FromPxd:
@staticmethod
cdef static_cdef(int* x)
......@@ -50,3 +50,16 @@ def call_static_cdef(int x):
# ('cpdef', 2)
# """
# return A.static_cpdef(x)
cdef class FromPxd:
@staticmethod
cdef static_cdef(int* x):
return 'pxd_cdef', x[0]
def call_static_pxd_cdef(int x):
"""
>>> call_static_pxd_cdef(2)
('pxd_cdef', 2)
"""
cdef int *x_ptr = &x
return FromPxd.static_cdef(x_ptr)
import unittest
# The test cases here cover several paths through the function calling
# code. They depend on the METH_XXX flag that is used to define a C
# function, which can't be verified from Python. If the METH_XXX decl
# for a C function changes, these tests may not cover the right paths.
class CFunctionCalls(unittest.TestCase):
def test_varargs0(self):
self.assertRaises(TypeError, {}.__contains__)
def test_varargs1(self):
{}.__contains__(0)
def test_varargs2(self):
self.assertRaises(TypeError, {}.__contains__, 0, 1)
def test_varargs0_ext(self):
try:
{}.__contains__(*())
except TypeError:
pass
def test_varargs1_ext(self):
{}.__contains__(*(0,))
def test_varargs2_ext(self):
try:
{}.__contains__(*(1, 2))
except TypeError:
pass
else:
raise RuntimeError
def test_varargs0_kw(self):
self.assertRaises(TypeError, {}.__contains__, x=2)
def test_varargs1_kw(self):
self.assertRaises(TypeError, {}.__contains__, x=2)
def test_varargs2_kw(self):
self.assertRaises(TypeError, {}.__contains__, x=2, y=2)
def test_oldargs0_0(self):
{}.keys()
def test_oldargs0_1(self):
self.assertRaises(TypeError, {}.keys, 0)
def test_oldargs0_2(self):
self.assertRaises(TypeError, {}.keys, 0, 1)
def test_oldargs0_0_ext(self):
{}.keys(*())
def test_oldargs0_1_ext(self):
try:
{}.keys(*(0,))
except TypeError:
pass
else:
raise RuntimeError
def test_oldargs0_2_ext(self):
try:
{}.keys(*(1, 2))
except TypeError:
pass
else:
raise RuntimeError
### Cython makes this a compile time error
# def test_oldargs0_0_kw(self):
# try:
# {}.keys(x=2)
# except TypeError:
# pass
# else:
# raise RuntimeError
def test_oldargs0_1_kw(self):
self.assertRaises(TypeError, {}.keys, x=2)
def test_oldargs0_2_kw(self):
self.assertRaises(TypeError, {}.keys, x=2, y=2)
def test_oldargs1_0(self):
self.assertRaises(TypeError, [].count)
def test_oldargs1_1(self):
[].count(1)
def test_oldargs1_2(self):
self.assertRaises(TypeError, [].count, 1, 2)
def test_oldargs1_0_ext(self):
try:
[].count(*())
except TypeError:
pass
else:
raise RuntimeError
def test_oldargs1_1_ext(self):
[].count(*(1,))
def test_oldargs1_2_ext(self):
try:
[].count(*(1, 2))
except TypeError:
pass
else:
raise RuntimeError
def test_oldargs1_0_kw(self):
self.assertRaises(TypeError, [].count, x=2)
def test_oldargs1_1_kw(self):
self.assertRaises(TypeError, [].count, {}, x=2)
def test_oldargs1_2_kw(self):
self.assertRaises(TypeError, [].count, x=2, y=2)
if __name__ == "__main__":
unittest.main()
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