Commit 8193f74a authored by Mark Florisson's avatar Mark Florisson
parents 76567d05 43a3dbea
......@@ -38,3 +38,4 @@ ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2
a6b9f0a6d02d23fc3d3a9d0587867faa3afb2fcd 0.14.rc0
15bf34c9387444e262acb1de594405444dd571a4 0.14
......@@ -220,7 +220,11 @@ def parse_dependencies(source_filename):
# Actual parsing is way to slow, so we use regular expressions.
# The only catch is that we must strip comments and string
# literals ahead of time.
source = Utils.open_source_file(source_filename, "rU").read()
fh = Utils.open_source_file(source_filename, "rU")
try:
source = fh.read()
finally:
fh.close()
distutils_info = DistutilsInfo(source)
source, literals = strip_string_literals(source)
source = source.replace('\\\n', ' ')
......
......@@ -52,9 +52,12 @@ def unbound_symbols(code, context=None):
symbol_collector = AllSymbols()
symbol_collector(tree)
unbound = []
import __builtin__
try:
import builtins
except ImportError:
import __builtin__ as builtins
for name in symbol_collector.names:
if not tree.scope.lookup(name) and not hasattr(__builtin__, name):
if not tree.scope.lookup(name) and not hasattr(builtins, name):
unbound.append(name)
return unbound
......@@ -79,7 +82,7 @@ def safe_type(arg, context=None):
return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim)
else:
for base_type in py_type.mro():
if base_type.__module__ == '__builtin__':
if base_type.__module__ in ('__builtin__', 'builtins'):
return 'object'
module = context.find_module(base_type.__module__, need_pxd=False)
if module:
......@@ -125,7 +128,7 @@ def cython_inline(code,
arg_names.sort()
arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names])
key = code, arg_sigs, sys.version_info, sys.executable, Cython.__version__
module_name = "_cython_inline_" + hashlib.md5(str(key)).hexdigest()
module_name = "_cython_inline_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
try:
if not os.path.exists(lib_dir):
os.makedirs(lib_dir)
......@@ -160,7 +163,11 @@ def __invoke(%(params)s):
for key, value in literals.items():
module_code = module_code.replace(key, value)
pyx_file = os.path.join(lib_dir, module_name + '.pyx')
open(pyx_file, 'w').write(module_code)
fh = open(pyx_file, 'w')
try:
fh.write(module_code)
finally:
fh.close()
extension = Extension(
name = module_name,
sources = [pyx_file],
......
......@@ -44,7 +44,7 @@ class AnnotationCCodeWriter(CCodeWriter):
if pos is not None:
CCodeWriter.mark_pos(self, pos)
if self.last_pos:
pos_code = self.code.setdefault(self.last_pos[0].get_description(),{})
pos_code = self.code.setdefault(self.last_pos[0].filename,{})
code = pos_code.get(self.last_pos[1], "")
pos_code[self.last_pos[1]] = code + self.annotation_buffer.getvalue()
self.annotation_buffer = StringIO()
......
......@@ -10,15 +10,15 @@ usage = """\
Cython (http://cython.org) is a compiler for code written in the
Cython language. Cython is based on Pyrex by Greg Ewing.
Usage: cython [options] sourcefile.pyx ...
Usage: cython [options] sourcefile.{pyx,py} ...
Options:
-V, --version Display version number of cython compiler
-l, --create-listing Write error messages to a listing file
-I, --include-dir <directory> Search for include files in named directory
(multiply include directories are allowed).
(multiple include directories are allowed).
-o, --output-file <filename> Specify name of generated C file
-t, --timestamps Only compile newer source files (implied with -r)
-t, --timestamps Only compile newer source files
-f, --force Compile all source files (overrides implied -t)
-q, --quiet Don't print module names in recursive mode
-v, --verbose Be verbose, print file names on multiple compilation
......@@ -30,11 +30,11 @@ Options:
are searched from)
--gdb Output debug information for cygdb
-D, --no-docstrings Remove docstrings.
-D, --no-docstrings Strip docstrings from the compiled module.
-a, --annotate Produce a colorized HTML version of the source.
--line-directives Produce #line directives pointing to the .pyx source
--cplus Output a c++ rather than c file.
--embed Embed the Python interpreter in a main() method.
--cplus Output a C++ rather than C file.
--embed Generate a main() function that embeds the Python interpreter.
-2 Compile based on Python-2 syntax and code semantics.
-3 Compile based on Python-3 syntax and code semantics.
--fast-fail Abort the compilation on the first error
......@@ -42,7 +42,7 @@ Options:
"""
# The following is broken http://trac.cython.org/cython_trac/ticket/379
# -r, --recursive Recursively find and compile dependencies
# -r, --recursive Recursively find and compile dependencies (implies -t)
#The following experimental options are supported only on MacOSX:
......@@ -125,6 +125,8 @@ def parse_command_line(args):
options.language_level = 3
elif option == "--fast-fail":
Options.fast_fail = True
elif option == "--disable-function-redefinition":
Options.disable_function_redefinition = True
elif option in ("-X", "--directive"):
try:
options.compiler_directives = Options.parse_directive_list(
......@@ -141,6 +143,9 @@ def parse_command_line(args):
else:
sys.stderr.write("Unknown debug flag: %s\n" % option)
bad_usage()
elif option in ('-h', '--help'):
sys.stdout.write(usage)
sys.exit(0)
else:
sys.stderr.write("Unknown compiler flag: %s\n" % option)
sys.exit(1)
......
......@@ -6,7 +6,7 @@
import cython
cython.declare(re=object, Naming=object, Options=object, StringEncoding=object,
Utils=object, SourceDescriptor=object, StringIOTree=object,
DebugFlags=object, none_or_sub=object)
DebugFlags=object, none_or_sub=object, basestring=object)
import re
import Naming
......@@ -19,9 +19,9 @@ import DebugFlags
from Cython.Utils import none_or_sub
try:
basestring
except NameError:
basestring = str
from __builtin__ import basestring
except ImportError:
from builtins import str as basestring
class UtilityCode(object):
# Stores utility code to add during code generation.
......
......@@ -948,7 +948,8 @@ class BytesNode(ConstNode):
#
# value BytesLiteral
type = PyrexTypes.c_char_ptr_type
# start off as Python 'bytes' to support len() in O(1)
type = bytes_type
def compile_time_value(self, denv):
return self.value
......@@ -969,11 +970,13 @@ class BytesNode(ConstNode):
return len(self.value) == 1
def coerce_to_boolean(self, env):
# This is special because we start off as a C char*. Testing
# that for truth directly would yield the wrong result.
# This is special because testing a C char* for truth directly
# would yield the wrong result.
return BoolNode(self.pos, value=bool(self.value))
def coerce_to(self, dst_type, env):
if self.type == dst_type:
return self
if dst_type.is_int:
if not self.can_coerce_to_char_literal():
error(self.pos, "Only single-character string literals can be coerced into ints.")
......@@ -984,21 +987,20 @@ class BytesNode(ConstNode):
return CharNode(self.pos, value=self.value)
node = BytesNode(self.pos, value=self.value)
if dst_type == PyrexTypes.c_char_ptr_type:
node.type = PyrexTypes.c_char_ptr_type
if dst_type.is_pyobject:
if dst_type in (py_object_type, Builtin.bytes_type):
node.type = Builtin.bytes_type
else:
self.check_for_coercion_error(dst_type, fail=True)
return node
elif dst_type == PyrexTypes.c_char_ptr_type:
node.type = dst_type
return node
elif dst_type == PyrexTypes.c_uchar_ptr_type:
node.type = PyrexTypes.c_char_ptr_type
return CastNode(node, PyrexTypes.c_uchar_ptr_type)
if not self.type.is_pyobject:
if dst_type in (py_object_type, Builtin.bytes_type):
node.type = Builtin.bytes_type
elif dst_type.is_pyobject:
self.fail_assignment(dst_type)
return self
elif dst_type.is_pyobject and dst_type is not py_object_type:
self.check_for_coercion_error(dst_type, fail=True)
elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
node.type = dst_type
return node
# We still need to perform normal coerce_to processing on the
......@@ -1006,11 +1008,6 @@ class BytesNode(ConstNode):
# in which case a type test node will be needed.
return ConstNode.coerce_to(node, dst_type, env)
def as_py_string_node(self, env):
# Return a new BytesNode with the same value as this node
# but whose type is a Python type instead of a C type.
return BytesNode(self.pos, value = self.value, type = Builtin.bytes_type)
def generate_evaluation_code(self, code):
if self.type.is_pyobject:
self.result_code = code.get_py_string_const(self.value)
......@@ -1431,7 +1428,7 @@ class NameNode(AtomicExprNode):
if self.is_used_as_rvalue:
entry = self.entry
if entry.is_builtin:
# if not Options.cache_builtins: # cached builtins are ok
if not Options.cache_builtins: # cached builtins are ok
self.gil_error()
elif entry.is_pyglobal:
self.gil_error()
......@@ -2036,7 +2033,7 @@ class IndexNode(ExprNode):
return None
def type_dependencies(self, env):
return self.base.type_dependencies(env)
return self.base.type_dependencies(env) + self.index.type_dependencies(env)
def infer_type(self, env):
base_type = self.base.infer_type(env)
......@@ -2605,6 +2602,7 @@ class SliceIndexNode(ExprNode):
self.start_code(),
self.stop_code()))
self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code)
def generate_slice_guard_code(self, code, target_size):
if not self.base.type.is_array:
......@@ -2952,11 +2950,23 @@ class SimpleCallNode(CallNode):
# Coerce arguments
for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type
self.args[i] = self.args[i].coerce_to(formal_type, env)
arg = self.args[i].coerce_to(formal_type, env)
if arg.type.is_pyobject and not env.nogil and (arg.is_attribute or not arg.is_simple):
# we do not own the argument's reference, but we must
# make sure it cannot be collected before we return
# from the function, so we create an owned temp
# reference to it
arg = arg.coerce_to_temp(env)
self.args[i] = arg
for i in range(max_nargs, actual_nargs):
if self.args[i].type.is_pyobject:
arg = self.args[i]
if arg.type.is_pyobject:
arg_ctype = arg.type.default_coerced_ctype()
if arg_ctype is None:
error(self.args[i].pos,
"Python object cannot be passed as a varargs parameter")
else:
self.args[i] = arg.coerce_to(arg_ctype, env)
# Calc result type and code fragment
if isinstance(self.function, NewExprNode):
self.type = PyrexTypes.CPtrType(self.function.class_type)
......@@ -3401,7 +3411,7 @@ class AttributeNode(ExprNode):
return module_scope.lookup_type(self.attribute)
if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
base_type = self.obj.analyse_as_type(env)
if base_type and hasattr(base_type, 'scope'):
if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
return base_type.scope.lookup_type(self.attribute)
return None
......@@ -8182,17 +8192,17 @@ typedef struct {
PyCFunctionObject func;
} %(binding_cfunc)s_object;
PyTypeObject %(binding_cfunc)s_type;
PyTypeObject *%(binding_cfunc)s = NULL;
static PyTypeObject %(binding_cfunc)s_type;
static PyTypeObject *%(binding_cfunc)s = NULL;
PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
#define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
int %(binding_cfunc)s_init(void); /* proto */
static int %(binding_cfunc)s_init(void); /* proto */
""" % Naming.__dict__,
impl="""
PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
%(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
if (op == NULL)
return NULL;
......@@ -8218,7 +8228,7 @@ static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyOb
return PyMethod_New(func, obj, type);
}
int %(binding_cfunc)s_init(void) {
static int %(binding_cfunc)s_init(void) {
%(binding_cfunc)s_type = PyCFunction_Type;
%(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
%(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
......
......@@ -74,7 +74,6 @@ class Context(object):
# language_level int currently 2 or 3 for Python 2/3
def __init__(self, include_directories, compiler_directives, cpp=False, language_level=2):
#self.modules = {"__builtin__" : BuiltinScope()}
import Builtin, CythonScope
self.modules = {"__builtin__" : Builtin.builtin_scope}
self.modules["cython"] = CythonScope.create_cython_scope(self)
......@@ -99,6 +98,7 @@ class Context(object):
from Future import print_function, unicode_literals
self.future_directives.add(print_function)
self.future_directives.add(unicode_literals)
self.modules['builtins'] = self.modules['__builtin__']
def create_pipeline(self, pxd, py=False):
from Visitor import PrintTree
......@@ -315,7 +315,10 @@ class Context(object):
try:
if debug_find_module:
print("Context.find_module: Parsing %s" % pxd_pathname)
source_desc = FileSourceDescriptor(pxd_pathname)
rel_path = module_name.replace('.', os.sep) + os.path.splitext(pxd_pathname)[1]
if not pxd_pathname.endswith(rel_path):
rel_path = pxd_pathname # safety measure to prevent printing incorrect paths
source_desc = FileSourceDescriptor(pxd_pathname, rel_path)
err, result = self.process_pxd(source_desc, scope, module_name)
if err:
raise err
......@@ -589,15 +592,23 @@ def run_pipeline(source, options, full_module_name = None):
# Set up source object
cwd = os.getcwd()
source_desc = FileSourceDescriptor(os.path.join(cwd, source))
abs_path = os.path.abspath(source)
source_ext = os.path.splitext(source)[1]
full_module_name = full_module_name or context.extract_module_name(source, options)
if options.relative_path_in_code_position_comments:
rel_path = full_module_name.replace('.', os.sep) + source_ext
if not abs_path.endswith(rel_path):
rel_path = source # safety measure to prevent printing incorrect paths
else:
rel_path = abs_path
source_desc = FileSourceDescriptor(abs_path, rel_path)
source = CompilationSource(source_desc, full_module_name, cwd)
# Set up result object
result = create_default_resultobj(source, options)
# Get pipeline
if source_desc.filename.endswith(".py"):
if source_ext.lower() == '.py':
pipeline = context.create_py_pipeline(options, result)
else:
pipeline = context.create_pyx_pipeline(options, result)
......@@ -825,6 +836,7 @@ default_options = dict(
compiler_directives = {},
evaluate_tree_assertions = False,
emit_linenums = False,
relative_path_in_code_position_comments = True,
language_level = 2,
gdb_debug = False,
)
......@@ -139,7 +139,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code.putln("")
h_code.putln("#endif")
h_code.copyto(open_new_file(result.h_file))
f = open_new_file(result.h_file)
try:
h_code.copyto(f)
finally:
f.close()
def generate_public_declaration(self, entry, h_code, i_code):
h_code.putln("%s %s;" % (
......@@ -222,7 +226,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code.putln("")
h_code.putln("#endif")
h_code.copyto(open_new_file(result.api_file))
f = open_new_file(result.api_file)
try:
h_code.copyto(f)
finally:
f.close()
def generate_cclass_header_code(self, type, h_code):
h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
......@@ -264,7 +272,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
code.putln("static int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name)
......@@ -569,14 +577,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#define PyBytes_Repr PyString_Repr
#define PyBytes_Concat PyString_Concat
#define PyBytes_ConcatAndDel PyString_ConcatAndDel
#endif
#if PY_VERSION_HEX < 0x02060000
#define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
#define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
#endif
#ifndef PySet_CheckExact
# define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
#define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
#endif
#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
#if PY_MAJOR_VERSION >= 3
#define PyIntObject PyLongObject
#define PyInt_Type PyLong_Type
......@@ -858,7 +870,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.extern_c_macro,
name))
elif entry.visibility == 'public':
#code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
Naming.extern_c_macro,
name))
......@@ -1591,8 +1602,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if entry.visibility == 'public':
header = "DL_EXPORT(PyTypeObject) %s = {"
else:
#header = "statichere PyTypeObject %s = {"
header = "PyTypeObject %s = {"
header = "static PyTypeObject %s = {"
#code.putln(header % scope.parent_type.typeobj_cname)
code.putln(header % type.typeobj_cname)
code.putln(
......@@ -2041,12 +2051,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.error_goto_if_null(type.typeptr_cname, pos))
self.use_type_import_utility_code(env)
if type.vtabptr_cname:
code.putln(
"if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
type.typeptr_cname,
type.vtabptr_cname,
code.error_goto(pos)))
env.use_utility_code(Nodes.get_vtable_utility_code)
code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
type.vtabptr_cname,
type.vtabstruct_cname,
type.typeptr_cname,
code.error_goto_if_null(type.vtabptr_cname, pos)))
env.types_imported[type] = 1
py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
......@@ -2099,24 +2109,24 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# a significant performance hit. (See trac #561.)
for func in entry.type.scope.pyfunc_entries:
if func.is_special and Options.docstrings and func.wrapperbase_cname:
code.putln("{");
code.putln("{")
code.putln(
'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
typeobj_cname,
func.name,
code.error_goto_if_null('wrapper', entry.pos)));
code.error_goto_if_null('wrapper', entry.pos)))
code.putln(
"if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {");
"if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
code.putln(
"%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
func.wrapperbase_cname));
func.wrapperbase_cname))
code.putln(
"%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname));
"%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
code.putln(
"((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
func.wrapperbase_cname));
code.putln("}");
code.putln("}");
func.wrapperbase_cname))
code.putln("}")
code.putln("}")
if type.vtable_cname:
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
......
......@@ -1353,7 +1353,7 @@ class FuncDefNode(StatNode, BlockNode):
# incref it to properly keep track of refcounts.
for entry in lenv.arg_entries:
if entry.type.is_pyobject:
if entry.assignments and not entry.in_closure:
if (acquire_gil or entry.assignments) and not entry.in_closure:
code.put_var_incref(entry)
# ----- Initialise local variables
for entry in lenv.var_entries:
......@@ -1463,7 +1463,7 @@ class FuncDefNode(StatNode, BlockNode):
if entry.type.is_pyobject:
if entry.in_closure:
code.put_var_giveref(entry)
elif entry.assignments:
elif acquire_gil or entry.assignments:
code.put_var_decref(entry)
if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
......@@ -1988,7 +1988,7 @@ class DefNode(FuncDefNode):
# staticmethod() was overridden - not much we can do here ...
self.is_staticmethod = False
if self.name == '__new__':
if self.name == '__new__' and env.is_py_class_scope:
self.is_staticmethod = 1
self.analyse_argument_types(env)
......@@ -2440,8 +2440,6 @@ class DefNode(FuncDefNode):
self.name, Naming.args_cname, self.error_value()))
code.putln("}")
code.globalstate.use_utility_code(keyword_string_check_utility_code)
if self.starstar_arg:
if self.star_arg:
kwarg_check = "unlikely(%s)" % Naming.kwds_cname
......@@ -2450,6 +2448,7 @@ class DefNode(FuncDefNode):
else:
kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
Naming.kwds_cname, Naming.kwds_cname)
code.globalstate.use_utility_code(keyword_string_check_utility_code)
code.putln(
"if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
kwarg_check, Naming.kwds_cname, self.name,
......@@ -2513,8 +2512,6 @@ class DefNode(FuncDefNode):
has_fixed_positional_count = not self.star_arg and \
min_positional_args == max_positional_args
code.globalstate.use_utility_code(raise_double_keywords_utility_code)
code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
if self.num_required_kw_args:
code.globalstate.use_utility_code(raise_keyword_required_utility_code)
......@@ -2605,6 +2602,7 @@ class DefNode(FuncDefNode):
if code.label_used(argtuple_error_label):
code.put_goto(success_label)
code.put_label(argtuple_error_label)
code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
self.name, has_fixed_positional_count,
min_positional_args, max_positional_args,
......@@ -2727,6 +2725,7 @@ class DefNode(FuncDefNode):
# kwargs) that were passed into positional
# arguments up to this point
code.putln('else {')
code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
self.name, has_fixed_positional_count,
min_positional_args, max_positional_args, i))
......@@ -3346,6 +3345,12 @@ class ExprStatNode(StatNode):
def analyse_expressions(self, env):
self.expr.analyse_expressions(env)
def nogil_check(self, env):
if self.expr.type.is_pyobject and self.expr.is_temp:
self.gil_error()
gil_message = "Discarding owned Python object"
def generate_execution_code(self, code):
self.expr.generate_evaluation_code(code)
if not self.expr.is_temp and self.expr.result():
......@@ -6094,7 +6099,8 @@ invalid_keyword:
bad:
return -1;
}
""")
""",
requires=[raise_double_keywords_utility_code])
#------------------------------------------------------------------------------------
......@@ -6238,25 +6244,26 @@ bad:
get_vtable_utility_code = UtilityCode(
proto = """
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
""",
impl = r"""
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
static void* __Pyx_GetVtable(PyObject *dict) {
void* ptr;
PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
if (!ob)
goto bad;
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
*(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
ptr = PyCapsule_GetPointer(ob, 0);
#else
*(void **)vtabptr = PyCObject_AsVoidPtr(ob);
ptr = PyCObject_AsVoidPtr(ob);
#endif
if (!*(void **)vtabptr)
goto bad;
if (!ptr && !PyErr_Occurred())
PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
Py_DECREF(ob);
return 0;
return ptr;
bad:
Py_XDECREF(ob);
return -1;
return NULL;
}
""")
......
......@@ -1110,8 +1110,9 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
def _function_is_builtin_name(self, function):
if not function.is_name:
return False
entry = self.current_env().lookup(function.name)
if entry and getattr(entry, 'scope', None) is not Builtin.builtin_scope:
env = self.current_env()
entry = env.lookup(function.name)
if entry is not env.builtin_scope().lookup_here(function.name):
return False
# if entry is None, it's at least an undeclared name, so likely builtin
return True
......@@ -1724,8 +1725,8 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
# into a C function call (defined in the builtin scope)
if not function.entry:
return node
is_builtin = function.entry.is_builtin \
or getattr(function.entry, 'scope', None) is Builtin.builtin_scope
is_builtin = function.entry.is_builtin or \
function.entry is self.current_env().builtin_scope().lookup_here(function.name)
if not is_builtin:
return node
function_handler = self._find_handler(
......@@ -1985,20 +1986,26 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
test_nodes = []
env = self.current_env()
for test_type_node in types:
if not test_type_node.entry:
return node
builtin_type = None
if isinstance(test_type_node, ExprNodes.NameNode):
if test_type_node.entry:
entry = env.lookup(test_type_node.entry.name)
if not entry or not entry.type or not entry.type.is_builtin_type:
return node
if entry and entry.type and entry.type.is_builtin_type:
builtin_type = entry.type
if builtin_type and builtin_type is not Builtin.type_type:
type_check_function = entry.type.type_check_function(exact=False)
if not type_check_function:
type_check_args = [arg]
elif test_type_node.type is Builtin.type_type:
type_check_function = '__Pyx_TypeCheck'
type_check_args = [arg, test_type_node]
else:
return node
if type_check_function not in tests:
tests.append(type_check_function)
test_nodes.append(
ExprNodes.PythonCapiCallNode(
test_type_node.pos, type_check_function, self.Py_type_check_func_type,
args = [arg],
args = type_check_args,
is_temp = True,
))
......
......@@ -51,6 +51,10 @@ c_line_in_traceback = 1
# executes the body of this module.
embed = False
# Disables function redefinition, allowing all functions to be declared at
# module creation time. For legacy code only.
disable_function_redefinition = False
# Declare compiler directives
directive_defaults = {
......
......@@ -353,6 +353,10 @@ class PyObjectType(PyrexType):
def can_coerce_to_pyobject(self, env):
return True
def default_coerced_ctype(self):
"The default C type that this Python type coerces to, or None."
return None
def assignable_from(self, src_type):
# except for pointers, conversion will be attempted
return not src_type.is_ptr or src_type.is_string
......@@ -404,6 +408,15 @@ class BuiltinObjectType(PyObjectType):
def __repr__(self):
return "<%s>"% self.cname
def default_coerced_ctype(self):
if self.name == 'bytes':
return c_char_ptr_type
elif self.name == 'bool':
return c_bint_type
elif self.name == 'float':
return c_double_type
return None
def assignable_from(self, src_type):
if isinstance(src_type, BuiltinObjectType):
return src_type.name == self.name
......@@ -1371,10 +1384,10 @@ impl="""
}
#if %(is_float)s
static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
#if HAVE_HYPOT
return hypot%(m)s(z.real, z.imag);
#else
#if !defined(HAVE_HYPOT) || defined(_MSC_VER)
return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
#else
return hypot%(m)s(z.real, z.imag);
#endif
}
static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s a, %(type)s b) {
......
......@@ -166,8 +166,9 @@ class FileSourceDescriptor(SourceDescriptor):
optional name argument and will be passed back when asking for
the position()-tuple.
"""
def __init__(self, filename):
def __init__(self, filename, path_description=None):
filename = Utils.decode_filename(filename)
self.path_description = path_description or filename
self.filename = filename
self.set_file_type_from_name(filename)
self._cmp_name = filename
......@@ -180,7 +181,7 @@ class FileSourceDescriptor(SourceDescriptor):
require_normalised_newlines=False)
def get_description(self):
return self.filename
return self.path_description
def get_filenametable_entry(self):
return self.filename
......@@ -199,6 +200,8 @@ class StringSourceDescriptor(SourceDescriptor):
Instances of this class can be used instead of a filenames if the
code originates from a string object.
"""
filename = None
def __init__(self, name, code):
self.name = name
#self.set_file_type_from_name(name)
......
......@@ -526,7 +526,7 @@ class Scope(object):
def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
# Add an entry for a Python function.
entry = self.lookup_here(name)
if not allow_redefine:
if not allow_redefine or Options.disable_function_redefinition:
return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
if entry:
if entry.type.is_unspecified:
......@@ -733,6 +733,13 @@ class BuiltinScope(Scope):
cname, type = definition
self.declare_var(name, type, None, cname)
def lookup(self, name, language_level=None):
# 'language_level' is passed by ModuleScope
if language_level == 3:
if name == 'str':
name = 'unicode'
return Scope.lookup(self, name)
def declare_builtin(self, name, pos):
if not hasattr(builtins, name):
if self.outer_scope is not None:
......@@ -882,6 +889,12 @@ class ModuleScope(Scope):
def global_scope(self):
return self
def lookup(self, name):
entry = self.lookup_here(name)
if entry is not None:
return entry
return self.outer_scope.lookup(name, language_level = self.context.language_level)
def declare_builtin(self, name, pos):
if not hasattr(builtins, name) and name != 'xrange':
# 'xrange' is special cased in Code.py
......@@ -1121,6 +1134,19 @@ class ModuleScope(Scope):
type.vtabslot_cname = "%s.%s" % (
Naming.obj_base_cname, type.base_type.vtabslot_cname)
elif type.scope and type.scope.cfunc_entries:
# one special case here: when inheriting from builtin
# types, the methods may also be built-in, in which
# case they won't need a vtable
entry_count = len(type.scope.cfunc_entries)
base_type = type.base_type
while base_type:
# FIXME: this will break if we ever get non-inherited C methods
if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
break
if base_type.is_builtin_type:
# builtin base type defines all methods => no vtable needed
return
base_type = base_type.base_type
#print "...allocating vtabslot_cname because there are C methods" ###
type.vtabslot_cname = Naming.vtabslot_cname
if type.vtabslot_cname:
......@@ -1535,9 +1561,8 @@ class CClassScope(ClassScope):
if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
error(pos, "Special method %s must be implemented via __richcmp__" % name)
if name == "__new__":
warning(pos, "__new__ method of extension type will change semantics "
error(pos, "__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead.")
name = EncodedString("__cinit__")
entry = self.declare_var(name, py_object_type, pos, visibility='extern')
special_sig = get_special_method_signature(name)
if special_sig:
......
......@@ -5,7 +5,7 @@
import re
from StringIO import StringIO
from Scanning import PyrexScanner, StringSourceDescriptor
from Symtab import BuiltinScope, ModuleScope
from Symtab import ModuleScope
import Symtab
import PyrexTypes
from Visitor import VisitorTransform
......
......@@ -226,6 +226,8 @@ class build_ext(_build_ext.build_ext):
if not self.inplace and (self.pyrex_c_in_temp
or getattr(extension, 'pyrex_c_in_temp', 0)):
target_dir = os.path.join(self.build_temp, "pyrex")
for package_name in extension.name.split('.')[:-1]:
target_dir = os.path.join(target_dir, package_name)
else:
target_dir = None
......
......@@ -49,9 +49,9 @@ cdef extern from "Python.h":
# 0 is returned on success and -1 on error.
void PyBuffer_Release(object obj, object view)
# Release the buffer view over obj. This should be called when the
# buffer is no longer being used as it may free memory from it.
void PyBuffer_Release(Py_buffer *view)
# Release the buffer view. This should be called when the buffer
# is no longer being used as it may free memory from it.
void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
# ??
......
__version__ = "0.14.rc0"
__version__ = "0.14+"
# Void cython.* directives (for case insensitive operating systems).
from Cython.Shadow import *
include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt
include COPYING.txt LICENSE.txt PKG-INFO Makefile
include COPYING.txt LICENSE.txt Makefile
include .hgrev
include setup.py
include setupegg.py
......@@ -15,16 +15,12 @@ include Demos/callback/*
include Demos/embed/*
include Demos/freeze/*
include Demos/libraries/*
include Demos/Setup.py
include Demos/Makefile*
recursive-include Tools *
recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt
recursive-include tests *_lib.cpp *.srctree
include runtests.py
include Cython/Mac/Makefile
include Cython/Mac/_Filemodule_patched.c
include Cython/Debugger/Tests/cfuncs.c
include Cython/Debugger/Tests/codefile
......
......@@ -112,6 +112,7 @@ def handle_special_build(modname, pyxfilename):
return ext, setup_args
def handle_dependencies(pyxfilename):
testing = '_test_files' in globals()
dependfile = os.path.splitext(pyxfilename)[0] + PYXDEP_EXT
# by default let distutils decide whether to rebuild on its own
......@@ -132,6 +133,7 @@ def handle_dependencies(pyxfilename):
files.extend(glob.glob(fullpath))
# only for unit testing to see we did the right thing
if testing:
_test_files[:] = [] #$pycheck_no
# if any file that the pyxfile depends upon is newer than
......@@ -143,6 +145,7 @@ def handle_dependencies(pyxfilename):
print("Rebuilding because of ", file)
filetime = os.path.getmtime(file)
os.utime(pyxfilename, (filetime, filetime))
if testing:
_test_files.append(file)
def build_module(name, pyxfilename, pyxbuild_dir=None):
......
import pyximport; pyximport.install()
import pyximport; pyximport.install(reload_support=True)
import os, sys
import time, shutil
import tempfile
......@@ -21,6 +21,7 @@ def on_remove_file_error(func, path, excinfo):
print "You may want to delete this yourself when you get a chance."
def test():
pyximport._test_files = []
tempdir = make_tempdir()
sys.path.append(tempdir)
filename = os.path.join(tempdir, "dummy.pyx")
......
......@@ -18,6 +18,7 @@ ipow_crash_T562
pure_mode_cmethod_inheritance_T583
genexpr_iterable_lookup_T600
for_from_pyvar_loop_T601
decorators_T593
# CPython regression tests that don't current work:
pyregr.test_threadsignals
......
......@@ -82,20 +82,26 @@ def ticket_338():
for obj from 0 <= obj < 4:
pass
def bare_pyvar_name(object x):
with nogil:
x
# For m(), the important thing is that there are errors on all lines in the range 23-69
# except these: 34, 44, 56, 58, 60, 62-64
# except these: 29, 34, 44, 56, 58, 60, 62-64
_ERRORS = u"""
1:5: Function with Python return type cannot be declared nogil
4:5: Function declared nogil has Python locals or temporaries
6:6: Assignment of Python object not allowed without gil
9:5: Discarding owned Python object not allowed without gil
11:5: Function with Python return type cannot be declared nogil
15:5: Calling gil-requiring function not allowed without gil
24:9: Calling gil-requiring function not allowed without gil
26:12: Assignment of Python object not allowed without gil
28:8: Discarding owned Python object not allowed without gil
28:16: Constructing complex number not allowed without gil
29:12: Accessing Python global or builtin not allowed without gil
30:8: Backquote expression not allowed without gil
30:8: Discarding owned Python object not allowed without gil
30:9: Operation not allowed without gil
31:15: Assignment of Python object not allowed without gil
31:15: Operation not allowed without gil
......@@ -105,20 +111,30 @@ _ERRORS = u"""
32:25: Constructing Python list not allowed without gil
32:25: Operation not allowed without gil
33:17: Iterating over Python object not allowed without gil
35:11: Discarding owned Python object not allowed without gil
35:11: Indexing Python object not allowed without gil
36:11: Discarding owned Python object not allowed without gil
36:11: Slicing Python object not allowed without gil
37:11: Constructing Python slice object not allowed without gil
37:11: Discarding owned Python object not allowed without gil
37:11: Indexing Python object not allowed without gil
37:13: Converting to Python object not allowed without gil
37:15: Converting to Python object not allowed without gil
37:17: Converting to Python object not allowed without gil
38:11: Accessing Python attribute not allowed without gil
39: 9: Constructing Python tuple not allowed without gil
40: 8: Constructing Python list not allowed without gil
41: 8: Constructing Python dict not allowed without gil
38:11: Discarding owned Python object not allowed without gil
39:9: Constructing Python tuple not allowed without gil
39:9: Discarding owned Python object not allowed without gil
40:8: Constructing Python list not allowed without gil
40:8: Discarding owned Python object not allowed without gil
41:8: Constructing Python dict not allowed without gil
41:8: Discarding owned Python object not allowed without gil
42:12: Discarding owned Python object not allowed without gil
42:12: Truth-testing Python object not allowed without gil
43:13: Python type test not allowed without gil
45:10: Discarding owned Python object not allowed without gil
45:10: Operation not allowed without gil
46:8: Discarding owned Python object not allowed without gil
46:8: Operation not allowed without gil
47:10: Assignment of Python object not allowed without gil
47:14: Assignment of Python object not allowed without gil
......
......@@ -58,18 +58,18 @@ _ERRORS = u"""
30:22: Cannot convert Unicode string to 'bytes' implicitly, encoding required.
31:22: Cannot convert 'str' to 'bytes' implicitly. This is not portable.
33:17: Cannot assign type 'char *' to 'str object'
33:17: Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.
34:19: Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.
35:17: Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.
36:19: Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.
38:20: str objects do not support coercion to unicode, use a unicode string literal instead (u'')
39:22: str objects do not support coercion to unicode, use a unicode string literal instead (u'')
40:20: Cannot assign type 'char *' to 'unicode object'
40:20: Cannot convert 'bytes' object to unicode implicitly, decoding required
41:22: Cannot convert 'bytes' object to unicode implicitly, decoding required
42:22: Cannot convert 'char*' to unicode implicitly, decoding required
44:19: Cannot assign type 'str object' to 'tuple object'
45:18: Cannot assign type 'unicode object' to 'tuple object'
46:18: Cannot assign type 'char *' to 'tuple object'
46:18: Cannot assign type 'bytes object' to 'tuple object'
"""
......@@ -8,6 +8,35 @@ cdef class MyInt(int):
"""
cdef readonly object attr
cdef class MyInt2(int):
"""
>>> MyInt2(2) == 2
True
>>> MyInt2(2).attr is None
True
>>> MyInt2(2).test(3)
5
"""
cdef readonly object attr
def test(self, arg):
return self._test(arg)
cdef _test(self, arg):
return self + arg
cdef class MyInt3(MyInt2):
"""
>>> MyInt3(2) == 2
True
>>> MyInt3(2).attr is None
True
>>> MyInt3(2).test(3)
6
"""
cdef _test(self, arg):
return self + arg + 1
cdef class MyFloat(float):
"""
>>> MyFloat(1.0)== 1.0
......@@ -23,6 +52,8 @@ cdef class MyUnicode(unicode):
"""
>>> MyUnicode(ustring) == ustring
True
>>> MyUnicode(ustring + ustring) == ustring
False
>>> MyUnicode(ustring).attr is None
True
"""
......@@ -37,6 +68,43 @@ cdef class MyList(list):
"""
cdef readonly object attr
cdef class MyListOverride(list):
"""
>>> MyListOverride([1,2,3]) == [1,2,3]
True
>>> l = MyListOverride([1,2,3])
>>> l.reverse()
>>> l
[1, 2, 3, 5]
>>> l._reverse()
>>> l
[1, 2, 3, 5, 5]
"""
# not doctested:
"""
>>> l = MyListOverride([1,2,3])
>>> l.append(8)
>>> l
[1, 2, 3, 0, 8]
>>> l._append(9)
>>> l
[1, 2, 3, 0, 8, 0, 9]
"""
def reverse(self):
self[:] = self + [5]
def _reverse(self):
self.reverse()
## FIXME: this doesn't currently work:
## cdef int append(self, value) except -1:
## self[:] = self + [0] + [value]
## return 0
## def _append(self, value):
## self.append(value)
cdef class MyDict(dict):
"""
>>> MyDict({1:2, 3:4}) == {1:2, 3:4}
......
__doc__ = u"""
>>> d = Defined()
>>> n = NotDefined()
Traceback (most recent call last):
NameError: name 'NotDefined' is not defined
"""
if True:
class Defined(object):
"""
>>> isinstance(Defined(), Defined)
True
"""
if False:
class NotDefined(object):
"""
>>> NotDefined() # fails when defined
"""
def test_class_cond(x):
"""
>>> Test, test = test_class_cond(True)
>>> test.A
1
>>> Test().A
1
>>> Test, test = test_class_cond(False)
>>> test.A
2
>>> Test().A
2
"""
if x:
class Test(object):
A = 1
else:
class Test(object):
A = 2
return Test, Test()
def test_func_cond(x):
"""
>>> func = test_func_cond(True)
>>> func()
1
>>> func = test_func_cond(False)
>>> func()
2
"""
if x:
def func():
return 1
else:
def func():
return 2
return func
......@@ -28,8 +28,8 @@ def test_pow(double complex z, double complex w, tol=None):
Various implementations produce slightly different results...
>>> a = complex(3, 1)
>>> test_pow(a, 1)
(3+1j)
>>> test_pow(a, 1, 1e-15)
True
>>> test_pow(a, 2, 1e-15)
True
>>> test_pow(a, a, 1e-15)
......@@ -48,7 +48,7 @@ def test_int_pow(double complex z, int n, tol=None):
[True, True, True, True, True, True, True, True, True]
>>> [test_int_pow(complex(0, 2), k, 1e-15) for k in range(-4, 5)]
[True, True, True, True, True, True, True, True, True]
>>> [test_int_pow(complex(2, 0.5), k, 1e-15) for k in range(0, 10)]
>>> [test_int_pow(complex(2, 0.5), k, 1e-14) for k in range(0, 10)]
[True, True, True, True, True, True, True, True, True, True]
"""
if tol is None:
......
......@@ -66,6 +66,19 @@ def unicode_literals():
print(isinstance(ustring, unicode) or type(ustring))
return ustring
def str_type_is_unicode():
"""
>>> str_type, s = str_type_is_unicode()
>>> isinstance(s, type(ustring)) or (s, str_type)
True
>>> isinstance(s, str_type) or (s, str_type)
True
>>> isinstance(ustring, str_type) or str_type
True
"""
cdef str s = 'abc'
return str, s
def list_comp():
"""
>>> list_comp()
......
"""
>>> am_i_buggy
False
>>> Foo
False
"""
def testme(func):
try:
am_i_buggy
return True
except NameError:
return False
@testme
def am_i_buggy():
pass
def testclass(klass):
try:
Foo
return True
except NameError:
return False
@testclass
class Foo:
pass
def called_deco(a,b,c):
def count(f):
a.append( (b,c) )
return f
return count
L = []
@called_deco(L, 5, c=6)
@called_deco(L, c=3, b=4)
@called_deco(L, 1, 2)
def wrapped_func(x):
"""
>>> L
[(1, 2), (4, 3), (5, 6)]
>>> wrapped_func(99)
99
>>> L
[(1, 2), (4, 3), (5, 6)]
"""
return x
def class_in_closure(x):
"""
>>> C1, c0 = class_in_closure(5)
>>> C1().smeth1()
(5, ())
>>> C1.smeth1(1,2)
(5, (1, 2))
>>> C1.smeth1()
(5, ())
>>> c0.smeth0()
1
>>> c0.__class__.smeth0()
1
"""
class ClosureClass1(object):
@staticmethod
def smeth1(*args):
return x, args
class ClosureClass0(object):
@staticmethod
def smeth0():
return 1
return ClosureClass1, ClosureClass0()
def class_not_in_closure():
"""
>>> c = class_not_in_closure()
>>> c.smeth0()
1
>>> c.__class__.smeth0()
1
"""
class ClosureClass0(object):
@staticmethod
def smeth0():
return 1
return ClosureClass0()
class ODict(dict):
def __init__(self):
dict.__init__(self)
self._order = []
dict.__setitem__(self, '_order', self._order)
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
self._order.append(key)
class Base(type):
@staticmethod
def __prepare__(*args, **kwargs):
return ODict()
class Bar(metaclass=Base):
"""
>>> Bar._order
['__module__', '__doc__', 'bar']
"""
@property
def bar(self):
return 0
"""
>>> a = A()
>>> a.f()
[2, 1]
>>> a.g()
(False, True)
>>> del_item({1: 'a', 2: 'b'}, 1)
{2: 'b'}
>>> del_item(list(range(10)), 2)
[0, 1, 3, 4, 5, 6, 7, 8, 9]
>>> del_dict({1: 'a', 2: 'b'}, 1)
{2: 'b'}
>>> del_list(list(range(5)), 3)
[0, 1, 2, 4]
>>> del_int(list(range(5)), 3)
[0, 1, 2, 4]
>>> del_list_int(list(range(5)), 3)
[0, 1, 2, 4]
>>> del_int({-1: 'neg', 1: 'pos'}, -1)
{1: 'pos'}
"""
class A:
class A(object):
"""
>>> a = A()
>>> a.f()
[2, 1]
>>> a.g()
(False, True)
"""
def f(self):
self.refs = [3,2,1]
del self.refs[0]
......@@ -33,21 +18,65 @@ class A:
return (hasattr(self, u"a"), hasattr(self, u"g"))
def del_item(L, o):
"""
>>> del_item({1: 'a', 2: 'b'}, 1)
{2: 'b'}
>>> del_item(list(range(10)), 2)
[0, 1, 3, 4, 5, 6, 7, 8, 9]
"""
del L[o]
return L
def del_dict(dict D, o):
"""
>>> del_dict({1: 'a', 2: 'b'}, 1)
{2: 'b'}
"""
del D[o]
return D
def del_list(list L, o):
"""
>>> del_list(list(range(5)), 3)
[0, 1, 2, 4]
"""
del L[o]
return L
def del_int(L, int i):
"""
>>> del_int(list(range(5)), 3)
[0, 1, 2, 4]
>>> del_int({-1: 'neg', 1: 'pos'}, -1)
{1: 'pos'}
"""
del L[i]
return L
def del_list_int(L, int i):
"""
>>> del_list_int(list(range(5)), 3)
[0, 1, 2, 4]
"""
del L[i]
return L
def del_temp_slice(a):
"""
>>> class A(object):
... attr = [1,2,3]
>>> a = A()
>>> a.attr
[1, 2, 3]
>>> del_temp_slice(a)
[]
>>> a.attr
[]
>>> del_temp_slice(a)
[]
>>> a.attr
[]
"""
while a.attr:
del a.attr[:]
return a.attr
......@@ -48,6 +48,11 @@ def test_optimised():
assert isinstance(complex(), complex)
assert not isinstance(u"foo", int)
assert isinstance(A, type)
assert isinstance(A(), A)
cdef type typed_type = A
assert isinstance(A(), typed_type)
cdef object untyped_type = A
assert isinstance(A(), <type>untyped_type)
return True
@cython.test_assert_path_exists('//PythonCapiCallNode')
......@@ -59,13 +64,11 @@ def test_optimised_tuple():
>>> test_optimised_tuple()
True
"""
assert isinstance(int(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice))
assert isinstance(list(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice))
assert isinstance(int(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A))
assert isinstance(list(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A))
assert isinstance(A(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A))
return True
@cython.test_assert_path_exists('//SimpleCallNode//SimpleCallNode')
@cython.test_fail_if_path_exists('//SimpleCallNode//PythonCapiCallNode',
'//PythonCapiCallNode//SimpleCallNode')
def test_custom():
"""
>>> test_custom()
......
cdef class Owner:
cdef object x
cdef call_me_with_owner(Owner owner, x):
owner.x = "def" # overwrite external reference
return x # crashes if x is not owned by function or caller
def test_ext_type_attr():
"""
>>> test_ext_type_attr()
'abc5'
"""
owner = Owner()
owner.x = ''.join("abc%d" % 5) # non-interned object
return call_me_with_owner(owner, owner.x)
cdef void call_me_without_gil(Owner owner, x) with gil:
owner.x = "def" # overwrite external reference
print x # crashes if x is not owned by function or caller
def test_ext_type_attr_nogil():
"""
>>> test_ext_type_attr_nogil()
abc5
"""
owner = Owner()
owner.x = ''.join("abc%d" % 5) # non-interned object
with nogil:
call_me_without_gil(owner, owner.x)
# the following isn't dangerous as long as index access uses temps
cdef call_me_with_list(list l, x):
l[:] = [(1,2), (3,4)] # overwrite external reference
return x # crashes if x is not owned by function or caller
def test_index():
"""
>>> test_index()
[3, 4]
"""
l = [[1,2],[3,4]]
return call_me_with_list(l, l[1])
......@@ -25,7 +25,7 @@ def simple():
xptrptr = &xptr
assert typeof(xptrptr) == "double **", typeof(xptrptr)
b = b"abc"
assert typeof(b) == "char *", typeof(b)
assert typeof(b) == "bytes object", typeof(b)
s = "abc"
assert typeof(s) == "str object", typeof(s)
u = u"xyz"
......@@ -57,7 +57,7 @@ def slicing():
>>> slicing()
"""
b = b"abc"
assert typeof(b) == "char *", typeof(b)
assert typeof(b) == "bytes object", typeof(b)
b1 = b[1:2]
assert typeof(b1) == "bytes object", typeof(b1)
b2 = b[1:2:2]
......@@ -92,9 +92,9 @@ def indexing():
>>> indexing()
"""
b = b"abc"
assert typeof(b) == "char *", typeof(b)
assert typeof(b) == "bytes object", typeof(b)
b1 = b[1]
assert typeof(b1) == "char", typeof(b1) # FIXME: Python object ??
assert typeof(b1) == "Python object", typeof(b1)
u = u"xyz"
assert typeof(u) == "unicode object", typeof(u)
u1 = u[1]
......@@ -479,3 +479,10 @@ def large_literals():
c, d = 10, 100000000000000000000000000000000
assert typeof(c) == "long", typeof(c)
assert typeof(d) == "Python object", typeof(d)
# Regression test for trac #638.
def bar(foo):
qux = foo
quux = foo[qux.baz]
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