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

Merge.

Had to move some changes made in ModuleNode.py over to Code.py manually.
parents 18ba3a48 9262420f
......@@ -29,8 +29,6 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
self.max_ndim = 0
result = super(IntroduceBufferAuxiliaryVars, self).__call__(node)
if self.buffers_exists:
if "endian.h" not in node.scope.include_files:
node.scope.include_files.append("endian.h")
use_py2_buffer_functions(node.scope)
use_empty_bufstruct_code(node.scope, self.max_ndim)
return result
......@@ -590,18 +588,20 @@ static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts) {
}
static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts) {
int num = 1;
int little_endian = ((char*)&num)[0];
int ok = 1;
switch (*ts) {
case '@':
case '=':
++ts; break;
case '<':
if (__BYTE_ORDER == __LITTLE_ENDIAN) ++ts;
if (little_endian) ++ts;
else ok = 0;
break;
case '>':
case '!':
if (__BYTE_ORDER == __BIG_ENDIAN) ++ts;
if (!little_endian) ++ts;
else ok = 0;
break;
}
......
......@@ -189,7 +189,7 @@ class GlobalState(object):
# This is called when it is known that no more global declarations will
# declared (but can be called before or after insert_XXX).
if self.pystring_table_needed:
self.pystring_table.putln("{0, 0, 0, 0, 0}").putln("};")
self.pystring_table.putln("{0, 0, 0, 0, 0, 0}").putln("};")
import Nodes
self.use_utility_code(Nodes.init_string_tab_utility_code)
self.initwriter.putln(
......@@ -254,17 +254,23 @@ class GlobalState(object):
def add_interned_num_decl(self, entry):
if self.should_declare(entry.cname, entry):
self.initwriter.putln("%s = PyInt_FromLong(%s); %s;" % (
entry.cname,
entry.init,
self.initwriter.error_goto_if_null(entry.cname, self.module_pos))) # todo: fix pos
if entry.init[-1] == "L":
self.initwriter.putln('%s = PyLong_FromString("%s", 0, 0); %s;' % (
entry.cname,
entry.init,
self.initwriter.error_goto_if_null(entry.cname, self.module_pos)))
else:
self.initwriter.putln("%s = PyInt_FromLong(%s); %s;" % (
entry.cname,
entry.init,
self.initwriter.error_goto_if_null(entry.cname, self.module_pos)))
self.put_pyobject_decl(entry)
def add_cached_builtin_decl(self, entry):
if self.should_declare(entry.cname, entry):
self.put_pyobject_decl(entry)
#
# File name state
#
......
......@@ -628,7 +628,7 @@ class BoolNode(ConstNode):
return self.value
def calculate_result_code(self):
return int(self.value)
return str(int(self.value))
class NullNode(ConstNode):
type = PyrexTypes.c_null_ptr_type
......@@ -646,13 +646,19 @@ class CharNode(ConstNode):
class IntNode(ConstNode):
# unsigned "" or "U"
# longness "" or "L" or "LL"
unsigned = ""
longness = ""
type = PyrexTypes.c_long_type
def coerce_to(self, dst_type, env):
# Arrange for a Python version of the string to be pre-allocated
# when coercing to a Python type.
if dst_type.is_pyobject:
self.entry = env.get_py_num(self.value)
self.entry = env.get_py_num(self.value, self.longness)
self.type = PyrexTypes.py_object_type
# We still need to perform normal coerce_to processing on the
# result, because we might be coercing to an extension type,
......@@ -663,7 +669,7 @@ class IntNode(ConstNode):
if self.type.is_pyobject:
return self.entry.cname
else:
return str(self.value)
return str(self.value) + self.unsigned + self.longness
def compile_time_value(self, denv):
return int(self.value, 0)
......@@ -1674,6 +1680,7 @@ class SimpleCallNode(CallNode):
# self ExprNode or None used internally
# coerced_self ExprNode or None used internally
# wrapper_call bool used internally
# has_optional_args bool used internally
subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
......@@ -1681,6 +1688,7 @@ class SimpleCallNode(CallNode):
coerced_self = None
arg_tuple = None
wrapper_call = False
has_optional_args = False
def compile_time_value(self, denv):
function = self.function.compile_time_value(denv)
......@@ -1767,6 +1775,11 @@ class SimpleCallNode(CallNode):
self.type = PyrexTypes.error_type
self.result_code = "<error>"
return
if func_type.optional_arg_count and expected_nargs != actual_nargs:
self.has_optional_args = 1
self.is_temp = 1
self.opt_arg_struct = env.allocate_temp(func_type.op_arg_struct.base_type)
env.release_temp(self.opt_arg_struct)
# Coerce arguments
for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type
......@@ -1812,15 +1825,7 @@ class SimpleCallNode(CallNode):
if expected_nargs == actual_nargs:
optional_args = 'NULL'
else:
optional_arg_code = [str(actual_nargs - expected_nargs)]
for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
arg_code = actual_arg.result_as(formal_arg.type)
optional_arg_code.append(arg_code)
# for formal_arg in formal_args[actual_nargs:max_nargs]:
# optional_arg_code.append(formal_arg.type.cast_code('0'))
optional_arg_struct = '{%s}' % ','.join(optional_arg_code)
optional_args = PyrexTypes.c_void_ptr_type.cast_code(
'&' + func_type.op_arg_struct.base_type.cast_code(optional_arg_struct))
optional_args = "&%s" % self.opt_arg_struct
arg_list_code.append(optional_args)
for actual_arg in self.args[len(formal_args):]:
......@@ -1843,6 +1848,19 @@ class SimpleCallNode(CallNode):
arg_code,
code.error_goto_if_null(self.result_code, self.pos)))
elif func_type.is_cfunction:
if self.has_optional_args:
actual_nargs = len(self.args)
expected_nargs = len(func_type.args) - func_type.optional_arg_count
code.putln("%s.%s = %s;" % (
self.opt_arg_struct,
Naming.pyrex_prefix + "n",
len(self.args) - expected_nargs))
args = zip(func_type.args, self.args)
for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
code.putln("%s.%s = %s;" % (
self.opt_arg_struct,
formal_arg.name,
actual_arg.result_as(formal_arg.type)))
exc_checks = []
if self.type.is_pyobject:
exc_checks.append("!%s" % self.result_code)
......@@ -1877,12 +1895,12 @@ class SimpleCallNode(CallNode):
rhs,
raise_py_exception,
code.error_goto(self.pos)))
return
code.putln(
"%s%s; %s" % (
lhs,
rhs,
code.error_goto_if(" && ".join(exc_checks), self.pos)))
else:
if exc_checks:
goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
else:
goto_error = ""
code.putln("%s%s; %s" % (lhs, rhs, goto_error))
class GeneralCallNode(CallNode):
# General Python function call, including keyword,
......@@ -2945,6 +2963,7 @@ class TypecastNode(ExprNode):
self.operand = self.operand.coerce_to_pyobject(env)
else:
warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
self.operand = self.operand.coerce_to_simple(env)
elif from_py and not to_py:
if self.type.from_py_function:
self.operand = self.operand.coerce_to(self.type, env)
......
......@@ -27,7 +27,8 @@ def make_lexicon():
name = letter + Rep(letter | digit)
intconst = decimal | (Str("0x") + Rep1(hexdigit))
longconst = intconst + Str("L")
intsuffix = (Opt(Any("Uu")) + Opt(Any("Ll")) + Opt(Any("Ll"))) | (Opt(Any("Ll")) + Opt(Any("Ll")) + Opt(Any("Uu")))
intliteral = intconst + intsuffix
fltconst = (decimal_fract + Opt(exponent)) | (decimal + exponent)
imagconst = (intconst | fltconst) + Any("jJ")
......@@ -79,8 +80,7 @@ def make_lexicon():
return Lexicon([
(name, 'IDENT'),
(intconst, 'INT'),
(longconst, 'LONG'),
(intliteral, 'INT'),
(fltconst, 'FLOAT'),
(imagconst, 'IMAG'),
(deco, 'DECORATOR'),
......
......@@ -842,8 +842,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#if need_self_cast:
# self.generate_self_cast(scope, code)
if type.vtabslot_cname:
if base_type:
struct_type_cast = "(struct %s*)" % base_type.vtabstruct_cname
vtab_base_type = type
while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
vtab_base_type = vtab_base_type.base_type
if vtab_base_type is not type:
struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
else:
struct_type_cast = ""
code.putln("p->%s = %s%s;" % (
......
......@@ -350,8 +350,13 @@ class CNameDeclaratorNode(CDeclaratorNode):
def analyse(self, base_type, env, nonempty = 0):
if nonempty and self.name == '':
# Must have mistaken the name for the type.
self.name = base_type.name
raise RuntimeError
# May have mistaken the name for the type.
if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
error(self.pos, "Missing argument name.")
elif base_type.is_void:
error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
self.name = base_type.declaration_code("", for_display=1, pyrex=1)
base_type = py_object_type
self.type = base_type
return self, base_type
......@@ -412,7 +417,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
def analyse(self, return_type, env, nonempty = 0):
func_type_args = []
for arg_node in self.args:
name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
name_declarator, type = arg_node.analyse(env)
name = name_declarator.name
if name_declarator.cname:
error(self.pos,
......@@ -612,13 +617,28 @@ class CVarDefNode(StatNode):
# declarators [CDeclaratorNode]
# in_pxd boolean
# api boolean
# need_properties [entry]
child_attrs = ["base_type", "declarators"]
need_properties = ()
def analyse_declarations(self, env, dest_scope = None):
if not dest_scope:
dest_scope = env
self.dest_scope = dest_scope
base_type = self.base_type.analyse(env)
if (dest_scope.is_c_class_scope
and self.visibility == 'public'
and base_type.is_pyobject
and (base_type.is_builtin_type or base_type.is_extension_type)):
self.need_properties = []
need_property = True
visibility = 'private'
else:
need_property = False
visibility = self.visibility
for declarator in self.declarators:
name_declarator, type = declarator.analyse(base_type, env)
if not type.is_complete():
......@@ -641,8 +661,11 @@ class CVarDefNode(StatNode):
if self.in_pxd and self.visibility != 'extern':
error(self.pos,
"Only 'extern' C variable declaration allowed in .pxd file")
dest_scope.declare_var(name, type, declarator.pos,
cname = cname, visibility = self.visibility, is_cdef = 1)
entry = dest_scope.declare_var(name, type, declarator.pos,
cname = cname, visibility = visibility, is_cdef = 1)
if need_property:
self.need_properties.append(entry)
entry.needs_property = 1
class CStructOrUnionDefNode(StatNode):
......@@ -951,7 +974,7 @@ class FuncDefNode(StatNode, BlockNode):
self.put_stararg_decrefs(code)
if acquire_gil:
code.putln("PyGILState_Release(_save);")
code.putln("/* TODO: decref scope object */")
# code.putln("/* TODO: decref scope object */")
# ----- Return
if not self.return_type.is_void:
code.putln("return %s;" % Naming.retval_cname)
......@@ -1532,6 +1555,10 @@ class DefNode(FuncDefNode):
def generate_argument_parsing_code(self, env, code):
# Generate PyArg_ParseTuple call for generic
# arguments, if any.
if self.entry.signature.has_dummy_arg:
# get rid of unused argument warning
code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
old_error_label = code.new_error_label()
our_error_label = code.error_label
end_label = code.new_label()
......@@ -2084,6 +2111,15 @@ class CClassDefNode(ClassDefNode):
if self.doc and Options.docstrings:
scope.doc = embed_position(self.pos, self.doc)
if has_body and not self.in_pxd:
# transforms not yet run on pxd files
from ParseTreeTransforms import AnalyseDeclarationsTransform
transform = AnalyseDeclarationsTransform(None)
for entry in scope.var_entries:
if hasattr(entry, 'needs_property'):
property = transform.create_Property(entry)
self.body.stats.append(property)
if has_body:
self.body.analyse_declarations(scope)
......
......@@ -342,6 +342,14 @@ class DecoratorTransform(CythonTransform):
class AnalyseDeclarationsTransform(CythonTransform):
basic_property = TreeFragment(u"""
property NAME:
def __get__(self):
return ATTR
def __set__(self, value):
ATTR = value
""", level='c_class')
def __call__(self, root):
self.env_stack = [root.scope]
return super(AnalyseDeclarationsTransform, self).__call__(root)
......@@ -366,7 +374,28 @@ class AnalyseDeclarationsTransform(CythonTransform):
# on these nodes in a seperate recursive process from the
# enclosing function or module, so we can simply drop them.
def visit_CVarDefNode(self, node):
return None
if node.need_properties:
# cdef public attributes may need type testing on
# assignment, so we create a property accesss
# mechanism for them.
stats = []
for entry in node.need_properties:
property = self.create_Property(entry)
property.analyse_declarations(node.dest_scope)
self.visit(property)
stats.append(property)
return StatListNode(pos=node.pos, stats=stats)
else:
return None
def create_Property(self, entry):
property = self.basic_property.substitute({
u"ATTR": AttributeNode(pos=entry.pos,
obj=NameNode(pos=entry.pos, name="self"),
attribute=entry.name),
}, pos=entry.pos).stats[0]
property.name = entry.name
return property
class AnalyseExpressionsTransform(CythonTransform):
def visit_ModuleNode(self, node):
......
......@@ -466,11 +466,18 @@ def p_atom(s):
elif sy == 'INT':
value = s.systring
s.next()
return ExprNodes.IntNode(pos, value = value)
elif sy == 'LONG':
value = s.systring
s.next()
return ExprNodes.LongNode(pos, value = value)
unsigned = ""
longness = ""
while value[-1] in "UuLl":
if value[-1] in "Ll":
longness += "L"
else:
unsigned += "U"
value = value[:-1]
return ExprNodes.IntNode(pos,
value = value,
unsigned = unsigned,
longness = longness)
elif sy == 'FLOAT':
value = s.systring
s.next()
......@@ -516,7 +523,7 @@ def p_name(s, name):
elif isinstance(value, int):
return ExprNodes.IntNode(pos, value = rep)
elif isinstance(value, long):
return ExprNodes.LongNode(pos, value = rep)
return ExprNodes.IntNode(pos, value = rep, longness = "L")
elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value = rep)
elif isinstance(value, unicode):
......@@ -2292,6 +2299,15 @@ def p_doc_string(s):
return result
else:
return None
def p_code(s, level=None):
s.add_type_name("object")
s.add_type_name("Py_buffer")
body = p_statement_list(s, Ctx(level = level), first_statement = 1)
if s.sy != 'EOF':
s.error("Syntax error in statement [%s,%s]" % (
repr(s.sy), repr(s.systring)))
return body
def p_module(s, pxd, full_module_name):
s.add_type_name("object")
......
......@@ -262,7 +262,7 @@ class Scope:
# Return the module-level scope containing this scope.
return self.outer_scope.builtin_scope()
def declare(self, name, cname, type, pos):
def declare(self, name, cname, type, pos, visibility):
# Create new entry, and add to dictionary if
# name is not None. Reports a warning if already
# declared.
......@@ -271,13 +271,17 @@ class Scope:
warning(pos, "'%s' is a reserved name in C." % cname, -1)
dict = self.entries
if name and dict.has_key(name):
warning(pos, "'%s' redeclared " % name, 0)
if visibility == 'extern':
warning(pos, "'%s' redeclared " % name, 0)
else:
error(pos, "'%s' redeclared " % name)
entry = Entry(name, cname, type, pos = pos)
entry.in_cinclude = self.in_cinclude
if name:
entry.qualified_name = self.qualify_name(name)
dict[name] = entry
entry.scope = self
entry.visibility = visibility
return entry
def qualify_name(self, name):
......@@ -290,7 +294,7 @@ class Scope:
cname = name
else:
cname = self.mangle(Naming.enum_prefix, name)
entry = self.declare(name, cname, type, pos)
entry = self.declare(name, cname, type, pos, 'private')
entry.is_const = 1
entry.value = value
return entry
......@@ -300,8 +304,7 @@ class Scope:
# Add an entry for a type definition.
if not cname:
cname = name
entry = self.declare(name, cname, type, pos)
entry.visibility = visibility
entry = self.declare(name, cname, type, pos, visibility)
entry.is_type = 1
if defining:
self.type_entries.append(entry)
......@@ -385,9 +388,8 @@ class Scope:
cname = name
else:
cname = self.mangle(Naming.var_prefix, name)
entry = self.declare(name, cname, type, pos)
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
entry.visibility = visibility
self.control_flow.set_state((), (name, 'initalized'), False)
return entry
......@@ -400,7 +402,7 @@ class Scope:
if entry and not entry.type.is_cfunction:
# This is legal Python, but for now will produce invalid C.
error(pos, "'%s' already declared" % name)
entry = self.declare_var(name, py_object_type, pos)
entry = self.declare_var(name, py_object_type, pos, visibility='extern')
entry.signature = pyfunction_signature
self.pyfunc_entries.append(entry)
return entry
......@@ -416,8 +418,11 @@ class Scope:
if visibility != 'private' and visibility != entry.visibility:
warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
if not entry.type.same_as(type):
warning(pos, "Function signature does not match previous declaration", 1)
entry.type = type
if visibility == 'extern' and entry.visibility == 'extern':
warning(pos, "Function signature does not match previous declaration", 1)
entry.type = type
else:
error(pos, "Function signature does not match previous declaration")
else:
if not cname:
if api or visibility != 'private':
......@@ -436,9 +441,8 @@ class Scope:
def add_cfunction(self, name, type, pos, cname, visibility):
# Add a C function entry without giving it a func_cname.
entry = self.declare(name, cname, type, pos)
entry = self.declare(name, cname, type, pos, visibility)
entry.is_cfunction = 1
entry.visibility = visibility
self.cfunc_entries.append(entry)
return entry
......@@ -549,9 +553,11 @@ class Scope:
self.interned_nums.append(entry)
return entry
def get_py_num(self, value):
def get_py_num(self, value, longness):
# Get entry for int constant. Returns an existing
# one if possible, otherwise creates a new one.
if longness or Utils.long_literal(value):
value += "L"
genv = self.global_scope()
entry = genv.num_to_entry.get(value)
if not entry:
......@@ -644,7 +650,7 @@ class PreImportScope(Scope):
Scope.__init__(self, Options.pre_import, None, None)
def declare_builtin(self, name, pos):
entry = self.declare(name, name, py_object_type, pos)
entry = self.declare(name, name, py_object_type, pos, 'private')
entry.is_variable = True
entry.is_pyglobal = True
return entry
......@@ -814,7 +820,7 @@ class ModuleScope(Scope):
for entry in self.cached_builtins:
if entry.name == name:
return entry
entry = self.declare(None, None, py_object_type, pos)
entry = self.declare(None, None, py_object_type, pos, 'private')
if Options.cache_builtins:
entry.is_builtin = 1
entry.is_const = 1
......@@ -1114,7 +1120,7 @@ class LocalScope(Scope):
def declare_arg(self, name, type, pos):
# Add an entry for an argument of a function.
cname = self.mangle(Naming.var_prefix, name)
entry = self.declare(name, cname, type, pos)
entry = self.declare(name, cname, type, pos, 'private')
entry.is_variable = 1
if type.is_pyobject:
entry.init = "0"
......@@ -1187,7 +1193,7 @@ class StructOrUnionScope(Scope):
cname = name
if type.is_cfunction:
type = PyrexTypes.CPtrType(type)
entry = self.declare(name, cname, type, pos)
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
self.var_entries.append(entry)
if type.is_pyobject and not allow_pyobject:
......@@ -1319,8 +1325,7 @@ class CClassScope(ClassScope):
% name)
if not cname:
cname = name
entry = self.declare(name, cname, type, pos)
entry.visibility = visibility
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
self.var_entries.append(entry)
if type.is_pyobject:
......@@ -1361,7 +1366,7 @@ class CClassScope(ClassScope):
warning(pos, "__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead.")
name = Utils.EncodedString("__cinit__")
entry = self.declare_var(name, py_object_type, pos)
entry = self.declare_var(name, py_object_type, pos, visibility='extern')
special_sig = get_special_method_signature(name)
if special_sig:
# Special methods get put in the method table with a particular
......@@ -1436,7 +1441,9 @@ class CClassScope(ClassScope):
return entry
def declare_property(self, name, doc, pos):
entry = self.declare(name, name, py_object_type, pos)
entry = self.lookup_here(name)
if entry is None:
entry = self.declare(name, name, py_object_type, pos, 'private')
entry.is_property = 1
entry.doc = doc
entry.scope = PropertyScope(name,
......@@ -1454,7 +1461,7 @@ class CClassScope(ClassScope):
for base_entry in \
base_scope.inherited_var_entries + base_scope.var_entries:
entry = self.declare(base_entry.name, adapt(base_entry.cname),
base_entry.type, None)
base_entry.type, None, 'private')
entry.is_variable = 1
self.inherited_var_entries.append(entry)
for base_entry in base_scope.cfunc_entries:
......@@ -1479,7 +1486,7 @@ class PropertyScope(Scope):
# Add an entry for a method.
signature = get_property_accessor_signature(name)
if signature:
entry = self.declare(name, name, py_object_type, pos)
entry = self.declare(name, name, py_object_type, pos, 'private')
entry.is_special = 1
entry.signature = signature
return entry
......
......@@ -28,7 +28,7 @@ class StringParseContext(Main.Context):
raise AssertionError("Not yet supporting any cimports/includes from string code snippets")
return ModuleScope(module_name, parent_module = None, context = self)
def parse_from_strings(name, code, pxds={}):
def parse_from_strings(name, code, pxds={}, level=None):
"""
Utility method to parse a (unicode) string of code. This is mostly
used for internal Cython compiler purposes (creating code snippets
......@@ -56,7 +56,10 @@ def parse_from_strings(name, code, pxds={}):
scanner = PyrexScanner(buf, code_source, source_encoding = encoding,
scope = scope, context = context)
tree = Parsing.p_module(scanner, 0, module_name)
if level is None:
tree = Parsing.p_module(scanner, 0, module_name)
else:
tree = Parsing.p_code(scanner, level=level)
return tree
class TreeCopier(VisitorTransform):
......@@ -171,7 +174,7 @@ def strip_common_indent(lines):
return lines
class TreeFragment(object):
def __init__(self, code, name="(tree fragment)", pxds={}, temps=[], pipeline=[]):
def __init__(self, code, name="(tree fragment)", pxds={}, temps=[], pipeline=[], level=None):
if isinstance(code, unicode):
def fmt(x): return u"\n".join(strip_common_indent(x.split(u"\n")))
......@@ -180,9 +183,9 @@ class TreeFragment(object):
for key, value in pxds.iteritems():
fmt_pxds[key] = fmt(value)
t = parse_from_strings(name, fmt_code, fmt_pxds)
mod = t
t = t.body # Make sure a StatListNode is at the top
mod = t = parse_from_strings(name, fmt_code, fmt_pxds, level=level)
if level is None:
t = t.body # Make sure a StatListNode is at the top
if not isinstance(t, StatListNode):
t = StatListNode(pos=mod.pos, stats=[t])
for transform in pipeline:
......
......@@ -115,3 +115,15 @@ def escape_byte_string(s):
else:
append(c)
return ''.join(l)
def long_literal(value):
if isinstance(value, basestring):
if len(value) < 2:
value = int(value)
elif value[0] == 0:
value = int(value, 8)
elif value[1] in 'xX':
value = int(value[2:], 16)
else:
value = int(value)
return not -2**31 <= value < 2**31
......@@ -7,7 +7,6 @@ from Cython.Distutils import build_ext
ext_modules=[
Extension("primes", ["primes.pyx"]),
Extension("spam", ["spam.pyx"]),
# Extension("optargs", ["optargs.pyx"], language = "c++"),
]
for file in glob.glob("*.pyx"):
......
PYTHON?=python
all: local
local:
${PYTHON} setup.py build_ext --inplace
clean:
@echo Cleaning Source
@rm -fr build
@rm -f *.pyc */*.pyc */*/*.pyc
@rm -f *~ */*~ */*/*~
@rm -f core */core
@rm -f Cython/Plex/Scanners.{so,pyd}
@(cd Demos; $(MAKE) clean)
testclean:
......
@REM Start cython from windows commandline as "cython", not "cython.py".
@REM This is especially useful for windows power shell, as no extra window
@REM is used.
@echo OFF
python -c "from Cython.Compiler.Main import main; main(command_line = 1)" %*
......@@ -296,7 +296,18 @@ def collect_unittests(path, module_prefix, suite, selectors):
loader = unittest.TestLoader()
skipped_dirs = []
for dirpath, dirnames, filenames in os.walk(path):
if dirpath != path and "__init__.py" not in filenames:
skipped_dirs.append(dirpath + os.path.sep)
continue
skip = False
for dir in skipped_dirs:
if dirpath.startswith(dir):
skip = True
if skip:
continue
parentname = os.path.split(dirpath)[-1]
if package_matches(parentname):
for f in filenames:
......@@ -332,7 +343,7 @@ def collect_doctests(path, module_prefix, suite, selectors):
module = getattr(module, x)
if hasattr(module, "__doc__") or hasattr(module, "__test__"):
try:
suite.addTests(doctest.DocTestSuite(module))
suite.addTest(doctest.DocTestSuite(module))
except ValueError: # no tests
pass
......
......@@ -14,8 +14,8 @@ if sys.version_info < (2,4):
cython_dir = os.path.join(get_python_lib(prefix=''), 'Cython')
compiler_dir = os.path.join(cython_dir, 'Compiler')
setup_args['data_files'] = [
{compiler_dir : ['Cython/Compiler/Lexicon.pickle'],
cython_dir : ['Cython/Includes/*.pxd']}]
(compiler_dir, ['Cython/Compiler/Lexicon.pickle']),
(cython_dir, ['Cython/Includes/*.pxd'])]
else:
setup_args['package_data'] = {'Cython.Compiler' : ['Lexicon.pickle'],
'Cython' : ['Includes/*.pxd']}
......
def f(obj, int i, float f, char *s1, char s2[]):
pass
\ No newline at end of file
cdef g(obj, int i, float f, char *s1, char s2[]):
pass
cdef do_g(object (*func)(object, int, float, char*, char*)):
return func(1, 2, 3.14159, "a", "b")
do_g(&g)
......@@ -4,4 +4,4 @@ cdef class Sub2(Crunchy):
cdef char character
cdef class Sub1(Sub2):
cdef char character
pass
cdef class Spam:
cdef public Spam e
_ERRORS = u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_extmember.pyx:2:18: Non-generic Python attribute cannot be exposed for writing from Python
"""
__doc__ = u"""
>>> e = ExtClass()
>>> e.get()
5
"""
cdef class ExtClass:
cdef int _attribute = 2
def get(self):
return self._attribute
_attribute = 5 # FIXME: this is not currently handled!!!
_ERRORS = u"""
8:13: Cannot assign default value to cdef class attributes
"""
......@@ -86,7 +86,6 @@ _ERRORS = u"""
15: 5: Calling gil-requiring function without gil
24: 9: Calling gil-requiring function without gil
26:12: Assignment of Python object not allowed without gil
27: 8: Constructing Python long int not allowed without gil
28: 8: 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
......
"""
>>> call_test()
False
True
False
True
True
True
True
"""
cdef test(bint value):
print value
def call_test():
test(False)
test(True)
test(0)
test(234)
test(-1)
x = True
test(x)
x = 3242
test(x)
__doc__ = u"""
>>> test_c(u'abc')
fileabc
typeabc
>>> print test_file_py(u'abc')
abc
>>> print range(u'abc')
rangeabc
"""
def test_file_py(file):
return file
cdef test_file_c(file):
return u'file' + file
def range(arg):
return u'range' + arg
cdef type(arg):
return u'type' + arg
def test_c(arg):
print test_file_c(arg)
print type(arg)
......@@ -2,6 +2,11 @@ __doc__ = u"""
>>> call2()
>>> call3()
>>> call4()
>>> test_foo()
2
3
7
26
"""
# the calls:
......@@ -19,3 +24,13 @@ def call4():
cdef b(a, b, c=1, d=2):
pass
cdef int foo(int a, int b=1, int c=1):
return a+b*c
def test_foo():
print foo(1)
print foo(1, 2)
print foo(1, 2, 3)
print foo(1, foo(2, 3), foo(4))
__doc__ = """
>>> s = Spam()
>>> s.e = s
>>> s.e = 1
Traceback (most recent call last):
TypeError: Cannot convert int to extmember.Spam
>>> s.e is s
True
>>> s.e = None
"""
cdef class Spam:
cdef public Spam e
__doc__ = """
>>> c_longs()
(1, 1L, -1L, 18446744073709551615L)
>>> py_longs()
(1, 1L, 100000000000000000000000000000000L, -100000000000000000000000000000000L)
"""
def c_longs():
cdef long a = 1L
cdef unsigned long ua = 1UL
cdef long long aa = 0xFFFFFFFFFFFFFFFFLL
cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL
return a, ua, aa, uaa
def py_longs():
return 1, 1L, 100000000000000000000000000000000, -100000000000000000000000000000000
......@@ -34,9 +34,9 @@ def h(i):
return 5 ** i
def constant_py():
result = 2L ** 10
result = (<object>2) ** 10
return result
def constant_long():
result = 2L ** 36
result = (<object>2L) ** 36
return result
......@@ -29,4 +29,4 @@ cdef class Sub2(list):
cdef char character
cdef class Sub1(Sub2):
cdef char character
pass
__doc__ = u"""
>>> zoo = Zoo()
>>> for cl in (Zoo, Bam, Bar, Foo, Base, Base0): assert isinstance(zoo, cl)
>>> fooit(zoo)
42
>>> bam = Bam()
>>> for cl in (Bam, Bar, Foo, Base, Base0): assert isinstance(bam, cl)
>>> fooit(bam)
42
>>> bar = Bar()
>>> for cl in (Bar, Foo, Base, Base0): assert isinstance(bar, cl)
>>> fooit(bar)
42
>>> foo = Foo()
>>> for cl in (Foo, Base, Base0): assert isinstance(foo, cl)
>>> fooit(foo)
42
>>> base = Base()
>>> for cl in (Base, Base0): assert isinstance(base, cl)
>>> fooit(base)
Traceback (most recent call last):
TypeError: Argument 'foo' has incorrect type (expected subclasses.Foo, got subclasses.Base)
>>> base0 = Base0()
>>> for cl in (Base0,): assert isinstance(base0, cl)
>>> fooit(base0)
Traceback (most recent call last):
TypeError: Argument 'foo' has incorrect type (expected subclasses.Foo, got subclasses.Base0)
"""
cdef class Base0:
pass
cdef class Base(Base0):
pass
cdef class Foo(Base):
cdef fooit(self):
return 42
cdef class Bar(Foo):
pass
cdef class Bam(Bar):
pass
cdef class Zoo(Bam):
pass
def fooit(Foo foo):
return foo.fooit()
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