Commit 6c2a2b3b authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents 4856376e 19209090
......@@ -11,7 +11,8 @@ import Symtab
class AutoTestDictTransform(ScopeTrackingTransform):
# Handles autotestdict directive
blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__']
blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__',
'__len__', '__contains__']
def visit_ModuleNode(self, node):
if node.is_pxd:
......
......@@ -44,8 +44,9 @@ class AnnotationCCodeWriter(CCodeWriter):
if pos is not None:
CCodeWriter.mark_pos(self, pos)
if self.last_pos:
code = self.code.get(self.last_pos[1], "")
self.code[self.last_pos[1]] = code + self.annotation_buffer.getvalue()
pos_code = self.code.setdefault(self.last_pos[0].get_description(),{})
code = pos_code.get(self.last_pos[1], "")
pos_code[self.last_pos[1]] = code + self.annotation_buffer.getvalue()
self.annotation_buffer = StringIO()
self.last_pos = pos
......@@ -63,15 +64,16 @@ class AnnotationCCodeWriter(CCodeWriter):
lines[k] = line
f.close()
all = []
for pos, item in self.annotations:
if pos[0] == source_filename:
start = item.start()
size, end = item.end()
if size:
all.append((pos, start))
all.append(((source_filename, pos[1], pos[2]+size), end))
else:
all.append((pos, start+end))
if False:
for pos, item in self.annotations:
if pos[0].filename == source_filename:
start = item.start()
size, end = item.end()
if size:
all.append((pos, start))
all.append(((source_filename, pos[1], pos[2]+size), end))
else:
all.append((pos, start+end))
all.sort()
all.reverse()
......@@ -136,11 +138,12 @@ function toggleDiv(id) {
error_goto = re.compile(ur'((; *if .*)? \{__pyx_filename = .*goto __pyx_L\w+;\})')
refnanny = re.compile(u'(__Pyx_X?(GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)')
code_source_file = self.code[source_filename]
for line in lines:
k += 1
try:
code = self.code[k]
code = code_source_file[k]
except KeyError:
code = ''
......
......@@ -413,16 +413,19 @@ def init_builtins():
init_builtin_funcs()
init_builtin_types()
init_builtin_structs()
global list_type, tuple_type, dict_type, set_type, type_type
global bytes_type, str_type, unicode_type, float_type
global list_type, tuple_type, dict_type, set_type, frozenset_type
global bytes_type, str_type, unicode_type
global float_type, bool_type, type_type
type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type
set_type = builtin_scope.lookup('set').type
frozenset_type = builtin_scope.lookup('frozenset').type
bytes_type = builtin_scope.lookup('bytes').type
str_type = builtin_scope.lookup('str').type
unicode_type = builtin_scope.lookup('unicode').type
float_type = builtin_scope.lookup('float').type
bool_type = builtin_scope.lookup('bool').type
init_builtins()
......@@ -10,7 +10,7 @@ debug_temp_code_comments = 0
debug_trace_code_generation = 0
# Do not replace exceptions with user-friendly error messages
debug_no_exception_intercept = 0
debug_no_exception_intercept = 1
# Print a message each time a new stage in the pipeline is entered
debug_verbose_pipeline = 0
This diff is collapsed.
......@@ -2,7 +2,7 @@
# Cython Top Level
#
import os, sys, re, codecs
import os, sys, re
if sys.version_info[:2] < (2, 3):
sys.stderr.write("Sorry, Cython requires Python 2.3 or later\n")
sys.exit(1)
......@@ -78,8 +78,8 @@ class Context(object):
self.pxds = {} # full name -> node tree
standard_include_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'Includes'))
standard_include_path = os.path.abspath(os.path.normpath(
os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
self.include_directories = include_directories + [standard_include_path]
def create_pipeline(self, pxd, py=False):
......@@ -358,17 +358,17 @@ class Context(object):
for dir in dirs:
path = os.path.join(dir, dotted_filename)
if os.path.exists(path):
if Utils.path_exists(path):
return path
if not include:
package_dir = self.check_package_dir(dir, package_names)
if package_dir is not None:
path = os.path.join(package_dir, module_filename)
if os.path.exists(path):
if Utils.path_exists(path):
return path
path = os.path.join(dir, package_dir, module_name,
package_filename)
if os.path.exists(path):
if Utils.path_exists(path):
return path
return None
......@@ -381,20 +381,12 @@ class Context(object):
dir = parent
return dir
def is_package_dir(self, dir):
package_init = os.path.join(dir, "__init__.py")
return os.path.exists(package_init) or \
os.path.exists(package_init + "x") # same with .pyx
def check_package_dir(self, dir, package_names):
package_dir = os.path.join(dir, *package_names)
if not os.path.exists(package_dir):
return None
for dirname in package_names:
dir = os.path.join(dir, dirname)
if not self.is_package_dir(dir):
return None
return package_dir
return dir
def c_file_out_of_date(self, source_path):
c_path = Utils.replace_suffix(source_path, ".c")
......@@ -424,9 +416,11 @@ class Context(object):
def is_package_dir(self, dir_path):
# Return true if the given directory is a package directory.
for filename in ("__init__.py", "__init__.pyx"):
for filename in ("__init__.py",
"__init__.pyx",
"__init__.pxd"):
path = os.path.join(dir_path, filename)
if os.path.exists(path):
if Utils.path_exists(path):
return 1
def read_dependency_file(self, source_path):
......
......@@ -411,7 +411,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for module in modules:
defined_here = module is env
modulecode.putln("/* Module declarations from %s */" %
module.qualified_name.encode("ASCII", "ignore"))
module.qualified_name)
self.generate_global_declarations(module, modulecode, defined_here)
self.generate_cfunction_predeclarations(module, modulecode, defined_here)
......@@ -525,11 +525,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#if PY_MAJOR_VERSION >= 3
#define PyBaseString_Type PyUnicode_Type
#define PyStringObject PyUnicodeObject
#define PyString_Type PyUnicode_Type
#define PyString_Check PyUnicode_Check
#define PyString_CheckExact PyUnicode_CheckExact
#else
#endif
#if PY_VERSION_HEX < 0x02060000
#define PyBytesObject PyStringObject
#define PyBytes_Type PyString_Type
#define PyBytes_Check PyString_Check
#define PyBytes_CheckExact PyString_CheckExact
#define PyBytes_FromString PyString_FromString
#define PyBytes_FromStringAndSize PyString_FromStringAndSize
#define PyBytes_FromFormat PyString_FromFormat
#define PyBytes_DecodeEscape PyString_DecodeEscape
#define PyBytes_AsString PyString_AsString
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
#define PyBytes_Size PyString_Size
#define PyBytes_AS_STRING PyString_AS_STRING
#define PyBytes_GET_SIZE PyString_GET_SIZE
#define PyBytes_Repr PyString_Repr
#define PyBytes_Concat PyString_Concat
#define PyBytes_ConcatAndDel PyString_ConcatAndDel
#endif
#if PY_MAJOR_VERSION >= 3
......@@ -634,11 +652,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_includes(self, env, cimported_modules, code):
includes = []
for filename in env.include_files:
# fake decoding of filenames to their original byte sequence
if filename[0] == '<' and filename[-1] == '>':
code.putln('#include %s' % filename)
byte_decoded_filenname = str(filename)
if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
code.putln('#include %s' % byte_decoded_filenname)
else:
code.putln('#include "%s"' % filename)
code.putln('#include "%s"' % byte_decoded_filenname)
def generate_filename_table(self, code):
code.putln("")
......@@ -1537,7 +1555,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_method_table(self, env, code):
code.putln("")
code.putln(
"static struct PyMethodDef %s[] = {" %
"static PyMethodDef %s[] = {" %
env.method_table_cname)
for entry in env.pyfunc_entries:
code.put_pymethoddef(entry, ",")
......@@ -1659,8 +1677,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#endif")
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("%s = __Pyx_PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
code.putln("#ifdef %s_USED" % Naming.binding_cfunc)
code.putln("if (%s_init() < 0) %s" % (Naming.binding_cfunc, code.error_goto(self.pos)))
code.putln("#endif")
......@@ -2177,7 +2195,11 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
PyOS_snprintf(warning, sizeof(warning),
"%s.%s size changed, may indicate binary incompatibility",
module_name, class_name);
#if PY_VERSION_HEX < 0x02050000
PyErr_Warn(NULL, warning);
#else
PyErr_WarnEx(NULL, warning, 0);
#endif
}
else if (((PyTypeObject *)result)->tp_basicsize != size) {
PyErr_Format(PyExc_ValueError,
......
......@@ -630,6 +630,8 @@ class CArgDeclNode(Node):
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# not_none boolean Tagged with 'not None'
# or_none boolean Tagged with 'or None'
# accept_none boolean Resolved boolean for not_none/or_none
# default ExprNode or None
# default_value PyObjectConst constant for default value
# annotation ExprNode or None Py3 function arg annotation
......@@ -1024,10 +1026,8 @@ class CppClassNode(CStructOrUnionDefNode):
def analyse_declarations(self, env):
scope = None
if self.attributes:
if self.attributes is not None:
scope = CppClassScope(self.name, env)
else:
self.attributes = None
base_class_types = []
for base_class_name in self.base_classes:
base_class_entry = env.lookup(base_class_name)
......@@ -1457,6 +1457,33 @@ class FuncDefNode(StatNode, BlockNode):
error(arg.pos,
"Argument type '%s' is incomplete" % arg.type)
return env.declare_arg(arg.name, arg.type, arg.pos)
def generate_arg_type_test(self, arg, code):
# Generate type test for one argument.
if arg.type.typeobj_is_available():
code.globalstate.use_utility_code(arg_type_test_utility_code)
typeptr_cname = arg.type.typeptr_cname
arg_code = "((PyObject *)%s)" % arg.entry.cname
code.putln(
'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
arg_code,
typeptr_cname,
arg.accept_none,
arg.name,
arg.type.is_builtin_type,
code.error_goto(arg.pos)))
else:
error(arg.pos, "Cannot test type of extern C class "
"without type object name specification")
def generate_arg_none_check(self, arg, code):
# Generate None check for one argument.
code.globalstate.use_utility_code(arg_type_test_utility_code)
code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
arg.name,
code.error_goto(arg.pos)))
code.putln('}')
def generate_wrapper_functions(self, code):
pass
......@@ -1709,23 +1736,8 @@ class CFuncDefNode(FuncDefNode):
for arg in self.type.args:
if arg.needs_type_test:
self.generate_arg_type_test(arg, code)
def generate_arg_type_test(self, arg, code):
# Generate type test for one argument.
if arg.type.typeobj_is_available():
typeptr_cname = arg.type.typeptr_cname
arg_code = "((PyObject *)%s)" % arg.cname
code.putln(
'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
arg_code,
typeptr_cname,
not arg.not_none,
arg.name,
type.is_builtin_type,
code.error_goto(arg.pos)))
else:
error(arg.pos, "Cannot test type of extern C class "
"without type object name specification")
elif arg.type.is_pyobject and not arg.accept_none:
self.generate_arg_none_check(arg, code)
def error_value(self):
if self.return_type.is_pyobject:
......@@ -1921,6 +1933,7 @@ class DefNode(FuncDefNode):
def analyse_argument_types(self, env):
directive_locals = self.directive_locals = env.directives['locals']
allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
for arg in self.args:
if hasattr(arg, 'name'):
type = arg.type
......@@ -1949,12 +1962,29 @@ class DefNode(FuncDefNode):
arg.needs_conversion = 0
arg.needs_type_test = 0
arg.is_generic = 1
if arg.not_none and not arg.type.is_extension_type:
error(self.pos,
"Only extension type arguments can have 'not None'")
if arg.type.is_pyobject:
if arg.or_none:
arg.accept_none = True
elif arg.not_none:
arg.accept_none = False
elif arg.type.is_extension_type or arg.type.is_builtin_type:
if arg.default and arg.default.constant_result is None:
# special case: def func(MyType obj = None)
arg.accept_none = True
else:
# default depends on compiler directive
arg.accept_none = allow_none_for_extension_args
else:
# probably just a plain 'object'
arg.accept_none = True
else:
arg.accept_none = True # won't be used, but must be there
if arg.not_none:
error(arg.pos, "Only Python type arguments can have 'not None'")
if arg.or_none:
error(arg.pos, "Only Python type arguments can have 'or None'")
def analyse_signature(self, env):
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):
......@@ -1999,7 +2029,6 @@ class DefNode(FuncDefNode):
if not arg.type.same_as(arg.hdr_type):
if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
arg.needs_type_test = 1
any_type_tests_needed = 1
else:
arg.needs_conversion = 1
if arg.needs_conversion:
......@@ -2017,9 +2046,6 @@ class DefNode(FuncDefNode):
if arg.is_generic and \
(arg.type.is_extension_type or arg.type.is_builtin_type):
arg.needs_type_test = 1
any_type_tests_needed = 1
if any_type_tests_needed:
env.use_utility_code(arg_type_test_utility_code)
def bad_signature(self):
sig = self.entry.signature
......@@ -2175,7 +2201,11 @@ class DefNode(FuncDefNode):
code.putln("%s; /*proto*/" % header)
if proto_only:
return
if self.entry.doc and Options.docstrings:
if (Options.docstrings and self.entry.doc and
(not self.entry.is_special or
self.entry.signature.method_flags()) and
not self.entry.scope.is_property_scope
):
docstr = self.entry.doc
if docstr.is_unicode:
docstr = docstr.utf8encode()
......@@ -2714,10 +2744,13 @@ class DefNode(FuncDefNode):
func = new_type.from_py_function
# copied from CoerceFromPyTypeNode
if func:
code.putln("%s = %s(%s); %s" % (
arg.entry.cname,
func,
arg.hdr_cname,
lhs = arg.entry.cname
rhs = "%s(%s)" % (func, arg.hdr_cname)
if new_type.is_enum:
rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
code.putln("%s = %s; %s" % (
lhs,
rhs,
code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
else:
error(arg.pos,
......@@ -2746,24 +2779,9 @@ class DefNode(FuncDefNode):
for arg in self.args:
if arg.needs_type_test:
self.generate_arg_type_test(arg, code)
def generate_arg_type_test(self, arg, code):
# Generate type test for one argument.
if arg.type.typeobj_is_available():
typeptr_cname = arg.type.typeptr_cname
arg_code = "((PyObject *)%s)" % arg.entry.cname
code.putln(
'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
arg_code,
typeptr_cname,
not arg.not_none,
arg.name,
arg.type.is_builtin_type,
code.error_goto(arg.pos)))
else:
error(arg.pos, "Cannot test type of extern C class "
"without type object name specification")
elif not arg.accept_none and arg.type.is_pyobject:
self.generate_arg_none_check(arg, code)
def error_value(self):
return self.entry.signature.error_value
......
This diff is collapsed.
......@@ -58,6 +58,7 @@ directive_defaults = {
'cdivision': False, # was True before 0.12
'cdivision_warnings': False,
'always_allow_keywords': False,
'allow_none_for_extension_args': True,
'wraparound' : True,
'ccomplex' : False, # use C99/C++ for complex types and arith
'callspec' : "",
......
......@@ -1310,8 +1310,8 @@ class TransformBuiltinMethods(EnvTransform):
node = BoolNode(node.pos, value=True)
elif attribute == u'NULL':
node = NullNode(node.pos)
elif attribute == u'set':
node = NameNode(node.pos, name=EncodedString('set'))
elif attribute in (u'set', u'frozenset'):
node = NameNode(node.pos, name=EncodedString(attribute))
elif not PyrexTypes.parse_basic_type(attribute):
error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute)
return node
......
......@@ -45,7 +45,7 @@ cpdef p_atom(PyrexScanner s)
cpdef p_name(PyrexScanner s, name)
cpdef p_cat_string_literal(PyrexScanner s)
cpdef p_opt_string_literal(PyrexScanner s)
cpdef p_string_literal(PyrexScanner s)
cpdef p_string_literal(PyrexScanner s, kind_override=*)
cpdef p_list_maker(PyrexScanner s)
cpdef p_comp_iter(PyrexScanner s, body)
cpdef p_comp_for(PyrexScanner s, body)
......
......@@ -11,14 +11,6 @@ import os
import re
import sys
try:
from __builtin__ import set
except (ImportError, AttributeError):
try:
from builtins import set
except (ImportError, AttributeError):
from sets import Set as set
from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
import Nodes
import ExprNodes
......@@ -678,7 +670,7 @@ def p_opt_string_literal(s):
else:
return None
def p_string_literal(s):
def p_string_literal(s, kind_override=None):
# A single string or char literal.
# Returns (kind, value) where kind in ('b', 'c', 'u')
# s.sy == 'BEGIN_STRING'
......@@ -695,6 +687,8 @@ def p_string_literal(s):
if Future.unicode_literals in s.context.future_directives:
if kind == '':
kind = 'u'
if kind_override is not None and kind_override in 'ub':
kind = kind_override
if kind == 'u':
chars = StringEncoding.UnicodeLiteralBuilder()
else:
......@@ -1907,7 +1901,9 @@ basic_c_type_names = ("void", "char", "int", "float", "double", "bint")
special_basic_c_types = {
# name : (signed, longness)
"Py_UNICODE" : (0, 0),
"Py_ssize_t" : (2, 0),
"ssize_t" : (2, 0),
"size_t" : (0, 0),
}
......@@ -2000,7 +1996,7 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
exception_value = exc_val, exception_check = exc_check,
nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil)
supported_overloaded_operators = set([
supported_overloaded_operators = cython.set([
'+', '-', '*', '/', '%',
'++', '--', '~', '|', '&', '^', '<<', '>>',
'==', '!=', '>=', '>', '<=', '<',
......@@ -2139,7 +2135,7 @@ def p_optional_ellipsis(s):
def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
kw_only = 0, annotated = 1):
pos = s.position()
not_none = 0
not_none = or_none = 0
default = None
annotation = None
if s.in_python_file:
......@@ -2152,15 +2148,17 @@ def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
else:
base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty)
declarator = p_c_declarator(s, ctx, nonempty = nonempty)
if s.sy == 'not' and not s.in_python_file:
if s.sy in ('not', 'or') and not s.in_python_file:
kind = s.sy
s.next()
if s.sy == 'IDENT' and s.systring == 'None':
s.next()
else:
s.error("Expected 'None'")
if not in_pyfunc:
error(pos, "'not None' only allowed in Python functions")
not_none = 1
error(pos, "'%s None' only allowed in Python functions" % kind)
or_none = kind == 'or'
not_none = kind == 'not'
if annotated and s.sy == ':':
s.next()
annotation = p_simple_expr(s)
......@@ -2177,6 +2175,7 @@ def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
base_type = base_type,
declarator = declarator,
not_none = not_none,
or_none = or_none,
default = default,
annotation = annotation,
kw_only = kw_only)
......@@ -2243,10 +2242,10 @@ def p_cdef_extern_block(s, pos, ctx):
s.next()
else:
_, include_file = p_string_literal(s)
ctx = ctx(cdef_flag = 1, visibility = 'extern')
if s.systring == "namespace":
s.next()
ctx.namespace = p_string_literal(s)[1]
ctx = ctx(cdef_flag = 1, visibility = 'extern')
ctx.namespace = p_string_literal(s, kind_override='u')[1]
if p_nogil(s):
ctx.nogil = 1
body = p_suite(s, ctx)
......@@ -2720,6 +2719,7 @@ def p_cpp_class_definition(s, pos, ctx):
s.expect_newline("Expected a newline")
s.expect_dedent()
else:
attributes = None
s.expect_newline("Syntax error in C++ class definition")
return Nodes.CppClassNode(pos,
name = class_name,
......
This diff is collapsed.
......@@ -2,12 +2,9 @@
# Cython Scanner
#
import sys
import os
import platform
import stat
import sys
import codecs
from time import time
import cython
cython.declare(EncodedString=object, string_prefixes=object, raw_prefixes=object, IDENT=object,
......
......@@ -210,6 +210,8 @@ class Scope(object):
# is_py_class_scope boolean Is a Python class scope
# is_c_class_scope boolean Is an extension type scope
# is_closure_scope boolean
# is_cpp_class_scope boolean Is a C++ class scope
# is_property_scope boolean Is a extension type property scope
# scope_prefix string Disambiguator for C names
# in_cinclude boolean Suppress C declaration code
# qualified_name string "modname" or "modname.classname"
......@@ -225,6 +227,7 @@ class Scope(object):
is_c_class_scope = 0
is_closure_scope = 0
is_cpp_class_scope = 0
is_property_scope = 0
is_module_scope = 0
is_internal = 0
scope_prefix = ""
......@@ -415,7 +418,7 @@ class Scope(object):
error(pos, "C++ classes may only be extern")
if cname is None:
cname = name
entry = self.lookup(name)
entry = self.lookup_here(name)
if not entry:
type = PyrexTypes.CppClassType(
name, scope, cname, base_classes, templates = templates)
......@@ -439,7 +442,8 @@ class Scope(object):
for base_class in base_classes:
declare_inherited_attributes(entry, base_class.base_classes)
entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
declare_inherited_attributes(entry, base_classes)
if entry.type.scope:
declare_inherited_attributes(entry, base_classes)
if self.is_cpp_class_scope:
entry.type.namespace = self.outer_scope.lookup(self.name).type
return entry
......@@ -1664,6 +1668,8 @@ class PropertyScope(Scope):
# a property of an extension type.
#
# parent_type PyExtensionType The type to which the property belongs
is_property_scope = 1
def declare_pyfunction(self, name, pos):
# Add an entry for a method.
......
......@@ -117,6 +117,7 @@ class ResultRefNode(AtomicExprNode):
# must be set externally (usually a temp name).
subexprs = []
lhs_of_first_assignment = False
def __init__(self, expression):
self.pos = expression.pos
......@@ -148,7 +149,8 @@ class ResultRefNode(AtomicExprNode):
def generate_assignment_code(self, rhs, code):
if self.type.is_pyobject:
rhs.make_owned_reference(code)
code.put_decref(self.result(), self.ctype())
if not self.lhs_of_first_assignment:
code.put_decref(self.result(), self.ctype())
code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
rhs.generate_post_assignment_code(code)
rhs.free_temps(code)
......@@ -250,3 +252,26 @@ class LetNode(Nodes.StatNode, LetNodeMixin):
self.setup_temp_expr(code)
self.body.generate_execution_code(code)
self.teardown_temp_expr(code)
class TempResultFromStatNode(ExprNodes.ExprNode):
# An ExprNode wrapper around a StatNode that executes the StatNode
# body. Requires a ResultRefNode that it sets up to refer to its
# own temp result. The StatNode must assign a value to the result
# node, which then becomes the result of this node.
#
# This can only be used in/after type analysis.
#
subexprs = []
child_attrs = ['body']
def __init__(self, result_ref, body):
self.result_ref = result_ref
self.pos = body.pos
self.body = body
self.type = result_ref.type
self.is_temp = 1
def generate_result_code(self, code):
self.result_ref.result_code = self.result()
self.body.generate_execution_code(code)
......@@ -325,7 +325,10 @@ class EnvTransform(CythonTransform):
def __call__(self, root):
self.env_stack = [root.scope]
return super(EnvTransform, self).__call__(root)
def current_env(self):
return self.env_stack[-1]
def visit_FuncDefNode(self, node):
self.env_stack.append(node.local_scope)
self.visitchildren(node)
......
from cpython.unicode cimport Py_UNICODE
cdef extern from "Python.h":
ctypedef long long PY_LONG_LONG
......
cdef extern from *:
ctypedef unsigned int Py_UNICODE
# Return true if the object o is a Unicode object or an instance
# of a Unicode subtype. Changed in version 2.2: Allowed subtypes
# to be accepted.
......@@ -91,6 +89,13 @@ cdef extern from *:
# when u is NULL.
object PyUnicode_FromUnicode(Py_UNICODE *u, Py_ssize_t size)
# Create a Unicode Object from the given Unicode code point ordinal.
#
# The ordinal must be in range(0x10000) on narrow Python builds
# (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError
# is raised in case it is not.
object PyUnicode_FromOrdinal(int ordinal)
# Return a read-only pointer to the Unicode object's internal
# Py_UNICODE buffer, NULL if unicode is not a Unicode object.
Py_UNICODE* PyUnicode_AsUnicode(object o) except NULL
......
......@@ -3,39 +3,44 @@ from pair cimport pair
cdef extern from "<deque>" namespace "std":
cdef cppclass deque[T]:
cppclass iterator:
T operator*()
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
cppclass reverse_iterator:
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
deque()
deque(deque&)
deque(size_t, T& val = T())
#deque(input_iterator, input_iterator)
TYPE& operator[]( size_type index )
const TYPE& operator[]( size_type index ) const
deque(size_t)
deque(size_t, T&)
#deque[input_iterator](input_iterator, input_iterator)
T& operator[](size_t)
#deque& operator=(deque&)
bool operator==(deque&, deque&)
bool operator!=(deque&, deque&)
bool operator<(deque&, deque&)
bool operator>(deque&, deque&)
bool operator<=(deque&, deque&)
bool operator>=(deque&, deque&)
void assign(size_t, TYPE&)
bint operator==(deque&, deque&)
bint operator!=(deque&, deque&)
bint operator<(deque&, deque&)
bint operator>(deque&, deque&)
bint operator<=(deque&, deque&)
bint operator>=(deque&, deque&)
void assign(size_t, T&)
void assign(input_iterator, input_iterator)
T& at(size_t)
T& back()
iterator begin()
const_iterator begin()
#const_iterator begin()
void clear()
bool empty()
bint empty()
iterator end()
const_iterator end()
#const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
......@@ -48,9 +53,10 @@ cdef extern from "<deque>" namespace "std":
void push_back(T&)
void push_front(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
#const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
void resize(size_t, T val = T())
#const_reverse_iterator rend()
void resize(size_t)
void resize(size_t, T&)
size_t size()
void swap(deque&)
cdef extern from "<list>" namespace "std":
cdef cppclass list[T]:
cppclass iterator:
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass reverse_iterator:
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
list()
list(list&)
list(size_t, T&)
#list operator=(list&)
bint operator==(list&, list&)
bint operator!=(list&, list&)
bint operator<(list&, list&)
bint operator>(list&, list&)
bint operator<=(list&, list&)
bint operator>=(list&, list&)
void assign(size_t, T&)
T& back()
iterator begin()
#const_iterator begin()
bint empty()
iterator end()
#const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
iterator insert(iterator, T&)
void insert(iterator, size_t, T&)
size_t max_size()
void merge(list&)
#void merge(list&, BinPred)
void pop_back()
void pop_front()
void push_back(T&)
void push_front(T&)
reverse_iterator rbegin()
#const_reverse_iterator rbegin()
void remove(T&)
#void remove_if(UnPred)
reverse_iterator rend()
#const_reverse_iterator rend()
void resize(size_t, T&)
void reverse()
size_t size()
void sort()
#void sort(BinPred)
void splice(iterator, list&)
void splice(iterator, list&, iterator)
void splice(iterator, list&, iterator, iterator)
void swap(list&)
void unique()
#void unique(BinPred)
from pair cimport pair
cdef extern from "<map>" namespace "std":
cdef cppclass map[T, U]:
cppclass iterator:
pair[T,U]& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass reverse_iterator:
pair[T,U] operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
map()
map(map&)
#map(key_compare&)
U& operator[](T&)
#map& operator=(map&)
bint operator==(map&, map&)
bint operator!=(map&, map&)
bint operator<(map&, map&)
bint operator>(map&, map&)
bint operator<=(map&, map&)
bint operator>=(map&, map&)
U& at(T&)
iterator begin()
#const_iterator begin()
void clear()
size_t count(T&)
bint empty()
iterator end()
#const_iterator end()
pair[iterator, iterator] equal_range(T&)
#pair[const_iterator, const_iterator] equal_range(key_type&)
void erase(iterator)
void erase(iterator, iterator)
size_t erase(T&)
iterator find(T&)
#const_iterator find(key_type&)
pair[iterator, bint] insert(pair[T,U]) # XXX pair[T,U]&
iterator insert(iterator, pair[T,U]) # XXX pair[T,U]&
#void insert(input_iterator, input_iterator)
#key_compare key_comp()
iterator lower_bound(T&)
#const_iterator lower_bound(key_type&)
size_t max_size()
reverse_iterator rbegin()
#const_reverse_iterator rbegin()
reverse_iterator rend()
#const_reverse_iterator rend()
size_t size()
void swap(map&)
iterator upper_bound(T&)
#const_iterator upper_bound(key_type&)
#value_compare value_comp()
cdef extern from "pair.h":
cdef extern from "<utility>" namespace "std":
cdef cppclass pair[T, U]:
T first
U second
pair()
pair(pair&)
pair(T&, U&)
from pair cimport pair
cdef extern from "<queue>" namespace "std":
cdef cppclass queue[T]:
queue()
queue(queue&)
#queue(Container&)
T& back()
bool empty()
bint empty()
T& front()
void pop()
void push(T&)
size_t size()
cdef cppclass priority_queue[T]:
priority_queue()
priority_queue(priority_queue&)
#priority_queue(Container&)
bint empty()
void pop()
void push(T&)
size_t size()
T& top()
......@@ -5,51 +5,56 @@ cdef extern from "<set>" namespace "std":
cppclass iterator:
T operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
cppclass reverse_iterator:
T operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
set()
set(set&)
#set set(key_compare&)
#set(key_compare&)
#set& operator=(set&)
bool operator==(set&, set&)
bool operator!=(set&, set&)
bool operator<(set&, set&)
bool operator>(set&, set&)
bool operator<=(set&, set&)
bool operator>=(set&, set&)
bint operator==(set&, set&)
bint operator!=(set&, set&)
bint operator<(set&, set&)
bint operator>(set&, set&)
bint operator<=(set&, set&)
bint operator>=(set&, set&)
iterator begin()
const_iterator begin()
#const_iterator begin()
void clear()
#size_t count(key_type&)
bool empty()
size_t count(T&)
bint empty()
iterator end()
const_iterator end()
#pair[iterator, iterator] equal_range(key_type&)
#pair[const_iterator, const_iterator] equal_range(key_type&)
#const_iterator end()
pair[iterator, iterator] equal_range(T&)
#pair[const_iterator, const_iterator] equal_range(T&)
void erase(iterator)
void erase(iterator, iterator)
#size_t erase(key_type&)
#iterator find(key_type&)
#const_iterator find(key_type&)
#pair[iterator, bool] insert(T&)
size_t erase(T&)
iterator find(T&)
#const_iterator find(T&)
pair[iterator, bint] insert(T&)
iterator insert(iterator, T&)
#void insert(input_iterator, input_iterator)
#key_compare key_comp()
#iterator lower_bound(key_type&)
#const_iterator lower_bound(key_type&)
iterator lower_bound(T&)
#const_iterator lower_bound(T&)
size_t max_size()
reverse_iterator rbegin()
const_reverse_iterator rbegin()
#const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
#const_reverse_iterator rend()
size_t size()
void swap(set&)
#iterator upper_bound(key_type&)
#const_iterator upper_bound(key_type&)
iterator upper_bound(T&)
#const_iterator upper_bound(T&)
#value_compare value_comp()
from pair cimport pair
cdef extern from "<list>" namespace "std":
cdef cppclass list[T]:
cppclass iterator:
T operator*()
iterator operator++()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
list()
list(list&)
list(size_t, T&)
#list operator=(list&)
bool operator==(list&, list&)
bool operator!=(list&, list&)
bool operator<(list&, list&)
bool operator>(list&, list&)
bool operator<=(list&, list&)
bool operator>=(list&, list&)
void assign(size_t, T&)
T& back()
iterator begin()
const_iterator begin()
bool empty()
iterator end()
const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
iterator insert(iterator, T&)
void insert(iterator, size_t, T&)
size_t max_size()
void merge(list&)
#voide merge(list&, BinPred)
void pop_back()
void pop_front()
void push_back(T&)
void push_front(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
void remove(T&)
#void remove_if(UnPred)
reverse_iterator rend()
const_reverse_iterator rend()
void resize(size_t, T&)
void reverse()
cdef extern from "<stack>" namespace "std":
cdef cppclass stack[T]:
stack()
stack(stack&)
#stack(Container&)
bint empty()
void pop()
void push(T&)
size_t size()
void sort()
#void sort(BinPred)
void splice(iterator, list&)
void splice(iterator, list&, iterator)
void splice(iterator, list&, iterator, iterator)
void swap(list&)
void unique()
#void unique(BinPred)
T& top()
from pair cimport pair
cdef extern from "<vector>" namespace "std":
cdef cppclass vector[T]:
cppclass iterator:
T operator*()
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
cppclass const_iterator(iterator):
pass
cppclass reverse_iterator(iterator):
pass
cppclass const_reverse_iterator(iterator):
pass
#cppclass input_iterator(iterator):
cppclass reverse_iterator:
T& operator*()
iterator operator++()
iterator operator--()
bint operator==(iterator)
bint operator!=(iterator)
#cppclass const_iterator(iterator):
# pass
#cppclass const_reverse_iterator(reverse_iterator):
# pass
vector()
#vector(vector&)
#vector(size_t, T&)
vector(vector&)
vector(size_t)
vector(size_t, T&)
#vector[input_iterator](input_iterator, input_iterator)
T& operator[](size_t)
#vector& operator=(vector&)
bool operator==(vector&, vector&)
bool operator!=(vector&, vector&)
bool operator<(vector&, vector&)
bool operator>(vector&, vector&)
bool operator<=(vector&, vector&)
bool operator>=(vector&, vector&)
bint operator==(vector&, vector&)
bint operator!=(vector&, vector&)
bint operator<(vector&, vector&)
bint operator>(vector&, vector&)
bint operator<=(vector&, vector&)
bint operator>=(vector&, vector&)
void assign(size_t, T&)
#void assign(input_iterator, input_iterator)
#void assign[input_iterator](input_iterator, input_iterator)
T& at(size_t)
T& back()
iterator begin()
const_iterator begin()
#const_iterator begin()
size_t capacity()
void clear()
bool empty()
bint empty()
iterator end()
const_iterator end()
#const_iterator end()
iterator erase(iterator)
iterator erase(iterator, iterator)
T& front()
......@@ -48,10 +50,11 @@ cdef extern from "<vector>" namespace "std":
void pop_back()
void push_back(T&)
reverse_iterator rbegin()
const_reverse_iterator rbegin()
#const_reverse_iterator rbegin()
reverse_iterator rend()
const_reverse_iterator rend()
#const_reverse_iterator rend()
void reserve(size_t)
void resize(size_t, T)
void resize(size_t)
void resize(size_t, T&)
size_t size()
void swap(vector&)
......@@ -481,8 +481,8 @@ cdef extern from "numpy/arrayobject.h":
bint PyArray_FROM_OT(object m, int type)
bint PyArray_FROM_OTF(object m, int type, int flags)
object PyArray_FROMANY(object m, int type, int min, int max, int flags)
bint PyArray_ZEROS(ndarray m, dims, int type, int fortran)
object PyArray_EMPTY(object m, dims, int type, int fortran)
bint PyArray_ZEROS(ndarray m, npy_intp* dims, int type, int fortran)
object PyArray_EMPTY(object m, npy_intp* dims, int type, int fortran)
void PyArray_FILLWBYTE(object, int val)
npy_intp PyArray_REFCOUNT(object)
object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
......
......@@ -153,40 +153,50 @@ class typedef(CythonType):
py_float = float
py_int = int
try:
py_long = long
except NameError: # Py3
py_long = int
py_float = float
py_complex = complex
try:
# Python 3
from builtins import set
from builtins import set, frozenset
except ImportError:
try:
# Python 2.4+
from __builtin__ import set
from __builtin__ import set, frozenset
except ImportError:
# Py 2.3
from sets import Set as set
from sets import Set as set, ImmutableSet as frozenset
# Predefined types
int_types = ['char', 'short', 'int', 'long', 'longlong', 'Py_ssize_t']
float_types = ['double', 'float']
int_types = ['char', 'short', 'Py_UNICODE', 'int', 'long', 'longlong', 'Py_ssize_t', 'size_t']
float_types = ['longdouble', 'double', 'float']
complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex']
other_types = ['bint', 'void']
gs = globals()
for name in int_types:
gs[name] = typedef(py_int)
gs['u'+name] = typedef(py_int)
if name != 'Py_UNICODE' and not name.endswith('size_t'):
gs['u'+name] = typedef(py_int)
gs['s'+name] = typedef(py_int)
double = float = typedef(py_float)
for name in float_types:
gs[name] = typedef(py_float)
for name in complex_types:
gs[name] = typedef(py_complex)
bint = typedef(bool)
void = typedef(int)
for t in int_types + float_types + other_types:
for t in int_types + float_types + complex_types + other_types:
for i in range(1, 4):
gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i)
......
......@@ -45,6 +45,27 @@ def file_newer_than(path, time):
ftime = modification_time(path)
return ftime > time
def path_exists(path):
# try on the filesystem first
if os.path.exists(path):
return True
# figure out if a PEP 302 loader is around
try:
loader = __loader__
# XXX the code below assumes as 'zipimport.zipimporter' instance
# XXX should be easy to generalize, but too lazy right now to write it
if path.startswith(loader.archive):
nrmpath = os.path.normpath(path)
arcname = nrmpath[len(loader.archive)+1:]
try:
loader.get_data(arcname)
return True
except IOError:
return False
except NameError:
pass
return False
# support for source file encoding detection
def encode_filename(filename):
......@@ -109,18 +130,31 @@ class NormalisedNewlineStream(object):
data = self._read(0x1000)
return u''.join(content).split(u'\n')
try:
from io import open as io_open
except ImportError:
io_open = None
io = None
if sys.version_info >= (2,6):
try:
import io
except ImportError:
pass
def open_source_file(source_filename, mode="r",
encoding=None, error_handling=None,
require_normalised_newlines=True):
if encoding is None:
encoding = detect_file_encoding(source_filename)
if io_open is not None:
return io_open(source_filename, mode=mode,
#
try:
loader = __loader__
if source_filename.startswith(loader.archive):
return open_source_from_loader(
loader, source_filename,
encoding, error_handling,
require_normalised_newlines)
except (NameError, AttributeError):
pass
#
if io is not None:
return io.open(source_filename, mode=mode,
encoding=encoding, errors=error_handling)
else:
# codecs module doesn't have universal newline support
......@@ -130,6 +164,28 @@ def open_source_file(source_filename, mode="r",
stream = NormalisedNewlineStream(stream)
return stream
def open_source_from_loader(loader,
source_filename,
encoding=None, error_handling=None,
require_normalised_newlines=True):
nrmpath = os.path.normpath(source_filename)
arcname = nrmpath[len(loader.archive)+1:]
data = loader.get_data(arcname)
if io is not None:
return io.TextIOWrapper(io.BytesIO(data),
encoding=encoding,
errors=error_handling)
else:
try:
import cStringIO as StringIO
except ImportError:
import StringIO
reader = codecs.getreader(encoding)
stream = reader(StringIO.StringIO(data))
if require_normalised_newlines:
stream = NormalisedNewlineStream(stream)
return stream
def str_to_number(value):
# note: this expects a string as input that was accepted by the
# parser already
......
......@@ -178,7 +178,10 @@ class TestBuilder(object):
def build_tests(self, test_class, path, workdir, module, expect_errors):
if expect_errors:
languages = self.languages[:1]
if 'cpp' in module and 'cpp' in self.languages:
languages = ['cpp']
else:
languages = self.languages[:1]
else:
languages = self.languages
if 'cpp' in module and 'c' in languages:
......@@ -752,6 +755,9 @@ if __name__ == '__main__':
parser.add_option("-C", "--coverage", dest="coverage",
action="store_true", default=False,
help="collect source coverage data for the Compiler")
parser.add_option("--coverage-xml", dest="coverage_xml",
action="store_true", default=False,
help="collect source coverage data for the Compiler in XML format")
parser.add_option("-A", "--annotate", dest="annotate_source",
action="store_true", default=True,
help="generate annotated HTML versions of the test source files")
......@@ -799,11 +805,12 @@ if __name__ == '__main__':
WITH_CYTHON = options.with_cython
if options.coverage:
if options.coverage or options.coverage_xml:
if not WITH_CYTHON:
options.coverage = False
options.coverage = options.coverage_xml = False
else:
import coverage
from coverage import coverage as _coverage
coverage = _coverage(branch=True)
coverage.erase()
coverage.start()
......@@ -924,14 +931,17 @@ if __name__ == '__main__':
result = test_runner.run(test_suite)
if options.coverage:
if options.coverage or options.coverage_xml:
coverage.stop()
ignored_modules = ('Options', 'Version', 'DebugFlags', 'CmdLine')
modules = [ module for name, module in sys.modules.items()
if module is not None and
name.startswith('Cython.Compiler.') and
name[len('Cython.Compiler.'):] not in ignored_modules ]
coverage.report(modules, show_missing=0)
if options.coverage:
coverage.report(modules, show_missing=0)
if options.coverage_xml:
coverage.xml_report(modules, outfile="coverage-report.xml")
if missing_dep_excluder.tests_missing_deps:
sys.stderr.write("Following tests excluded because of missing dependencies on your system:\n")
......
......@@ -85,7 +85,7 @@ else:
else:
scripts = ["cython.py"]
def compile_cython_modules():
def compile_cython_modules(profile=False):
source_root = os.path.abspath(os.path.dirname(__file__))
compiled_modules = ["Cython.Plex.Scanners",
"Cython.Compiler.Scanning",
......@@ -116,6 +116,10 @@ def compile_cython_modules():
del sys.modules[module]
sys.path.insert(0, os.path.join(source_root, self.build_lib))
if profile:
from Cython.Compiler.Options import directive_defaults
directive_defaults['profile'] = True
print("Enabled profiling for the Cython binary modules")
build_ext_orig.build_extensions(self)
setup_args['ext_modules'] = extensions
......@@ -132,6 +136,10 @@ def compile_cython_modules():
print("Compilation of '%s' failed" % ext.sources[0])
from Cython.Compiler.Main import compile
from Cython import Utils
if profile:
from Cython.Compiler.Options import directive_defaults
directive_defaults['profile'] = True
print("Enabled profiling for the Cython binary modules")
source_root = os.path.dirname(__file__)
for module in compiled_modules:
source_file = os.path.join(source_root, *module.split('.'))
......@@ -159,10 +167,14 @@ def compile_cython_modules():
print("ERROR: %s" % sys.exc_info()[1])
print("Extension module compilation failed, using plain Python implementation")
cython_profile = '--cython-profile' in sys.argv
if cython_profile:
sys.argv.remove('--cython-profile')
try:
sys.argv.remove("--no-cython-compile")
except ValueError:
compile_cython_modules()
compile_cython_modules(cython_profile)
setup_args.update(setuptools_extra_args)
......
#ifdef __cplusplus
extern "C" {
#endif
extern DL_EXPORT(int) f1(void);
extern DL_EXPORT(int) __cdecl f2(void);
extern DL_EXPORT(int) __stdcall f3(void);
extern DL_EXPORT(int) __fastcall f4(void);
#ifdef __cplusplus
}
#endif
int f1(void) {return 0;}
int __cdecl f2(void) {return 0;}
int __stdcall f3(void) {return 0;}
int __fastcall f4(void) {return 0;}
#ifdef __cplusplus
extern "C" {
#endif
extern int (*p1)(void);
extern int (__cdecl *p2)(void);
extern int (__stdcall *p3)(void);
extern int (__fastcall *p4)(void);
#ifdef __cplusplus
}
#endif
int (*p1)(void);
int (__cdecl *p2)(void);
int (__stdcall *p3)(void);
int (__fastcall *p4)(void);
cdef extern from "callingconvention.h":
pass
cdef extern int f1()
cdef extern int __cdecl f2()
......
#ifdef __cplusplus
extern "C" {
#endif
extern char *cp;
extern char *cpa[5];
extern int (*ifnpa[5])(void);
extern char *(*cpfnpa[5])(void);
extern int (*ifnp)(void);
extern int (*iap)[5];
#ifdef __cplusplus
}
#endif
char *cp;
char *cpa[5];
int (*ifnpa[5])(void);
char *(*cpfnpa[5])(void);
int (*ifnp)(void);
int (*iap)[5];
#ifdef __cplusplus
extern "C" {
#endif
extern DL_EXPORT(int) ifn(void);
extern DL_EXPORT(char *) cpfn(void);
extern DL_EXPORT(int) fnargfn(int (void));
extern DL_EXPORT(int) (*iapfn(void))[5];
extern DL_EXPORT(char *)(*cpapfn(void))[5];
#ifdef __cplusplus
}
#endif
int ifn(void) {return 0;}
char *cpfn(void) {return 0;}
int fnargfn(int f(void)) {return 0;}
#ifdef __cplusplus
extern "C" {
#endif
extern int ia[];
extern int iaa[][3];
extern DL_EXPORT(int) a(int[][3], int[][3][5]);
#ifdef __cplusplus
}
#endif
int ia[1];
int iaa[1][3];
int a(int a[][3], int b[][3][5]) {return 0;}
cdef extern from "declarations.h":
pass
cdef extern char *cp
cdef extern char *cpa[5]
cdef extern int (*ifnpa[5])()
......
#ifdef __cplusplus
extern "C" {
#endif
extern DL_EXPORT(int) spam(void);
extern DL_EXPORT(void) grail(void);
extern DL_EXPORT(char *)tomato(void);
#ifdef __cplusplus
}
#endif
int spam(void) {return 0;}
void grail(void) {return;}
char *tomato(void) {return 0;}
cdef extern from "excvalcheck.h":
pass
cdef extern int spam() except -1
cdef extern void grail() except *
cdef extern char *tomato() except? NULL
......
cimport libc
cimport libc.stdio
cimport libc.errno
cimport libc.float
cimport libc.limits
cimport libc.locale
cimport libc.signal
cimport libc.stddef
cimport libc.stdint
cimport libc.stdio
cimport libc.stdlib
cimport libc.string
from libc cimport errno
from libc cimport float
from libc cimport limits
from libc cimport locale
from libc cimport signal
from libc cimport stddef
from libc cimport stdint
from libc cimport stdio
from libc cimport stdlib
from libc cimport string
from libc.errno cimport *
from libc.float cimport *
from libc.limits cimport *
......@@ -8,3 +33,7 @@ from libc.stdint cimport *
from libc.stdio cimport *
from libc.stdlib cimport *
from libc.string cimport *
libc.stdio.printf("hello %s\n", b"world")
stdio.printf("hello %s\n", b"world")
printf("hello %s\n", b"world")
cimport libcpp
cimport libcpp.deque
cimport libcpp.list
cimport libcpp.map
cimport libcpp.pair
cimport libcpp.queue
cimport libcpp.set
cimport libcpp.stack
cimport libcpp.vector
from libcpp.deque cimport *
from libcpp.list cimport *
from libcpp.map cimport *
from libcpp.pair cimport *
from libcpp.queue cimport *
from libcpp.set cimport *
from libcpp.stack cimport *
from libcpp.vector cimport *
cdef libcpp.deque.deque[int] d1 = deque[int]()
cdef libcpp.list.list[int] l1 = list[int]()
cdef libcpp.map.map[int,int] m1 = map[int,int]()
cdef libcpp.pair.pair[int,int] p1 = pair[int,int](1,2)
cdef libcpp.queue.queue[int] q1 = queue[int]()
cdef libcpp.set.set[int] s1 = set[int]()
cdef libcpp.stack.stack[int] t1 = stack[int]()
cdef libcpp.vector.vector[int] v1 = vector[int]()
cdef deque[int].iterator id1 = d1.begin()
cdef deque[int].iterator id2 = d1.end()
cdef deque[int].reverse_iterator rid1 = d1.rbegin()
cdef deque[int].reverse_iterator rid2 = d1.rend()
cdef list[int].iterator il1 = l1.begin()
cdef list[int].iterator il2 = l1.end()
cdef list[int].reverse_iterator ril1 = l1.rbegin()
cdef list[int].reverse_iterator ril2 = l1.rend()
cdef map[int,int].iterator im1 = m1.begin()
cdef map[int,int].iterator im2 = m1.end()
cdef map[int,int].reverse_iterator rim1 = m1.rbegin()
cdef map[int,int].reverse_iterator rim2 = m1.rend()
cdef pair[map[int,int].iterator, bint] pimb = m1.insert(p1)
cdef set[int].iterator is1 = s1.begin()
cdef set[int].iterator is2 = s1.end()
cdef set[int].reverse_iterator ris1 = s1.rbegin()
cdef set[int].reverse_iterator ris2 = s1.rend()
cdef pair[set[int].iterator, bint] pisb = s1.insert(4)
cdef vector[int].iterator iv1 = v1.begin()
cdef vector[int].iterator iv2 = v1.end()
cdef vector[int].reverse_iterator riv1 = v1.rbegin()
cdef vector[int].reverse_iterator riv2 = v1.rend()
void e1(void);
void *e2(void);
#ifdef __cplusplus
extern "C" {
#endif
extern DL_EXPORT(void) e1(void);
extern DL_EXPORT(void *) e2(void);
#ifdef __cplusplus
}
#endif
void e1(void) {return;}
void *e2(void) {return 0;}
#ifdef __cplusplus
extern "C" {
#endif
extern DL_EXPORT(PyObject *) g(PyObject*);
extern DL_EXPORT(void) g2(PyObject*);
#ifdef __cplusplus
}
#endif
PyObject *g(PyObject* o) {return 0;}
void g2(PyObject* o) {return;}
cdef class C:
def __cinit__(self):
"This is an unusable docstring."
def __init__(self):
"This is an unusable docstring."
def __dealloc__(self):
"This is an unusable docstring."
def __richcmp__(self, other, int op):
"This is an unusable docstring."
def __nonzero__(self):
"This is an unusable docstring."
return False
def __contains__(self, other):
"This is an unusable docstring."
property foo:
def __get__(self):
"So is this."
def __set__(self, x):
"And here is another one."
def __add__(self, other):
"usable docstring"
def __iter__(self):
"usable docstring"
return False
def __next__(self):
"usable docstring"
return False
cdef extern from *:
cdef cppclass Foo:
Foo()
Foo(int)
new Foo(1, 2)
_ERRORS = u"""
6:7: no suitable method found
"""
def eggs(int x not None, y not None):
def eggs(int x not None, char* y not None):
pass
_ERRORS = u"""
1:0: Only extension type arguments can have 'not None'
1:0: Only extension type arguments can have 'not None'
1: 9: Only Python type arguments can have 'not None'
1:25: Only Python type arguments can have 'not None'
"""
......@@ -4,12 +4,14 @@ cdef int cx = "test" # fails
cdef int x1 = "\xFF" # works
cdef int x2 = "\u0FFF" # fails
cdef int x3 = u"\xFF" # fails
cdef Py_UNICODE u1 = u"\xFF" # works
cdef int u3 = u"\xFF" # fails
_ERRORS = u"""
2:14: Only single-character strings can be coerced into ints.
3:14: Only single-character strings can be coerced into ints.
6:15: Only single-character strings can be coerced into ints.
7:14: Unicode objects do not support coercion to C types.
_ERRORS = """
2:14: Only single-character string literals can be coerced into ints.
3:14: Only single-character string literals can be coerced into ints.
6:15: Only single-character string literals can be coerced into ints.
9:14: Unicode literals do not support coercion to C types other than Py_UNICODE.
"""
# -*- coding: iso-8859-1 -*-
cdef Py_UNICODE char_ASCII = u'A'
cdef Py_UNICODE char_KLINGON = u'\uF8D2'
def char_too_long_ASCII():
cdef Py_UNICODE c = u'AB'
def char_too_long_Unicode():
cdef Py_UNICODE c = u'A\uF8D2'
def char_too_long_bytes():
cdef Py_UNICODE c = b'AB'
def char_too_long_latin1():
cdef Py_UNICODE char_bytes_latin1 = b'\xf6'
_ERRORS = """
7:24: Only single-character Unicode string literals can be coerced into Py_UNICODE.
10:24: Only single-character Unicode string literals can be coerced into Py_UNICODE.
13:24: Only single-character string literals can be coerced into ints.
16:40: Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.
"""
......@@ -50,7 +50,7 @@ cdef list l_f2 = b1
cdef list l_f3 = u1
_ERRORS = u"""
25:20: Unicode objects do not support coercion to C types.
25:20: Unicode literals do not support coercion to C types other than Py_UNICODE.
26:22: Unicode objects do not support coercion to C types.
27:22: 'str' objects do not support coercion to C types (use 'bytes'?).
......
......@@ -110,4 +110,20 @@ cdef class MyCdefClass:
False
"""
def __len__(self):
"""
Should not be included, as it can't be looked up with getattr in Py 3.1
>>> True
False
"""
def __contains__(self, value):
"""
Should not be included, as it can't be looked up with getattr in Py 3.1
>>> True
False
"""
cdeffunc()
def bool_list(list obj):
"""
>>> bool_list( [] )
False
>>> bool_list( [1] )
True
>>> bool_list(None)
False
"""
return bool(obj)
def if_list(list obj):
"""
>>> if_list( [] )
False
>>> if_list( [1] )
True
>>> if_list(None)
False
"""
if obj:
return True
else:
return False
def if_list_literal(t):
"""
>>> if_list_literal(True)
True
>>> if_list_literal(False)
False
"""
if t:
if [1,2,3]:
return True
else:
return False
else:
if []:
return True
else:
return False
def bool_tuple(tuple obj):
"""
>>> bool_tuple( () )
False
>>> bool_tuple( (1,) )
True
>>> bool_tuple(None)
False
"""
return bool(obj)
def if_tuple(tuple obj):
"""
>>> if_tuple( () )
False
>>> if_tuple( (1,) )
True
>>> if_tuple(None)
False
"""
if obj:
return True
else:
return False
def if_tuple_literal(t):
"""
>>> if_tuple_literal(True)
True
>>> if_tuple_literal(False)
False
"""
if t:
if (1,2,3):
return True
else:
return False
else:
if ():
return True
else:
return False
b0 = b''
b1 = b'abc'
def bool_bytes(bytes obj):
"""
>>> bool_bytes(b0)
False
>>> bool_bytes(b1)
True
>>> bool_bytes(None)
False
"""
return bool(obj)
def if_bytes(bytes obj):
"""
>>> if_bytes(b0)
False
>>> if_bytes(b1)
True
>>> if_bytes(None)
False
"""
if obj:
return True
else:
return False
def if_bytes_literal(t):
"""
>>> if_bytes_literal(True)
True
>>> if_bytes_literal(False)
False
"""
if t:
if b'abc':
return True
else:
return False
else:
if b'':
return True
else:
return False
u0 = u''
u1 = u'abc'
def bool_unicode(unicode obj):
"""
>>> bool_unicode(u0)
False
>>> bool_unicode(u1)
True
>>> bool_unicode(None)
False
"""
return bool(obj)
def if_unicode(unicode obj):
"""
>>> if_unicode(u0)
False
>>> if_unicode(u1)
True
>>> if_unicode(None)
False
"""
if obj:
return True
else:
return False
def if_unicode_literal(t):
"""
>>> if_unicode_literal(True)
True
>>> if_unicode_literal(False)
False
"""
if t:
if u'abc':
return True
else:
return False
else:
if u'':
return True
else:
return False
......@@ -17,6 +17,19 @@ def slice_charptr_decode():
cstring[:3].decode('UTF-8'),
cstring[:9].decode('UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_platform_encoding():
"""
>>> print(str(slice_charptr_decode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
cdef bytes s = u'abcABCqtp'.encode()
cdef char* cstr = s
return (cstr[:1].decode(),
cstr[:3].decode(),
cstr[:9].decode())
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_unknown_encoding():
......
......@@ -69,15 +69,9 @@ def lentest_uchar_c():
return l
@cython.test_assert_path_exists(
"//SimpleCallNode",
)
def lentest_py():
return len(pystr)
@cython.test_assert_path_exists(
"//SimpleCallNode",
)
def lentest_py_c():
cdef Py_ssize_t l = len(pystr)
return l
......@@ -43,4 +43,18 @@ def test_conjugate(long complex z):
>>> test_conjugate(2+3j)
(2-3j)
"""
return z.conjugate()
\ No newline at end of file
return z.conjugate()
def test_conjugate2(short complex z):
"""
>>> test_conjugate2(2+3j)
(2-3j)
"""
return z.conjugate()
def test_conjugate3(long long complex z):
"""
>>> test_conjugate3(2+3j)
(2-3j)
"""
return z.conjugate()
......@@ -26,3 +26,20 @@ def test_wrap_pair(int i, double x):
return wrap.get().first(), wrap.get().second(), deref(wrap) == deref(wrap)
finally:
del wrap
def test_wrap_pair_pair(int i, int j, double x):
"""
>>> test_wrap_pair_pair(1, 3, 1.5)
(1, 3, 1.5, True)
>>> test_wrap_pair_pair(2, 5, 2.25)
(2, 5, 2.25, True)
"""
try:
wrap = new Wrap[Pair[int, Pair[int, double]]](
Pair[int, Pair[int, double]](i,Pair[int, double](j, x)))
return (wrap.get().first(),
wrap.get().second().first(),
wrap.get().second().second(),
deref(wrap) == deref(wrap))
finally:
del wrap
......@@ -13,6 +13,7 @@ class Pair {
T1 _first;
T2 _second;
public:
Pair() { }
Pair(T1 u, T2 v) { _first = u; _second = v; }
T1 first(void) { return _first; }
T2 second(void) { return _second; }
......
......@@ -78,7 +78,7 @@ def test_attr_int(TestExtInt e):
return False
ctypedef union _aux:
int i
size_t i
void *p
cdef class TestExtPtr:
......
cimport cython
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def get(dict d, key):
"""
>>> d = { 1: 10 }
......@@ -38,6 +43,9 @@ def get(dict d, key):
"""
return d.get(key)
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def get_default(dict d, key, default):
"""
>>> d = { 1: 10 }
......@@ -69,3 +77,14 @@ def get_default(dict d, key, default):
ValueError
"""
return d.get(key, default)
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def get_in_condition(dict d, key, expected_result):
"""
>>> d = dict(a=1, b=2)
>>> get_in_condition(d, 'a', 1)
True
"""
return d.get(key) is expected_result
......@@ -32,3 +32,12 @@ def test(dict d, index):
cdef class Subscriptable:
def __getitem__(self, key):
return key
def getitem_in_condition(dict d, key, expected_result):
"""
>>> d = dict(a=1, b=2)
>>> getitem_in_condition(d, 'a', 1)
True
"""
return d[key] is expected_result
cimport cython
import sys
IS_PY3 = sys.version_info[0] >= 3
def _bool():
"""
>>> _bool() == bool()
True
"""
return bool()
def _int():
"""
>>> _int() == int()
True
"""
return int()
def _long():
"""
>>> IS_PY3 or _long() == long()
True
"""
return long()
def _float():
"""
>>> _float() == float()
True
"""
return float()
def _complex():
"""
>>> _complex() == complex()
True
"""
return complex()
def _bytes():
"""
>>> IS_PY3 and _bytes() == bytes() or _bytes() == str()
True
"""
return bytes()
def _str():
"""
>>> _str() == str()
True
"""
return str()
def _unicode():
"""
>>> IS_PY3 and _unicode() == str() or _unicode() == unicode()
True
"""
return unicode()
def _tuple():
"""
>>> _tuple() == tuple()
True
"""
return tuple()
def _list():
"""
>>> _list() == list()
True
"""
return list()
def _dict():
"""
>>> _dict() == dict()
True
"""
return dict()
py_set = cython.set
def _set():
"""
>>> _set() == py_set()
True
"""
return set()
py_frozenset = cython.frozenset
def _frozenset():
"""
>>> _frozenset() == py_frozenset()
True
"""
return frozenset()
cdef public enum Truth:
FALSE=0
TRUE=1
def enum_boolctx(Truth arg):
"""
>>> enum_boolctx(FALSE)
False
>>> enum_boolctx(TRUE)
True
"""
if arg:
return True
else:
return False
cdef extern from *:
enum: FALSE_VALUE "(0)"
enum: TRUE_VALUE "(1)"
def extern_enum_false():
"""
>>> extern_enum_false()
"""
if FALSE_VALUE:
raise ValueError
def extern_enum_true():
"""
>>> extern_enum_true()
"""
if not TRUE_VALUE:
raise ValueError
def extern_enum_false_true():
"""
>>> extern_enum_false_true()
"""
if not TRUE_VALUE or FALSE_VALUE:
raise ValueError
cimport cython
### extension types
cdef class MyExtType:
cdef object attr
def __cinit__(self):
self.attr = 123
cdef attr(MyExtType x):
return x is None and 321 or x.attr
# defaults, without 'not/or None'
def ext_default(MyExtType x): # currently behaves like 'or None'
"""
>>> ext_default(MyExtType())
123
>>> ext_default(None)
321
"""
return attr(x)
@cython.allow_none_for_extension_args(False)
def ext_default_none(MyExtType x=None): # special cased default arg
"""
>>> ext_default_none(MyExtType())
123
>>> ext_default_none(None)
321
>>> ext_default_none()
321
"""
return attr(x)
@cython.allow_none_for_extension_args(True)
def ext_default_check_off(MyExtType x):
"""
>>> ext_default_check_off(MyExtType())
123
>>> ext_default_check_off(None)
321
"""
return attr(x)
@cython.allow_none_for_extension_args(False)
def ext_default_check_on(MyExtType x):
"""
>>> ext_default_check_on(MyExtType())
123
>>> ext_default_check_on(None)
Traceback (most recent call last):
TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType)
"""
return attr(x)
# with 'or/not None'
def ext_or_none(MyExtType x or None):
"""
>>> ext_or_none(MyExtType())
123
>>> ext_or_none(None)
321
"""
return attr(x)
def ext_not_none(MyExtType x not None):
"""
>>> ext_not_none(MyExtType())
123
>>> ext_not_none(None)
Traceback (most recent call last):
TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType)
"""
return attr(x)
### builtin types (using list)
cdef litem(list L, int item):
return L is None and 321 or L[item]
# defaults, without 'not/or None'
def builtin_default(list L): # currently behaves like 'or None'
"""
>>> builtin_default([123])
123
>>> builtin_default(None)
321
"""
return litem(L, 0)
@cython.allow_none_for_extension_args(False)
def builtin_default_none(list L=None): # special cased default arg
"""
>>> builtin_default_none([123])
123
>>> builtin_default_none(None)
321
>>> builtin_default_none()
321
"""
return litem(L, 0)
@cython.allow_none_for_extension_args(True)
def builtin_default_check_off(list L):
"""
>>> builtin_default_check_off([123])
123
>>> builtin_default_check_off(None)
321
"""
return litem(L, 0)
@cython.allow_none_for_extension_args(False)
def builtin_default_check_on(list L):
"""
>>> builtin_default_check_on([123])
123
>>> builtin_default_check_on(None)
Traceback (most recent call last):
TypeError: Argument 'L' has incorrect type (expected list, got NoneType)
"""
return litem(L, 0)
# with 'or/not None'
def builtin_or_none(list L or None):
"""
>>> builtin_or_none([123])
123
>>> builtin_or_none(None)
321
"""
return litem(L, 0)
def builtin_not_none(list L not None):
"""
>>> builtin_not_none([123])
123
>>> builtin_not_none(None)
Traceback (most recent call last):
TypeError: Argument 'L' has incorrect type (expected list, got NoneType)
"""
return litem(L, 0)
## builtin type 'object' - isinstance(None, object) is True!
@cython.allow_none_for_extension_args(False)
def object_default(object o): # always behaves like 'or None'
"""
>>> object_default(object())
'object'
>>> object_default([])
'list'
>>> object_default(None)
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def object_default_none(object o=None): # behaves like 'or None'
"""
>>> object_default_none(object())
'object'
>>> object_default_none([])
'list'
>>> object_default_none(None)
'NoneType'
>>> object_default_none()
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def object_or_none(object o or None):
"""
>>> object_or_none(object())
'object'
>>> object_or_none([])
'list'
>>> object_or_none(None)
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def object_not_none(object o not None):
"""
>>> object_not_none(object())
'object'
>>> object_not_none([])
'list'
>>> object_not_none(None)
Traceback (most recent call last):
TypeError: Argument 'o' must not be None
"""
return type(o).__name__
## untyped 'object' - isinstance(None, object) is True!
@cython.allow_none_for_extension_args(False)
def notype_default(o): # behaves like 'or None'
"""
>>> notype_default(object())
'object'
>>> notype_default([])
'list'
>>> notype_default(None)
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def notype_default_none(o=None): # behaves like 'or None'
"""
>>> notype_default_none(object())
'object'
>>> notype_default_none([])
'list'
>>> notype_default_none(None)
'NoneType'
>>> notype_default_none()
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def notype_or_none(o or None):
"""
>>> notype_or_none(object())
'object'
>>> notype_or_none([])
'list'
>>> notype_or_none(None)
'NoneType'
"""
return type(o).__name__
@cython.allow_none_for_extension_args(False)
def notype_not_none(o not None):
"""
>>> notype_not_none(object())
'object'
>>> notype_not_none([])
'list'
>>> notype_not_none(None)
Traceback (most recent call last):
TypeError: Argument 'o' must not be None
"""
return type(o).__name__
cimport cython
bytes_abc = b'abc'
bytes_ABC = b'ABC'
bytes_abc_null = b'a\0b\0c'
bytes_ABC_null = b'A\0B\0C'
unicode_abc = u'abc'
unicode_ABC = u'ABC'
unicode_abc_null = u'a\0b\0c'
unicode_ABC_null = u'A\0B\0C'
def for_in_bytes(bytes s):
"""
>>> for_in_bytes(bytes_abc)
'X'
>>> for_in_bytes(bytes_ABC)
'C'
>>> for_in_bytes(bytes_abc_null)
'X'
>>> for_in_bytes(bytes_ABC_null)
'C'
"""
for c in s:
# Py2/Py3
if c == b'C' or c == c'C':
return 'C'
else:
return 'X'
@cython.test_assert_path_exists("//ForFromStatNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def for_char_in_bytes(bytes s):
"""
>>> for_char_in_bytes(bytes_abc)
'X'
>>> for_char_in_bytes(bytes_ABC)
'C'
>>> for_char_in_bytes(bytes_abc_null)
'X'
>>> for_char_in_bytes(bytes_ABC_null)
'C'
"""
cdef char c
for c in s:
if c == b'C':
return 'C'
else:
return 'X'
@cython.test_assert_path_exists("//ForFromStatNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def for_char_in_enumerate_bytes(bytes s):
"""
>>> for_char_in_enumerate_bytes(bytes_abc)
'X'
>>> for_char_in_enumerate_bytes(bytes_ABC)
2
>>> for_char_in_enumerate_bytes(bytes_abc_null)
'X'
>>> for_char_in_enumerate_bytes(bytes_ABC_null)
4
"""
cdef char c
cdef Py_ssize_t i
for i, c in enumerate(s):
if c == b'C':
return i
else:
return 'X'
@cython.test_assert_path_exists("//ForFromStatNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def for_pyunicode_in_unicode(unicode s):
"""
>>> for_pyunicode_in_unicode(unicode_abc)
'X'
>>> for_pyunicode_in_unicode(unicode_ABC)
'C'
>>> for_pyunicode_in_unicode(unicode_abc_null)
'X'
>>> for_pyunicode_in_unicode(unicode_ABC_null)
'C'
"""
cdef Py_UNICODE c
for c in s:
if c == u'C':
return 'C'
else:
return 'X'
@cython.test_assert_path_exists("//ForFromStatNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
def for_pyunicode_in_enumerate_unicode(unicode s):
"""
>>> for_pyunicode_in_enumerate_unicode(unicode_abc)
'X'
>>> for_pyunicode_in_enumerate_unicode(unicode_ABC)
2
>>> for_pyunicode_in_enumerate_unicode(unicode_abc_null)
'X'
>>> for_pyunicode_in_enumerate_unicode(unicode_ABC_null)
4
"""
cdef Py_UNICODE c
cdef Py_ssize_t i
for i, c in enumerate(s):
if c == u'C':
return i
else:
return 'X'
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
from __future__ import with_statement
import sys
if sys.version_info < (2,5):
__doc__ = __doc__.replace(u"exit <type 'type'> <type 'MyException'>",
u"exit <type 'classobj'> <type 'instance'>")
def typename(t):
return u"<type '%s'>" % type(t).__name__
......
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