Commit 0ca51142 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel

parents be8d3798 9dfe33b2
......@@ -446,9 +446,9 @@ def buf_lookup_full_code(proto, defin, name, nd):
proto.putln("#define %s(type, buf, %s) (type)(%s_imp(buf, %s))" % (name, macroargs, name, macroargs))
funcargs = ", ".join(["Py_ssize_t i%d, Py_ssize_t s%d, Py_ssize_t o%d" % (i, i, i) for i in range(nd)])
proto.putln("static INLINE void* %s_imp(void* buf, %s);" % (name, funcargs))
proto.putln("static CYTHON_INLINE void* %s_imp(void* buf, %s);" % (name, funcargs))
defin.putln(dedent("""
static INLINE void* %s_imp(void* buf, %s) {
static CYTHON_INLINE void* %s_imp(void* buf, %s) {
char* ptr = (char*)buf;
""") % (name, funcargs) + "".join([dedent("""\
ptr += s%d * i%d;
......@@ -723,10 +723,10 @@ typedef struct {
} __Pyx_BufFmt_StackElem;
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
static int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
""", impl="""
static INLINE int __Pyx_IsLittleEndian(void) {
static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
unsigned int n = 1;
return *(unsigned char*)(&n) != 0;
}
......@@ -1123,7 +1123,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
}
}
static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
buf->buf = NULL;
buf->obj = NULL;
buf->strides = __Pyx_zeros;
......@@ -1164,7 +1164,7 @@ fail:;
return -1;
}
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
if (info->buf == NULL) return;
if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
__Pyx_ReleaseBuffer(info);
......
......@@ -50,7 +50,7 @@ builtin_function_table = [
#('round', "", "", ""),
('setattr', "OOO", "r", "PyObject_SetAttr"),
#('sum', "", "", ""),
('type', "O", "O", "PyObject_Type"),
#('type', "O", "O", "PyObject_Type"),
#('unichr', "", "", ""),
#('unicode', "", "", ""),
#('vars', "", "", ""),
......@@ -120,6 +120,13 @@ builtin_types_table = [
("frozenset", "PyFrozenSet_Type", []),
]
types_that_construct_their_instance = (
# some builtin types do not always return an instance of
# themselves - these do:
'type', 'bool', 'long', 'float', 'bytes', 'unicode', 'tuple', 'list',
'dict', 'file', 'set', 'frozenset'
# 'str', # only in Py3.x
)
builtin_structs_table = [
......@@ -287,19 +294,19 @@ proto = """
#define PySet_Pop(set) \\
PyObject_CallMethod(set, (char *)"pop", NULL)
static INLINE int PySet_Clear(PyObject *set) {
static CYTHON_INLINE int PySet_Clear(PyObject *set) {
PyObject *ret = PyObject_CallMethod(set, (char *)"clear", NULL);
if (!ret) return -1;
Py_DECREF(ret); return 0;
}
static INLINE int PySet_Discard(PyObject *set, PyObject *key) {
static CYTHON_INLINE int PySet_Discard(PyObject *set, PyObject *key) {
PyObject *ret = PyObject_CallMethod(set, (char *)"discard", (char *)"O", key);
if (!ret) return -1;
Py_DECREF(ret); return 0;
}
static INLINE int PySet_Add(PyObject *set, PyObject *key) {
static CYTHON_INLINE int PySet_Add(PyObject *set, PyObject *key) {
PyObject *ret = PyObject_CallMethod(set, (char *)"add", (char *)"O", key);
if (!ret) return -1;
Py_DECREF(ret); return 0;
......@@ -407,7 +414,7 @@ def init_builtins():
init_builtin_types()
init_builtin_structs()
global list_type, tuple_type, dict_type, set_type, type_type
global bytes_type, str_type, unicode_type
global bytes_type, str_type, unicode_type, float_type
type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
......@@ -416,5 +423,6 @@ def init_builtins():
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
init_builtins()
......@@ -80,11 +80,6 @@ def parse_command_line(args):
options.show_version = 1
elif option in ("-l", "--create-listing"):
options.use_listing_file = 1
elif option in ("-C", "--compile"):
options.c_only = 0
elif option in ("--link"):
options.c_only = 0
options.obj_only = 0
elif option in ("-+", "--cplus"):
options.cplus = 1
elif option == "--embed":
......@@ -121,7 +116,7 @@ def parse_command_line(args):
options.emit_linenums = True
elif option in ("-X", "--directive"):
try:
options.compiler_directives = Options.parse_directive_list(pop_arg())
options.compiler_directives = Options.parse_directive_list(pop_arg(), relaxed_bool=True)
except ValueError, e:
sys.stderr.write("Error in compiler directive: %s\n" % e.message)
sys.exit(1)
......@@ -135,14 +130,9 @@ def parse_command_line(args):
elif arg.endswith(".py"):
# maybe do some other stuff, but this should work for now
sources.append(arg)
elif arg.endswith(".o"):
options.objects.append(arg)
else:
sys.stderr.write(
"cython: %s: Unknown filename suffix\n" % arg)
if options.objects and len(sources) > 1:
sys.stderr.write(
"cython: Only one source file allowed together with .o files\n")
if options.use_listing_file and len(sources) > 1:
sys.stderr.write(
"cython: Only one source file allowed when using -o\n")
......
......@@ -619,15 +619,30 @@ class GlobalState(object):
def add_cached_builtin_decl(self, entry):
if Options.cache_builtins:
if self.should_declare(entry.cname, entry):
interned_cname = self.get_interned_identifier(entry.name).cname
self.put_pyobject_decl(entry)
w = self.parts['cached_builtins']
if entry.name == 'xrange':
# replaced by range() in Py3
w.putln('#if PY_MAJOR_VERSION >= 3')
self.put_cached_builtin_init(
entry.pos, StringEncoding.EncodedString('range'),
entry.cname)
w.putln('#else')
self.put_cached_builtin_init(
entry.pos, StringEncoding.EncodedString(entry.name),
entry.cname)
if entry.name == 'xrange':
w.putln('#endif')
def put_cached_builtin_init(self, pos, name, cname):
w = self.parts['cached_builtins']
interned_cname = self.get_interned_identifier(name).cname
w.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
entry.cname,
cname,
Naming.builtins_cname,
interned_cname,
entry.cname,
w.error_goto(entry.pos)))
cname,
w.error_goto(pos)))
def generate_const_declarations(self):
self.generate_string_constants()
......@@ -1281,6 +1296,9 @@ class CCodeWriter(object):
def put_finish_refcount_context(self):
self.putln("__Pyx_RefNannyFinishContext();")
def put_trace_declarations(self):
self.putln('__Pyx_TraceDeclarations');
def put_trace_call(self, name, pos):
self.putln('__Pyx_TraceCall("%s", %s[%s], %s);' % (name, Naming.filetable_cname, self.lookup_filename(pos[0]), pos[1]));
......
......@@ -533,6 +533,14 @@ class ExprNode(Node):
#
# This method is called during the analyse_expressions
# phase of the src_node's processing.
#
# Note that subclasses that override this (especially
# ConstNodes) must not (re-)set their own .type attribute
# here. Since expression nodes may turn up in different
# places in the tree (e.g. inside of CloneNodes in cascaded
# assignments), this method must return a new node instance
# if it changes the type.
#
src = self
src_type = self.type
src_is_py_type = src_type.is_pyobject
......@@ -749,24 +757,28 @@ class IntNode(ConstNode):
type = PyrexTypes.c_long_type
def coerce_to(self, dst_type, env):
if dst_type.is_numeric and not dst_type.is_complex:
self.type = PyrexTypes.c_long_type
if self.type is dst_type:
return self
# Arrange for a Python version of the number to be pre-allocated
# when coercing to a Python type.
node = IntNode(self.pos, value=self.value,
unsigned=self.unsigned, longness=self.longness)
if dst_type.is_numeric and not dst_type.is_complex:
return node
if dst_type.is_pyobject:
self.type = PyrexTypes.py_object_type
node.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,
# in which case a type test node will be needed.
return ConstNode.coerce_to(self, dst_type, env)
return ConstNode.coerce_to(node, dst_type, env)
def coerce_to_boolean(self, env):
self.type = PyrexTypes.c_bint_type
return self
return IntNode(
self.pos, value=self.value,
type = PyrexTypes.c_bint_type,
unsigned=self.unsigned, longness=self.longness)
def generate_evaluation_code(self, code):
if self.type.is_pyobject:
# pre-allocate a Python version of the number
self.result_code = code.get_py_num(self.value, self.longness)
else:
self.result_code = self.get_constant_c_result_code()
......@@ -838,31 +850,29 @@ class BytesNode(ConstNode):
return len(self.value) == 1
def coerce_to(self, dst_type, env):
if dst_type == PyrexTypes.c_char_ptr_type:
self.type = PyrexTypes.c_char_ptr_type
return self
elif dst_type == PyrexTypes.c_uchar_ptr_type:
self.type = PyrexTypes.c_char_ptr_type
return CastNode(self, PyrexTypes.c_uchar_ptr_type)
if dst_type.is_int:
if not self.can_coerce_to_char_literal():
error(self.pos, "Only single-character strings can be coerced into ints.")
return self
return CharNode(self.pos, value=self.value)
node = self
node = BytesNode(self.pos, value=self.value)
if dst_type == PyrexTypes.c_char_ptr_type:
node.type = PyrexTypes.c_char_ptr_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 = self.as_py_string_node(env)
node.type = Builtin.bytes_type
elif dst_type.is_pyobject:
self.fail_assignment(dst_type)
return self
else:
node = self
elif dst_type.is_pyobject and dst_type is not py_object_type:
self.check_for_coercion_error(dst_type, fail=True)
return self
return node
# We still need to perform normal coerce_to processing on the
# result, because we might be coercing to an extension type,
......@@ -925,7 +935,7 @@ class StringNode(PyConstNode):
is_identifier = None
def coerce_to(self, dst_type, env):
if dst_type is not py_object_type and dst_type is not str_type:
if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
# if dst_type is Builtin.bytes_type:
# # special case: bytes = 'str literal'
# return BytesNode(self.pos, value=self.value)
......@@ -1010,15 +1020,16 @@ class ImagNode(AtomicExprNode):
self.type.create_declaration_utility_code(env)
def coerce_to(self, dst_type, env):
# Arrange for a Python version of the number to be pre-allocated
# when coercing to a Python type.
if self.type is dst_type:
return self
node = ImagNode(self.pos, value=self.value)
if dst_type.is_pyobject:
self.is_temp = 1
self.type = PyrexTypes.py_object_type
node.is_temp = 1
node.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,
# in which case a type test node will be needed.
return AtomicExprNode.coerce_to(self, dst_type, env)
return AtomicExprNode.coerce_to(node, dst_type, env)
gil_message = "Constructing complex number"
......@@ -1080,7 +1091,7 @@ class NameNode(AtomicExprNode):
elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
self.name == self.entry.type.name:
# Unfortunately the type attribute of type objects
# is used for the pointer to the type the represent.
# is used for the pointer to the type they represent.
return type_type
else:
return self.entry.type
......@@ -1154,7 +1165,9 @@ class NameNode(AtomicExprNode):
if not self.entry:
self.entry = env.lookup_here(self.name)
if not self.entry:
if env.directives['infer_types']:
if env.directives['warn.undeclared']:
warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
if env.directives['infer_types'] != False:
type = unspecified_type
else:
type = py_object_type
......@@ -1849,11 +1862,18 @@ class IndexNode(ExprNode):
self.original_index_type = self.index.type
if self.base.type.is_pyobject:
if self.index.type.is_int:
if (not setting
and (self.base.type is list_type or self.base.type is tuple_type)
and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
and not env.directives['boundscheck']):
self.is_temp = 0
else:
self.is_temp = 1
self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
else:
self.index = self.index.coerce_to_pyobject(env)
self.type = py_object_type
self.is_temp = 1
self.type = py_object_type
else:
if self.base.type.is_ptr or self.base.type.is_array:
self.type = self.base.type.base_type
......@@ -1891,6 +1911,10 @@ class IndexNode(ExprNode):
def calculate_result_code(self):
if self.is_buffer_access:
return "(*%s)" % self.buffer_ptr_code
elif self.base.type is list_type:
return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
elif self.base.type is tuple_type:
return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
else:
return "(%s[%s])" % (
self.base.result(), self.index.result())
......@@ -1938,7 +1962,7 @@ class IndexNode(ExprNode):
# is_temp is True, so must pull out value and incref it.
code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
elif self.type.is_pyobject:
elif self.type.is_pyobject and self.is_temp:
if self.index.type.is_int:
index_code = self.index.result()
if self.base.type is list_type:
......@@ -2081,6 +2105,15 @@ class SliceIndexNode(ExprNode):
subexprs = ['base', 'start', 'stop']
def infer_type(self, env):
base_type = self.base.infer_type(env)
if base_type.is_string:
return bytes_type
elif base_type in (bytes_type, str_type, unicode_type,
list_type, tuple_type):
return base_type
return py_object_type
def calculate_constant_result(self):
self.constant_result = self.base.constant_result[
self.start.constant_result : self.stop.constant_result]
......@@ -2399,12 +2432,22 @@ class SimpleCallNode(CallNode):
return self.function.type_dependencies(env)
def infer_type(self, env):
func_type = self.function.infer_type(env)
function = self.function
func_type = function.infer_type(env)
if func_type.is_ptr:
func_type = func_type.base_type
if func_type.is_cfunction:
return func_type.return_type
else:
elif func_type is type_type:
if function.is_name and function.entry and function.entry.type:
result_type = function.entry.type
if result_type.is_extension_type:
return result_type
elif result_type.is_builtin_type:
if function.entry.name == 'float':
return PyrexTypes.c_double_type
elif function.entry.name in Builtin.types_that_construct_their_instance:
return result_type
return py_object_type
def analyse_as_type(self, env):
......@@ -2438,7 +2481,19 @@ class SimpleCallNode(CallNode):
self.arg_tuple = TupleNode(self.pos, args = self.args)
self.arg_tuple.analyse_types(env)
self.args = None
if function.is_name and function.type_entry:
if func_type is Builtin.type_type and function.is_name and \
function.entry and \
function.entry.is_builtin and \
function.entry.name in Builtin.types_that_construct_their_instance:
# calling a builtin type that returns a specific object type
if function.entry.name == 'float':
# the following will come true later on in a transform
self.type = PyrexTypes.c_double_type
self.result_ctype = PyrexTypes.c_double_type
else:
self.type = Builtin.builtin_types[function.entry.name]
self.result_ctype = py_object_type
elif function.is_name and function.type_entry:
# We are calling an extension type constructor. As
# long as we do not support __new__(), the result type
# is clear
......@@ -2583,7 +2638,7 @@ class SimpleCallNode(CallNode):
func_type.opt_arg_cname(formal_arg.name),
actual_arg.result_as(formal_arg.type)))
exc_checks = []
if self.type.is_pyobject:
if self.type.is_pyobject and self.is_temp:
exc_checks.append("!%s" % self.result())
else:
exc_val = func_type.exception_value
......@@ -2632,28 +2687,32 @@ class SimpleCallNode(CallNode):
class PythonCapiFunctionNode(ExprNode):
subexprs = []
def __init__(self, pos, name, func_type, utility_code = None):
def __init__(self, pos, py_name, cname, func_type, utility_code = None):
self.pos = pos
self.name = name
self.name = py_name
self.cname = cname
self.type = func_type
self.utility_code = utility_code
def analyse_types(self, env):
pass
def generate_result_code(self, code):
if self.utility_code:
code.globalstate.use_utility_code(self.utility_code)
def calculate_result_code(self):
return self.name
return self.cname
class PythonCapiCallNode(SimpleCallNode):
# Python C-API Function call (only created in transforms)
def __init__(self, pos, function_name, func_type,
utility_code = None, **kwargs):
utility_code = None, py_name=None, **kwargs):
self.type = func_type.return_type
self.result_ctype = self.type
self.function = PythonCapiFunctionNode(
pos, function_name, func_type,
pos, py_name, function_name, func_type,
utility_code = utility_code)
# call this last so that we can override the constructed
# attributes above with explicit keyword arguments if required
......@@ -2704,7 +2763,7 @@ class GeneralCallNode(CallNode):
if not self.function.type.is_pyobject:
if self.function.type.is_error:
self.type = error_type
return error_type
return
if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
else:
......@@ -2726,6 +2785,7 @@ class GeneralCallNode(CallNode):
def generate_result_code(self, code):
if self.type.is_error: return
kwargs_call_function = "PyEval_CallObjectWithKeywords"
if self.keyword_args and self.starstar_arg:
code.put_error_if_neg(self.pos,
"PyDict_Update(%s, %s)" % (
......@@ -2736,6 +2796,10 @@ class GeneralCallNode(CallNode):
keyword_code = self.keyword_args.py_result()
elif self.starstar_arg:
keyword_code = self.starstar_arg.py_result()
if self.starstar_arg.type is not Builtin.dict_type:
# CPython supports calling functions with non-dicts, so do we
code.globalstate.use_utility_code(kwargs_call_utility_code)
kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
else:
keyword_code = None
if not keyword_code:
......@@ -2743,7 +2807,8 @@ class GeneralCallNode(CallNode):
self.function.py_result(),
self.positional_args.py_result())
else:
call_code = "PyEval_CallObjectWithKeywords(%s, %s, %s)" % (
call_code = "%s(%s, %s, %s)" % (
kwargs_call_function,
self.function.py_result(),
self.positional_args.py_result(),
keyword_code)
......@@ -3018,11 +3083,12 @@ class AttributeNode(ExprNode):
if obj_type is None:
obj_type = self.obj.type
self.member = self.attribute
if obj_type.is_pyobject:
self.type = py_object_type
self.is_py_attr = 1
if not obj_type.is_pyobject and not obj_type.is_error:
if obj_type.can_coerce_to_pyobject(env):
self.obj = self.obj.coerce_to_pyobject(env)
else:
if not obj_type.is_error:
error(self.pos,
"Object of type '%s' has no attribute '%s'" %
(obj_type, self.attribute))
......@@ -3621,14 +3687,13 @@ class ComprehensionNode(ExprNode):
def infer_type(self, env):
return self.target.infer_type(env)
def analyse_declarations(self, env):
self.append.target = self # this is used in the PyList_Append of the inner loop
self.loop.analyse_declarations(env)
def analyse_types(self, env):
self.target.analyse_expressions(env)
self.type = self.target.type
self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
# We are analysing declarations to late.
self.loop.target.analyse_target_declaration(env)
env.infer_types()
self.loop.analyse_declarations(env)
self.loop.analyse_expressions(env)
def calculate_result_code(self):
......@@ -4340,7 +4405,7 @@ class TypecastNode(ExprNode):
if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
if to_py and not from_py:
if self.operand.type.create_to_py_utility_code(env):
if self.operand.type.can_coerce_to_pyobject(env):
self.result_ctype = py_object_type
self.operand = self.operand.coerce_to_pyobject(env)
else:
......@@ -4494,7 +4559,7 @@ class TypeofNode(ExprNode):
literal = None
type = py_object_type
subexprs = ['operand', 'literal']
subexprs = ['literal'] # 'operand' will be ignored after type analysis!
def analyse_types(self, env):
self.operand.analyse_types(env)
......@@ -5419,8 +5484,8 @@ class CmpNode(object):
contians_utility_code = UtilityCode(
proto="""
static INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
static INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
}
""")
......@@ -5789,11 +5854,15 @@ class CoerceToPyTypeNode(CoercionNode):
type = py_object_type
is_temp = 1
def __init__(self, arg, env):
def __init__(self, arg, env, type=py_object_type):
CoercionNode.__init__(self, arg)
if not arg.type.create_to_py_utility_code(env):
error(arg.pos,
"Cannot convert '%s' to Python object" % arg.type)
if type is not py_object_type:
self.type = py_object_type
elif arg.type.is_string:
self.type = Builtin.bytes_type
gil_message = "Converting to Python object"
......@@ -6143,10 +6212,10 @@ bad:
type_test_utility_code = UtilityCode(
proto = """
static INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
""",
impl = """
static INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (unlikely(!type)) {
PyErr_Format(PyExc_SystemError, "Missing type object");
return 0;
......@@ -6227,7 +6296,7 @@ impl = ""
getitem_int_utility_code = UtilityCode(
proto = """
static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
PyObject *r;
if (!j) return NULL;
r = PyObject_GetItem(o, j);
......@@ -6241,7 +6310,7 @@ static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
__Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_GetItemInt_Generic(o, to_py_func(i)))
static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
if (likely(o != Py_None)) {
if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
PyObject *r = Py%(type)s_GET_ITEM(o, i);
......@@ -6263,7 +6332,7 @@ static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i
__Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_GetItemInt_Generic(o, to_py_func(i)))
static INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
PyObject *r;
if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
r = PyList_GET_ITEM(o, i);
......@@ -6295,7 +6364,7 @@ proto = """
__Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\
__Pyx_SetItemInt_Generic(o, to_py_func(i), v))
static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
int r;
if (!j) return -1;
r = PyObject_SetItem(o, j, v);
......@@ -6303,7 +6372,7 @@ static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v
return r;
}
static INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) {
if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
Py_INCREF(v);
Py_DECREF(PyList_GET_ITEM(o, i));
......@@ -6329,7 +6398,7 @@ proto = """
__Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\
__Pyx_DelItem_Generic(o, to_py_func(i)))
static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
int r;
if (!j) return -1;
r = PyObject_DelItem(o, j);
......@@ -6337,7 +6406,7 @@ static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
return r;
}
static INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) {
if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
return PySequence_DelItem(o, i);
else {
......@@ -6353,50 +6422,50 @@ impl = """
raise_noneattr_error_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
""",
impl = '''
static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
}
''')
raise_noneindex_error_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNoneIndexingError(void);
static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
""",
impl = '''
static INLINE void __Pyx_RaiseNoneIndexingError(void) {
static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
}
''')
raise_none_iter_error_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNoneNotIterableError(void);
static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
""",
impl = '''
static INLINE void __Pyx_RaiseNoneNotIterableError(void) {
static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
}
''')
raise_too_many_values_to_unpack = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseTooManyValuesError(void);
static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void);
""",
impl = '''
static INLINE void __Pyx_RaiseTooManyValuesError(void) {
static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(void) {
PyErr_SetString(PyExc_ValueError, "too many values to unpack");
}
''')
raise_need_more_values_to_unpack = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
""",
impl = '''
static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
PyErr_Format(PyExc_ValueError,
#if PY_VERSION_HEX < 0x02050000
"need more than %d value%s to unpack", (int)index,
......@@ -6462,15 +6531,42 @@ requires = [raise_need_more_values_to_unpack,
raise_too_many_values_to_unpack]
)
#------------------------------------------------------------------------------------
# CPython supports calling functions with non-dict kwargs by
# converting them to a dict first
kwargs_call_utility_code = UtilityCode(
proto = """
static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
""",
impl = """
static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
PyObject* result;
if (likely(PyDict_Check(kwargs))) {
return PyEval_CallObjectWithKeywords(callable, args, kwargs);
} else {
PyObject* real_dict;
real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
if (unlikely(!real_dict))
return NULL;
result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
Py_DECREF(real_dict);
return result; /* may be NULL */
}
}
""",
)
#------------------------------------------------------------------------------------
int_pow_utility_code = UtilityCode(
proto="""
static INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
""",
impl="""
static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
%(type)s t = b;
switch (e) {
case 3:
......@@ -6497,10 +6593,10 @@ static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
div_int_utility_code = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
""",
impl="""
static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s q = a / b;
%(type)s r = a - q*b;
q -= ((r != 0) & ((r ^ b) < 0));
......@@ -6510,10 +6606,10 @@ static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
mod_int_utility_code = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
""",
impl="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s r = a %% b;
r += ((r != 0) & ((r ^ b) < 0)) * b;
return r;
......@@ -6522,10 +6618,10 @@ static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
mod_float_utility_code = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
""",
impl="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s r = fmod%(math_h_modifier)s(a, b);
r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
return r;
......
......@@ -8,7 +8,6 @@ compile-time values.
from Nodes import *
from ExprNodes import *
from Visitor import BasicVisitor
from Errors import CompileError
......
#
# Pyrex Scanner - Lexical Definitions
#
# Changing anything in this file will cause Lexicon.pickle
# to be rebuilt next time pyrexc is run.
# Cython Scanner - Lexical Definitions
#
raw_prefixes = "rR"
......
......@@ -92,7 +92,8 @@ class Context(object):
from AnalysedTreeTransforms import AutoTestDictTransform
from AutoDocTransforms import EmbedSignature
from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform
from Optimize import OptimizeBuiltinCalls, ConstantFolding, FinalOptimizePhase
from Optimize import EarlyReplaceBuiltinCalls, OptimizeBuiltinCalls
from Optimize import ConstantFolding, FinalOptimizePhase
from Optimize import DropRefcountingTransform
from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_declarations, check_c_declarations_pxd
......@@ -133,6 +134,7 @@ class Context(object):
CreateClosureClasses(self),
AutoTestDictTransform(self),
EmbedSignature(self),
EarlyReplaceBuiltinCalls(self),
MarkAssignments(self),
TransformBuiltinMethods(self),
IntroduceBufferAuxiliaryVars(self),
......@@ -509,15 +511,6 @@ class Context(object):
except EnvironmentError:
pass
result.c_file = None
if result.c_file and not options.c_only and c_compile:
result.object_file = c_compile(result.c_file,
verbose_flag = options.show_version,
cplus = options.cplus)
if not options.obj_only and c_link:
result.extension_file = c_link(result.object_file,
extra_objects = options.objects,
verbose_flag = options.show_version,
cplus = options.cplus)
def create_parse(context):
def parse(compsrc):
......@@ -605,17 +598,11 @@ class CompilationOptions(object):
compiler_directives dict Overrides for pragma options (see Options.py)
evaluate_tree_assertions boolean Test support: evaluate parse tree assertions
Following options are experimental and only used on MacOSX:
c_only boolean Stop after generating C file (default)
obj_only boolean Stop after compiling to .o file
objects [string] Extra .o files to link with
cplus boolean Compile as c++ code
"""
def __init__(self, defaults = None, c_compile = 0, c_link = 0, **kw):
def __init__(self, defaults = None, **kw):
self.include_path = []
self.objects = []
if defaults:
if isinstance(defaults, CompilationOptions):
defaults = defaults.__dict__
......@@ -623,10 +610,6 @@ class CompilationOptions(object):
defaults = default_options
self.__dict__.update(defaults)
self.__dict__.update(kw)
if c_compile:
self.c_only = 0
if c_link:
self.obj_only = 0
class CompilationResult(object):
......@@ -719,8 +702,7 @@ def compile_multiple(sources, options):
"Cannot find .pyx file for cimported module '%s'\n" % module_name)
return results
def compile(source, options = None, c_compile = 0, c_link = 0,
full_module_name = None, **kwds):
def compile(source, options = None, full_module_name = None, **kwds):
"""
compile(source [, options], [, <option> = <value>]...)
......@@ -730,8 +712,7 @@ def compile(source, options = None, c_compile = 0, c_link = 0,
checking is requested, a CompilationResult is returned, otherwise a
CompilationResultSet is returned.
"""
options = CompilationOptions(defaults = options, c_compile = c_compile,
c_link = c_link, **kwds)
options = CompilationOptions(defaults = options, **kwds)
if isinstance(source, basestring) and not options.timestamps \
and not options.recursive:
return compile_single(source, options, full_module_name)
......@@ -782,8 +763,6 @@ default_options = dict(
show_version = 0,
use_listing_file = 0,
errors_to_stderr = 1,
c_only = 1,
obj_only = 1,
cplus = 0,
output_file = None,
annotate = False,
......@@ -797,13 +776,3 @@ default_options = dict(
evaluate_tree_assertions = False,
emit_linenums = False,
)
if sys.platform == "mac":
from Cython.Mac.MacSystem import c_compile, c_link, CCompilerError
default_options['use_listing_file'] = 1
elif sys.platform == "darwin":
from Cython.Mac.DarwinSystem import c_compile, c_link, CCompilerError
else:
c_compile = None
c_link = None
......@@ -418,153 +418,163 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_cfunction_predeclarations(module, modulecode, defined_here)
def generate_module_preamble(self, env, cimported_modules, code):
code.putln('/* Generated by Cython %s on %s */' % (
code.putln("/* Generated by Cython %s on %s */" % (
Version.version, time.asctime()))
code.putln('')
code.putln('#define PY_SSIZE_T_CLEAN')
code.putln("")
code.putln("#define PY_SSIZE_T_CLEAN")
for filename in env.python_include_files:
code.putln('#include "%s"' % filename)
code.putln("#ifndef Py_PYTHON_H")
code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.")
code.putln("#else")
code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
code.putln("#ifndef PY_LONG_LONG")
code.putln(" #define PY_LONG_LONG LONG_LONG")
code.putln("#endif")
code.putln("#ifndef DL_EXPORT")
code.putln(" #define DL_EXPORT(t) t")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(" #define METH_COEXIST 0")
code.putln(" #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)")
code.putln(" #define PyDict_Contains(d,o) PySequence_Contains(d,o)")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02050000")
code.putln(" typedef int Py_ssize_t;")
code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
code.putln(" #define PY_FORMAT_SIZE_T \"\"")
code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
code.putln("#endif")
code.put("""
#ifndef PY_LONG_LONG
#define PY_LONG_LONG LONG_LONG
#endif
#ifndef DL_EXPORT
#define DL_EXPORT(t) t
#endif
#if PY_VERSION_HEX < 0x02040000
#define METH_COEXIST 0
#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
#define PyDict_Contains(d,o) PySequence_Contains(d,o)
#endif
code.putln("#if PY_VERSION_HEX < 0x02060000")
code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
code.putln(" #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)")
code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
code.putln(" PyObject_HEAD_INIT(type) size,")
code.putln(" #define PyType_Modified(t)")
code.putln("")
code.putln(" typedef struct {")
code.putln(" void *buf;")
code.putln(" PyObject *obj;")
code.putln(" Py_ssize_t len;")
code.putln(" Py_ssize_t itemsize;")
code.putln(" int readonly;")
code.putln(" int ndim;")
code.putln(" char *format;")
code.putln(" Py_ssize_t *shape;")
code.putln(" Py_ssize_t *strides;")
code.putln(" Py_ssize_t *suboffsets;")
code.putln(" void *internal;")
code.putln(" } Py_buffer;")
code.putln("")
code.putln(" #define PyBUF_SIMPLE 0")
code.putln(" #define PyBUF_WRITABLE 0x0001")
code.putln(" #define PyBUF_FORMAT 0x0004")
code.putln(" #define PyBUF_ND 0x0008")
code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
code.putln(" #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
code.putln("")
code.putln("#endif")
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
#define PY_SSIZE_T_MAX INT_MAX
#define PY_SSIZE_T_MIN INT_MIN
#define PY_FORMAT_SIZE_T \"\"
#define PyInt_FromSsize_t(z) PyInt_FromLong(z)
#define PyInt_AsSsize_t(o) PyInt_AsLong(o)
#define PyNumber_Index(o) PyNumber_Int(o)
#define PyIndex_Check(o) PyNumber_Check(o)
#define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
#endif
code.put(builtin_module_name_utility_code.proto)
#if PY_VERSION_HEX < 0x02060000
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
#define PyVarObject_HEAD_INIT(type, size) \\
PyObject_HEAD_INIT(type) size,
#define PyType_Modified(t)
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
code.putln("#endif")
typedef struct {
void *buf;
PyObject *obj;
Py_ssize_t len;
Py_ssize_t itemsize;
int readonly;
int ndim;
char *format;
Py_ssize_t *shape;
Py_ssize_t *strides;
Py_ssize_t *suboffsets;
void *internal;
} Py_buffer;
#define PyBUF_SIMPLE 0
#define PyBUF_WRITABLE 0x0001
#define PyBUF_FORMAT 0x0004
#define PyBUF_ND 0x0008
#define PyBUF_STRIDES (0x0010 | PyBUF_ND)
#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
code.putln(" #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
code.putln("#endif")
#endif
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyBaseString_Type PyUnicode_Type")
code.putln(" #define PyString_Type PyUnicode_Type")
code.putln(" #define PyString_CheckExact PyUnicode_CheckExact")
code.putln("#else")
code.putln(" #define PyBytes_Type PyString_Type")
code.putln(" #define PyBytes_CheckExact PyString_CheckExact")
code.putln("#endif")
#if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyInt_Type PyLong_Type")
code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
code.putln(" #define PyInt_FromString PyLong_FromString")
code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
code.putln(" #define PyInt_FromLong PyLong_FromLong")
code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
code.putln(" #define PyInt_AsLong PyLong_AsLong")
code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)")
code.putln("#else")
#if PY_MAJOR_VERSION >= 3
#define Py_TPFLAGS_CHECKTYPES 0
#define Py_TPFLAGS_HAVE_INDEX 0
#endif
#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
#define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
#if PY_MAJOR_VERSION >= 3
#define PyBaseString_Type PyUnicode_Type
#define PyString_Type PyUnicode_Type
#define PyString_CheckExact PyUnicode_CheckExact
#else
#define PyBytes_Type PyString_Type
#define PyBytes_CheckExact PyString_CheckExact
#endif
#if PY_MAJOR_VERSION >= 3
#define PyInt_Type PyLong_Type
#define PyInt_Check(op) PyLong_Check(op)
#define PyInt_CheckExact(op) PyLong_CheckExact(op)
#define PyInt_FromString PyLong_FromString
#define PyInt_FromUnicode PyLong_FromUnicode
#define PyInt_FromLong PyLong_FromLong
#define PyInt_FromSize_t PyLong_FromSize_t
#define PyInt_FromSsize_t PyLong_FromSsize_t
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG
#define PyInt_AsSsize_t PyLong_AsSsize_t
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
#else
""")
if Future.division in env.context.future_directives:
code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)")
else:
code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)")
code.putln("#endif")
code.put("""
#endif
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
code.putln("#endif")
#if PY_MAJOR_VERSION >= 3
#define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)
#endif
code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
code.putln(" #ifndef __stdcall")
code.putln(" #define __stdcall")
code.putln(" #endif")
code.putln(" #ifndef __cdecl")
code.putln(" #define __cdecl")
code.putln(" #endif")
code.putln(" #ifndef __fastcall")
code.putln(" #define __fastcall")
code.putln(" #endif")
code.putln("#else")
code.putln(" #define _USE_MATH_DEFINES")
code.putln("#endif")
#if !defined(WIN32) && !defined(MS_WINDOWS)
#ifndef __stdcall
#define __stdcall
#endif
#ifndef __cdecl
#define __cdecl
#endif
#ifndef __fastcall
#define __fastcall
#endif
#else
#define _USE_MATH_DEFINES
#endif
code.putln("#if PY_VERSION_HEX < 0x02050000")
code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))")
code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))")
code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))")
code.putln("#else")
code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))")
code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))")
code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))")
code.putln("#endif")
#if PY_VERSION_HEX < 0x02050000
#define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
#define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
#define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
#else
#define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
#define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
#define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
#endif
code.putln("#if PY_VERSION_HEX < 0x02050000")
code.putln(" #define __Pyx_NAMESTR(n) ((char *)(n))")
code.putln(" #define __Pyx_DOCSTR(n) ((char *)(n))")
code.putln("#else")
code.putln(" #define __Pyx_NAMESTR(n) (n)")
code.putln(" #define __Pyx_DOCSTR(n) (n)")
code.putln("#endif")
#if PY_VERSION_HEX < 0x02050000
#define __Pyx_NAMESTR(n) ((char *)(n))
#define __Pyx_DOCSTR(n) ((char *)(n))
#else
#define __Pyx_NAMESTR(n) (n)
#define __Pyx_DOCSTR(n) (n)
#endif
""")
self.generate_extern_c_macro_definition(code)
code.putln("#include <math.h>")
......@@ -1991,18 +2001,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_name = '__Pyx_BUILTIN_MODULE_NAME'
if type.name in self.py3_type_name_map:
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), 1); %s' % (
type.typeptr_cname,
module_name,
self.py3_type_name_map[type.name],
objstruct,
error_code))
code.putln("#else")
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
type.typeptr_cname,
module_name,
type.name,
objstruct,
not type.is_external or type.is_subclassed,
error_code))
if type.name in self.py3_type_name_map:
code.putln("#endif")
......@@ -2103,23 +2114,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#
#------------------------------------------------------------------------------------
builtin_module_name_utility_code = UtilityCode(
proto = """\
#if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
""")
#------------------------------------------------------------------------------------
streq_utility_code = UtilityCode(
proto = """
static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
""",
impl = """
static INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
return *s1 == *s2;
}
......@@ -2159,17 +2159,18 @@ bad:
type_import_utility_code = UtilityCode(
proto = """
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size, int strict); /*proto*/
""",
impl = """
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
long size)
long size, int strict)
{
PyObject *py_module = 0;
PyObject *result = 0;
PyObject *py_name = 0;
char warning[200];
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
......@@ -2194,9 +2195,15 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
module_name, class_name);
goto bad;
}
if (((PyTypeObject *)result)->tp_basicsize != size) {
if (!strict && ((PyTypeObject *)result)->tp_basicsize > size) {
PyOS_snprintf(warning, sizeof(warning),
"%s.%s size changed, may indicate binary incompatibility",
module_name, class_name);
PyErr_WarnEx(NULL, warning, 0);
}
else if (((PyTypeObject *)result)->tp_basicsize != size) {
PyErr_Format(PyExc_ValueError,
"%s.%s does not appear to be the correct type object",
"%s.%s has the wrong size, try recompiling",
module_name, class_name);
goto bad;
}
......
......@@ -599,11 +599,13 @@ class CArgDeclNode(Node):
# default_value PyObjectConst constant for default value
# annotation ExprNode or None Py3 function arg annotation
# is_self_arg boolean Is the "self" arg of an extension type method
# is_type_arg boolean Is the "class" arg of an extension type classmethod
# is_kw_only boolean Is a keyword-only argument
child_attrs = ["base_type", "declarator", "default"]
is_self_arg = 0
is_type_arg = 0
is_generic = 1
type = None
name_declarator = None
......@@ -671,6 +673,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
# longness integer
# complex boolean
# is_self_arg boolean Is self argument of C method
# ##is_type_arg boolean Is type argument of class method
child_attrs = []
arg_name = None # in case the argument name was interpreted as a type
......@@ -689,6 +692,8 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
if self.is_self_arg and env.is_c_class_scope:
#print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
type = env.parent_type
## elif self.is_type_arg and env.is_c_class_scope:
## type = Builtin.type_type
else:
type = py_object_type
else:
......@@ -705,6 +710,8 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
elif could_be_name:
if self.is_self_arg and env.is_c_class_scope:
type = env.parent_type
## elif self.is_type_arg and env.is_c_class_scope:
## type = Builtin.type_type
else:
type = py_object_type
self.arg_name = self.name
......@@ -1098,6 +1105,8 @@ class FuncDefNode(StatNode, BlockNode):
init))
tempvardecl_code = code.insertion_point()
self.generate_keyword_list(code)
if profile:
code.put_trace_declarations()
# ----- Extern library function declarations
lenv.generate_library_function_declarations(code)
# ----- GIL acquisition
......@@ -1501,6 +1510,8 @@ class CFuncDefNode(FuncDefNode):
storage_class = ""
else:
storage_class = "static "
if 'inline' in self.modifiers:
self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
code.putln("%s%s %s {" % (
storage_class,
' '.join(self.modifiers).upper(), # macro forms
......@@ -1649,7 +1660,7 @@ class DefNode(FuncDefNode):
return_type_annotation = None
entry = None
acquire_gil = 0
self_in_stararg = 0
def __init__(self, pos, **kwds):
FuncDefNode.__init__(self, pos, **kwds)
......@@ -1725,6 +1736,31 @@ class DefNode(FuncDefNode):
directive_locals = getattr(cfunc, 'directive_locals', {}))
def analyse_declarations(self, env):
self.is_classmethod = self.is_staticmethod = False
if self.decorators:
for decorator in self.decorators:
func = decorator.decorator
if func.is_name:
self.is_classmethod |= func.name == 'classmethod'
self.is_staticmethod |= func.name == 'staticmethod'
if self.is_classmethod and env.lookup_here('classmethod'):
# classmethod() was overridden - not much we can do here ...
self.is_classmethod = False
if self.is_staticmethod and env.lookup_here('staticmethod'):
# staticmethod() was overridden - not much we can do here ...
self.is_staticmethod = False
self.analyse_argument_types(env)
if self.name == '<lambda>':
self.declare_lambda_function(env)
else:
self.declare_pyfunction(env)
self.analyse_signature(env)
self.return_type = self.entry.signature.return_type()
self.create_local_scope(env)
def analyse_argument_types(self, env):
directive_locals = self.directive_locals = env.directives['locals']
for arg in self.args:
if hasattr(arg, 'name'):
......@@ -1757,13 +1793,6 @@ class DefNode(FuncDefNode):
if arg.not_none and not arg.type.is_extension_type:
error(self.pos,
"Only extension type arguments can have 'not None'")
if self.name == '<lambda>':
self.declare_lambda_function(env)
else:
self.declare_pyfunction(env)
self.analyse_signature(env)
self.return_type = self.entry.signature.return_type()
self.create_local_scope(env)
def analyse_signature(self, env):
any_type_tests_needed = 0
......@@ -1783,13 +1812,26 @@ class DefNode(FuncDefNode):
elif len(self.args) == 2:
if self.args[1].default is None and not self.args[1].kw_only:
self.entry.signature = TypeSlots.ibinaryfunc
sig = self.entry.signature
nfixed = sig.num_fixed_args()
for i in range(nfixed):
if i < len(self.args):
if sig is TypeSlots.pymethod_signature and nfixed == 1 \
and len(self.args) == 0 and self.star_arg:
# this is the only case where a diverging number of
# arguments is not an error - when we have no explicit
# 'self' parameter as in method(*args)
sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
self.self_in_stararg = 1
nfixed = 0
for i in range(min(nfixed, len(self.args))):
arg = self.args[i]
arg.is_generic = 0
if sig.is_self_arg(i):
if sig.is_self_arg(i) and not self.is_staticmethod:
if self.is_classmethod:
arg.is_type_arg = 1
arg.hdr_type = arg.type = Builtin.type_type
else:
arg.is_self_arg = 1
arg.hdr_type = arg.type = env.parent_type
arg.needs_conversion = 0
......@@ -1805,10 +1847,11 @@ class DefNode(FuncDefNode):
arg.hdr_cname = Naming.arg_prefix + arg.name
else:
arg.hdr_cname = Naming.var_prefix + arg.name
else:
if nfixed > len(self.args):
self.bad_signature()
return
if nfixed < len(self.args):
elif nfixed < len(self.args):
if not sig.has_generic_args:
self.bad_signature()
for arg in self.args:
......@@ -1836,7 +1879,9 @@ class DefNode(FuncDefNode):
def signature_has_nongeneric_args(self):
argcount = len(self.args)
if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
if argcount == 0 or (
argcount == 1 and (self.args[0].is_self_arg or
self.args[0].is_type_arg)):
return 0
return 1
......@@ -1892,7 +1937,7 @@ class DefNode(FuncDefNode):
arg.entry.used = 1
arg.entry.is_self_arg = arg.is_self_arg
if arg.hdr_type:
if arg.is_self_arg or \
if arg.is_self_arg or arg.is_type_arg or \
(arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
arg.entry.is_declared_generic = 1
self.declare_python_arg(env, self.star_arg)
......@@ -1900,8 +1945,11 @@ class DefNode(FuncDefNode):
def declare_python_arg(self, env, arg):
if arg:
entry = env.declare_var(arg.name,
PyrexTypes.py_object_type, arg.pos)
if env.directives['infer_types'] != 'none':
type = PyrexTypes.unspecified_type
else:
type = py_object_type
entry = env.declare_var(arg.name, type, arg.pos)
entry.used = 1
entry.init = "0"
entry.init_to_none = 0
......@@ -1934,12 +1982,12 @@ class DefNode(FuncDefNode):
def generate_function_header(self, code, with_pymethdef, proto_only=0):
arg_code_list = []
sig = self.entry.signature
if sig.has_dummy_arg:
if sig.has_dummy_arg or self.self_in_stararg:
arg_code_list.append(
"PyObject *%s" % Naming.self_cname)
for arg in self.args:
if not arg.is_generic:
if arg.is_self_arg:
if arg.is_self_arg or arg.is_type_arg:
arg_code_list.append("PyObject *%s" % arg.hdr_cname)
else:
arg_code_list.append(
......@@ -1994,7 +2042,7 @@ 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:
if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
# get rid of unused argument warning
code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
......@@ -2027,14 +2075,14 @@ class DefNode(FuncDefNode):
arg_entry = arg.entry
if arg.is_generic:
if arg.default:
if not arg.is_self_arg:
if not arg.is_self_arg and not arg.is_type_arg:
if arg.kw_only:
kw_only_args.append(arg)
else:
positional_args.append(arg)
elif arg.kw_only:
kw_only_args.append(arg)
elif not arg.is_self_arg:
elif not arg.is_self_arg and not arg.is_type_arg:
positional_args.append(arg)
self.generate_tuple_and_keyword_parsing_code(
......@@ -2115,8 +2163,37 @@ class DefNode(FuncDefNode):
self.starstar_arg.entry.xdecref_cleanup = 0
code.put_gotref(self.starstar_arg.entry.cname)
if self.star_arg:
if self.self_in_stararg:
# need to create a new tuple with 'self' inserted as first item
code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
self.star_arg.entry.cname,
Naming.args_cname,
self.star_arg.entry.cname))
if self.starstar_arg:
code.putln("{")
code.put_decref(self.starstar_arg.entry.cname, py_object_type)
code.putln("return %s;" % self.error_value())
code.putln("}")
else:
code.putln("return %s;" % self.error_value())
code.put_gotref(self.star_arg.entry.cname)
code.put_incref(Naming.self_cname, py_object_type)
code.put_giveref(Naming.self_cname)
code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
self.star_arg.entry.cname, Naming.self_cname))
temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
temp, temp, Naming.args_cname, temp))
code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
Naming.args_cname, temp))
code.put_incref("item", py_object_type)
code.put_giveref("item")
code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
self.star_arg.entry.cname, temp))
code.putln("}")
code.funcstate.release_temp(temp)
self.star_arg.entry.xdecref_cleanup = 0
elif self.star_arg:
code.put_incref(Naming.args_cname, py_object_type)
code.putln("%s = %s;" % (
self.star_arg.entry.cname,
......@@ -2128,7 +2205,7 @@ class DefNode(FuncDefNode):
argtuple_error_label = code.new_label("argtuple_error")
min_positional_args = self.num_required_args - self.num_required_kw_args
if len(self.args) > 0 and self.args[0].is_self_arg:
if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
min_positional_args -= 1
max_positional_args = len(positional_args)
has_fixed_positional_count = not self.star_arg and \
......@@ -3068,6 +3145,7 @@ class CascadedAssignmentNode(AssignmentNode):
def analyse_types(self, env, use_temp = 0):
self.rhs.analyse_types(env)
if not self.rhs.is_simple():
if use_temp:
self.rhs = self.rhs.coerce_to_temp(env)
else:
......@@ -3729,9 +3807,6 @@ class IfClauseNode(Node):
self.condition.generate_disposal_code(code)
self.condition.free_temps(code)
self.body.generate_execution_code(code)
#code.putln(
# "goto %s;" %
# end_label)
code.put_goto(end_label)
code.putln("}")
......@@ -4555,12 +4630,8 @@ class TryFinallyStatNode(StatNode):
code.putln(
"%s = %s;" % (
Naming.exc_lineno_name, Naming.lineno_cname))
#code.putln(
# "goto %s;" %
# catch_label)
code.put_goto(catch_label)
code.putln(
"}")
code.putln("}")
def put_error_uncatcher(self, code, i, error_label):
code.globalstate.use_utility_code(restore_exception_utility_code)
......@@ -4824,12 +4895,14 @@ class FromImportStatNode(StatNode):
utility_function_predeclarations = \
"""
#ifdef __GNUC__
#define INLINE __inline__
#elif _WIN32
#define INLINE __inline
#else
#define INLINE
#ifndef CYTHON_INLINE
#if defined(__GNUC__)
#define CYTHON_INLINE __inline__
#elif defined(_MSC_VER)
#define CYTHON_INLINE __inline
#else
#define CYTHON_INLINE
#endif
#endif
typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
......@@ -5016,11 +5089,11 @@ requires=[printing_utility_code])
restore_exception_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
""",
impl = """
static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_GET();
......@@ -5035,7 +5108,7 @@ static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *t
Py_XDECREF(tmp_tb);
}
static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
PyThreadState *tstate = PyThreadState_GET();
*type = tstate->curexc_type;
*value = tstate->curexc_value;
......@@ -5255,11 +5328,11 @@ requires=[get_exception_utility_code])
reset_exception_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
""",
impl = """
static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
PyThreadState *tstate = PyThreadState_GET();
*type = tstate->exc_type;
*value = tstate->exc_value;
......@@ -5358,10 +5431,10 @@ static void __Pyx_RaiseArgtupleInvalid(
raise_keyword_required_utility_code = UtilityCode(
proto = """
static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
""",
impl = """
static INLINE void __Pyx_RaiseKeywordRequired(
static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
const char* func_name,
PyObject* kw_name)
{
......@@ -5403,11 +5476,11 @@ static void __Pyx_RaiseDoubleKeywordsError(
keyword_string_check_utility_code = UtilityCode(
proto = """
static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
const char* function_name, int kw_allowed); /*proto*/
""",
impl = """
static INLINE int __Pyx_CheckKeywordStrings(
static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
PyObject *kwdict,
const char* function_name,
int kw_allowed)
......@@ -5752,11 +5825,11 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
force_init_threads_utility_code = UtilityCode(
proto="""
#ifndef __PYX_FORCE_INIT_THREADS
#if PY_VERSION_HEX < 0x02040200
#define __PYX_FORCE_INIT_THREADS 1
#else
#define __PYX_FORCE_INIT_THREADS 0
#endif
#if PY_VERSION_HEX < 0x02040200
#define __PYX_FORCE_INIT_THREADS 1
#else
#define __PYX_FORCE_INIT_THREADS 0
#endif
#endif
""")
......@@ -5767,59 +5840,64 @@ proto="""
profile_utility_code = UtilityCode(proto="""
#ifndef CYTHON_PROFILE
#define CYTHON_PROFILE 1
#define CYTHON_PROFILE 1
#endif
#ifndef CYTHON_PROFILE_REUSE_FRAME
#define CYTHON_PROFILE_REUSE_FRAME 0
#define CYTHON_PROFILE_REUSE_FRAME 0
#endif
#if CYTHON_PROFILE
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
#if CYTHON_PROFILE_REUSE_FRAME
#define CYTHON_FRAME_MODIFIER static
#define CYTHON_FRAME_DEL
#else
#define CYTHON_FRAME_MODIFIER
#define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
#endif
#if CYTHON_PROFILE_REUSE_FRAME
#define CYTHON_FRAME_MODIFIER static
#define CYTHON_FRAME_DEL
#else
#define CYTHON_FRAME_MODIFIER
#define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
#endif
#define __Pyx_TraceDeclarations \\
static PyCodeObject *%(FRAME_CODE)s = NULL; \\
CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
int __Pyx_use_tracing = 0;
#define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
static PyCodeObject *%(FRAME_CODE)s = NULL; \\
CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
int __Pyx_use_tracing = 0; \\
if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
#define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
__Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
}
}
#define __Pyx_TraceException() \\
if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
#define __Pyx_TraceException() \\
if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
if (exc_info) { \\
PyThreadState_GET()->c_profilefunc( \\
PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
Py_DECREF(exc_info); \\
} \\
}
}
#define __Pyx_TraceReturn(result) \\
if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
#define __Pyx_TraceReturn(result) \\
if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
PyThreadState_GET()->c_profilefunc( \\
PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
CYTHON_FRAME_DEL; \\
}
}
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
#else
#define __Pyx_TraceCall(funcname, srcfile, firstlineno)
#define __Pyx_TraceException()
#define __Pyx_TraceReturn(result)
#define __Pyx_TraceDeclarations
#define __Pyx_TraceCall(funcname, srcfile, firstlineno)
#define __Pyx_TraceException()
#define __Pyx_TraceReturn(result)
#endif /* CYTHON_PROFILE */
"""
% {
......
......@@ -116,17 +116,15 @@ class IterationTransform(Visitor.VisitorTransform):
node, dict_obj, keys, values)
# enumerate() ?
if iterator.self is None and \
isinstance(function, ExprNodes.NameNode) and \
function.entry.is_builtin and \
if iterator.self is None and function.is_name and \
function.entry and function.entry.is_builtin and \
function.name == 'enumerate':
return self._transform_enumerate_iteration(node, iterator)
# range() iteration?
if Options.convert_range and node.target.type.is_int:
if iterator.self is None and \
isinstance(function, ExprNodes.NameNode) and \
function.entry.is_builtin and \
if iterator.self is None and function.is_name and \
function.entry and function.entry.is_builtin and \
function.name in ('range', 'xrange'):
return self._transform_range_iteration(node, iterator)
......@@ -618,6 +616,9 @@ class DropRefcountingTransform(Visitor.VisitorTransform):
visit_Node = Visitor.VisitorTransform.recurse_to_children
def visit_ParallelAssignmentNode(self, node):
"""
Parallel swap assignments like 'a,b = b,a' are safe.
"""
left_names, right_names = [], []
left_indices, right_indices = [], []
temps = []
......@@ -725,9 +726,160 @@ class DropRefcountingTransform(Visitor.VisitorTransform):
return (base.name, index_val)
class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
"""Optimize some common calls to builtin types *before* the type
analysis phase and *after* the declarations analysis phase.
This transform cannot make use of any argument types, but it can
restructure the tree in a way that the type analysis phase can
respond to.
Introducing C function calls here may not be a good idea. Move
them to the OptimizeBuiltinCalls transform instead, which runs
after type analyis.
"""
# only intercept on call nodes
visit_Node = Visitor.VisitorTransform.recurse_to_children
def visit_SimpleCallNode(self, node):
self.visitchildren(node)
function = node.function
if not self._function_is_builtin_name(function):
return node
return self._dispatch_to_handler(node, function, node.args)
def visit_GeneralCallNode(self, node):
self.visitchildren(node)
function = node.function
if not self._function_is_builtin_name(function):
return node
arg_tuple = node.positional_args
if not isinstance(arg_tuple, ExprNodes.TupleNode):
return node
args = arg_tuple.args
return self._dispatch_to_handler(
node, function, args, node.keyword_args)
def _function_is_builtin_name(self, function):
if not function.is_name:
return False
entry = self.env_stack[-1].lookup(function.name)
if not entry or getattr(entry, 'scope', None) is not Builtin.builtin_scope:
return False
return True
def _dispatch_to_handler(self, node, function, args, kwargs=None):
if kwargs is None:
handler_name = '_handle_simple_function_%s' % function.name
else:
handler_name = '_handle_general_function_%s' % function.name
handle_call = getattr(self, handler_name, None)
if handle_call is not None:
if kwargs is None:
return handle_call(node, args)
else:
return handle_call(node, args, kwargs)
return node
def _inject_capi_function(self, node, cname, func_type, utility_code=None):
node.function = ExprNodes.PythonCapiFunctionNode(
node.function.pos, node.function.name, cname, func_type,
utility_code = utility_code)
def _error_wrong_arg_count(self, function_name, node, args, expected=None):
if not expected: # None or 0
arg_str = ''
elif isinstance(expected, basestring) or expected > 1:
arg_str = '...'
elif expected == 1:
arg_str = 'x'
else:
arg_str = ''
if expected is not None:
expected_str = 'expected %s, ' % expected
else:
expected_str = ''
error(node.pos, "%s(%s) called with wrong number of args, %sfound %d" % (
function_name, arg_str, expected_str, len(args)))
# specific handlers for simple call nodes
def _handle_simple_function_set(self, node, pos_args):
"""Replace set([a,b,...]) by a literal set {a,b,...} and
set([ x for ... ]) by a literal { x for ... }.
"""
arg_count = len(pos_args)
if arg_count == 0:
return ExprNodes.SetNode(node.pos, args=[],
type=Builtin.set_type)
if arg_count > 1:
return node
iterable = pos_args[0]
if isinstance(iterable, (ExprNodes.ListNode, ExprNodes.TupleNode)):
return ExprNodes.SetNode(node.pos, args=iterable.args)
elif isinstance(iterable, ExprNodes.ComprehensionNode) and \
isinstance(iterable.target, (ExprNodes.ListNode,
ExprNodes.SetNode)):
iterable.target = ExprNodes.SetNode(node.pos, args=[])
iterable.pos = node.pos
return iterable
else:
return node
def _handle_simple_function_dict(self, node, pos_args):
"""Replace dict([ (a,b) for ... ]) by a literal { a:b for ... }.
"""
if len(pos_args) != 1:
return node
arg = pos_args[0]
if isinstance(arg, ExprNodes.ComprehensionNode) and \
isinstance(arg.target, (ExprNodes.ListNode,
ExprNodes.SetNode)):
append_node = arg.append
if isinstance(append_node.expr, (ExprNodes.TupleNode, ExprNodes.ListNode)) and \
len(append_node.expr.args) == 2:
key_node, value_node = append_node.expr.args
target_node = ExprNodes.DictNode(
pos=arg.target.pos, key_value_pairs=[])
new_append_node = ExprNodes.DictComprehensionAppendNode(
append_node.pos, target=target_node,
key_expr=key_node, value_expr=value_node)
arg.target = target_node
arg.type = target_node.type
replace_in = Visitor.RecursiveNodeReplacer(append_node, new_append_node)
return replace_in(arg)
return node
def _handle_simple_function_float(self, node, pos_args):
if len(pos_args) == 0:
return ExprNodes.FloatNode(node.pos, value='0.0')
if len(pos_args) > 1:
self._error_wrong_arg_count('float', node, pos_args, 1)
return node
# specific handlers for general call nodes
def _handle_general_function_dict(self, node, pos_args, kwargs):
"""Replace dict(a=b,c=d,...) by the underlying keyword dict
construction which is done anyway.
"""
if len(pos_args) > 0:
return node
if not isinstance(kwargs, ExprNodes.DictNode):
return node
if node.starstar_arg:
# we could optimize this by updating the kw dict instead
return node
return kwargs
class OptimizeBuiltinCalls(Visitor.EnvTransform):
"""Optimize some common methods calls and instantiation patterns
for builtin types.
for builtin types *after* the type analysis phase.
Running after type analysis, this transform can only perform
function replacements that do not alter the function return type
in a way that was not anticipated by the type analysis.
"""
# only intercept on call nodes
visit_Node = Visitor.VisitorTransform.recurse_to_children
......@@ -740,19 +892,22 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
arg_tuple = node.positional_args
if not isinstance(arg_tuple, ExprNodes.TupleNode):
return node
args = arg_tuple.args
return self._dispatch_to_handler(
node, function, arg_tuple, node.keyword_args)
node, function, args, node.keyword_args)
def visit_SimpleCallNode(self, node):
self.visitchildren(node)
function = node.function
if not function.type.is_pyobject:
return node
if function.type.is_pyobject:
arg_tuple = node.arg_tuple
if not isinstance(arg_tuple, ExprNodes.TupleNode):
return node
args = arg_tuple.args
else:
args = node.args
return self._dispatch_to_handler(
node, node.function, arg_tuple)
node, function, args)
### cleanup to avoid redundant coercions to/from Python types
......@@ -805,13 +960,15 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
if func_arg.type == node.type:
return func_arg
elif node.type.assignable_from(func_arg.type) or func_arg.type.is_float:
return ExprNodes.CastNode(func_arg, node.type)
return ExprNodes.TypecastNode(
node.pos, operand=func_arg, type=node.type)
elif function.name == 'float':
if func_arg.type.is_float or node.type.is_float:
if func_arg.type == node.type:
return func_arg
elif node.type.assignable_from(func_arg.type) or func_arg.type.is_float:
return ExprNodes.CastNode(func_arg, node.type)
return ExprNodes.TypecastNode(
node.pos, operand=func_arg, type=node.type)
return node
### dispatch to specific optimisers
......@@ -823,20 +980,27 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
handler = getattr(self, '_handle_any_%s' % match_name, None)
return handler
def _dispatch_to_handler(self, node, function, arg_tuple, kwargs=None):
def _dispatch_to_handler(self, node, function, arg_list, kwargs=None):
if function.is_name:
match_name = "_function_%s" % function.name
# we only consider functions that are either builtin
# Python functions or builtins that were already replaced
# 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
if not is_builtin:
return node
function_handler = self._find_handler(
"function_%s" % function.name, kwargs)
if function_handler is None:
return node
if kwargs:
return function_handler(node, arg_tuple, kwargs)
return function_handler(node, arg_list, kwargs)
else:
return function_handler(node, arg_tuple)
elif function.is_attribute:
return function_handler(node, arg_list)
elif function.is_attribute and function.type.is_pyobject:
attr_name = function.attribute
arg_list = arg_tuple.args
self_arg = function.obj
obj_type = self_arg.type
is_unbound_method = False
......@@ -888,31 +1052,17 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
### builtin types
def _handle_general_function_dict(self, node, pos_args, kwargs):
"""Replace dict(a=b,c=d,...) by the underlying keyword dict
construction which is done anyway.
"""
if len(pos_args.args) > 0:
return node
if not isinstance(kwargs, ExprNodes.DictNode):
return node
if node.starstar_arg:
# we could optimize this by updating the kw dict instead
return node
return kwargs
PyDict_Copy_func_type = PyrexTypes.CFuncType(
Builtin.dict_type, [
PyrexTypes.CFuncTypeArg("dict", Builtin.dict_type, None)
])
def _handle_simple_function_dict(self, node, pos_args):
"""Replace dict(some_dict) by PyDict_Copy(some_dict) and
dict([ (a,b) for ... ]) by a literal { a:b for ... }.
"""Replace dict(some_dict) by PyDict_Copy(some_dict).
"""
if len(pos_args.args) != 1:
if len(pos_args) != 1:
return node
arg = pos_args.args[0]
arg = pos_args[0]
if arg.type is Builtin.dict_type:
arg = ExprNodes.NoneCheckNode(
arg, "PyExc_TypeError", "'NoneType' is not iterable")
......@@ -921,46 +1071,6 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
args = [arg],
is_temp = node.is_temp
)
elif isinstance(arg, ExprNodes.ComprehensionNode) and \
arg.type is Builtin.list_type:
append_node = arg.append
if isinstance(append_node.expr, (ExprNodes.TupleNode, ExprNodes.ListNode)) and \
len(append_node.expr.args) == 2:
key_node, value_node = append_node.expr.args
target_node = ExprNodes.DictNode(
pos=arg.target.pos, key_value_pairs=[], is_temp=1)
new_append_node = ExprNodes.DictComprehensionAppendNode(
append_node.pos, target=target_node,
key_expr=key_node, value_expr=value_node,
is_temp=1)
arg.target = target_node
arg.type = target_node.type
replace_in = Visitor.RecursiveNodeReplacer(append_node, new_append_node)
return replace_in(arg)
return node
def _handle_simple_function_set(self, node, pos_args):
"""Replace set([a,b,...]) by a literal set {a,b,...} and
set([ x for ... ]) by a literal { x for ... }.
"""
arg_count = len(pos_args.args)
if arg_count == 0:
return ExprNodes.SetNode(node.pos, args=[],
type=Builtin.set_type, is_temp=1)
if arg_count > 1:
return node
iterable = pos_args.args[0]
if isinstance(iterable, (ExprNodes.ListNode, ExprNodes.TupleNode)):
return ExprNodes.SetNode(node.pos, args=iterable.args,
type=Builtin.set_type, is_temp=1)
elif isinstance(iterable, ExprNodes.ComprehensionNode) and \
iterable.type is Builtin.list_type:
iterable.target = ExprNodes.SetNode(
node.pos, args=[], type=Builtin.set_type, is_temp=1)
iterable.type = Builtin.set_type
iterable.pos = node.pos
return iterable
else:
return node
PyList_AsTuple_func_type = PyrexTypes.CFuncType(
......@@ -971,23 +1081,52 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
def _handle_simple_function_tuple(self, node, pos_args):
"""Replace tuple([...]) by a call to PyList_AsTuple.
"""
if len(pos_args.args) != 1:
if len(pos_args) != 1:
return node
list_arg = pos_args.args[0]
list_arg = pos_args[0]
if list_arg.type is not Builtin.list_type:
return node
if not isinstance(list_arg, (ExprNodes.ComprehensionNode,
ExprNodes.ListNode)):
pos_args.args[0] = ExprNodes.NoneCheckNode(
pos_args[0] = ExprNodes.NoneCheckNode(
list_arg, "PyExc_TypeError",
"'NoneType' object is not iterable")
return ExprNodes.PythonCapiCallNode(
node.pos, "PyList_AsTuple", self.PyList_AsTuple_func_type,
args = pos_args.args,
args = pos_args,
is_temp = node.is_temp
)
PyObject_AsDouble_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_double_type, [
PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None),
],
exception_value = "((double)-1)",
exception_check = True)
def _handle_simple_function_float(self, node, pos_args):
# Note: this requires the float() function to be typed as
# returning a C 'double'
if len(pos_args) != 1:
self._error_wrong_arg_count('float', node, pos_args, 1)
return node
func_arg = pos_args[0]
if isinstance(func_arg, ExprNodes.CoerceToPyTypeNode):
func_arg = func_arg.arg
if func_arg.type is PyrexTypes.c_double_type:
return func_arg
elif node.type.assignable_from(func_arg.type) or func_arg.type.is_numeric:
return ExprNodes.TypecastNode(
node.pos, operand=func_arg, type=node.type)
return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_PyObject_AsDouble",
self.PyObject_AsDouble_func_type,
args = pos_args,
is_temp = node.is_temp,
utility_code = pyobject_as_double_utility_code,
py_name = "float")
### builtin functions
PyObject_GetAttr2_func_type = PyrexTypes.CFuncType(
......@@ -1004,22 +1143,45 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
])
def _handle_simple_function_getattr(self, node, pos_args):
args = pos_args.args
if len(args) == 2:
node = ExprNodes.PythonCapiCallNode(
if len(pos_args) == 2:
return ExprNodes.PythonCapiCallNode(
node.pos, "PyObject_GetAttr", self.PyObject_GetAttr2_func_type,
args = args,
is_temp = node.is_temp
)
elif len(args) == 3:
node = ExprNodes.PythonCapiCallNode(
args = pos_args,
is_temp = node.is_temp)
elif len(pos_args) == 3:
return ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_GetAttr3", self.PyObject_GetAttr3_func_type,
utility_code = Builtin.getattr3_utility_code,
args = args,
is_temp = node.is_temp
)
args = pos_args,
is_temp = node.is_temp,
utility_code = Builtin.getattr3_utility_code)
else:
self._error_wrong_arg_count('getattr', node, args, '2 or 3')
self._error_wrong_arg_count('getattr', node, pos_args, '2 or 3')
return node
Pyx_strlen_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_size_t_type, [
PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None)
])
def _handle_simple_function_len(self, node, pos_args):
# note: this only works because we already replaced len() by
# PyObject_Length() which returns a Py_ssize_t instead of a
# Python object, so we can return a plain size_t instead
# without caring about Python object conversion etc.
if len(pos_args) != 1:
self._error_wrong_arg_count('len', node, pos_args, 1)
return node
arg = pos_args[0]
if isinstance(arg, ExprNodes.CoerceToPyTypeNode):
arg = arg.arg
if not arg.type.is_string:
return node
node = ExprNodes.PythonCapiCallNode(
node.pos, "strlen", self.Pyx_strlen_func_type,
args = [arg],
is_temp = node.is_temp,
utility_code = include_string_h_utility_code
)
return node
Pyx_Type_func_type = PyrexTypes.CFuncType(
......@@ -1028,16 +1190,13 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
])
def _handle_simple_function_type(self, node, pos_args):
args = pos_args.args
if len(args) != 1:
if len(pos_args) != 1:
return node
node = ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_Type", self.Pyx_Type_func_type,
args = args,
is_temp = node.is_temp,
utility_code = pytype_utility_code,
)
return node
node.pos, "Py_TYPE", self.Pyx_Type_func_type,
args = pos_args,
is_temp = False)
return ExprNodes.CastNode(node, PyrexTypes.py_object_type)
### special methods
......@@ -1265,47 +1424,89 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
if len(args) < 1 or len(args) > 3:
self._error_wrong_arg_count('bytes.decode', node, args, '1-3')
return node
if not isinstance(args[0], ExprNodes.SliceIndexNode):
# we need the string length as a slice end index
return node
temps = []
if isinstance(args[0], ExprNodes.SliceIndexNode):
index_node = args[0]
string_node = index_node.base
if not string_node.type.is_string:
# nothing to optimise here
return node
start, stop = index_node.start, index_node.stop
if not stop:
# FIXME: could use strlen() - although Python will do that anyway ...
return node
if stop.type.is_pyobject:
if not start or start.constant_result == 0:
start = None
else:
if start.type.is_pyobject:
start = start.coerce_to(PyrexTypes.c_py_ssize_t_type, self.env_stack[-1])
if stop:
start = UtilNodes.LetRefNode(start)
temps.append(start)
string_node = ExprNodes.AddNode(pos=start.pos,
operand1=string_node,
operator='+',
operand2=start,
is_temp=False,
type=string_node.type
)
if stop and stop.type.is_pyobject:
stop = stop.coerce_to(PyrexTypes.c_py_ssize_t_type, self.env_stack[-1])
if start and start.constant_result != 0:
# FIXME: put start into a temp and do the math
elif isinstance(args[0], ExprNodes.CoerceToPyTypeNode) \
and args[0].arg.type.is_string:
# use strlen() to find the string length, just as CPython would
start = stop = None
string_node = args[0].arg
else:
# let Python do its job
return node
if not stop:
if start or not string_node.is_name:
string_node = UtilNodes.LetRefNode(string_node)
temps.append(string_node)
stop = ExprNodes.PythonCapiCallNode(
string_node.pos, "strlen", self.Pyx_strlen_func_type,
args = [string_node],
is_temp = False,
utility_code = include_string_h_utility_code,
).coerce_to(PyrexTypes.c_py_ssize_t_type, self.env_stack[-1])
elif start:
stop = ExprNodes.SubNode(
pos = stop.pos,
operand1 = stop,
operator = '-',
operand2 = start,
is_temp = False,
type = PyrexTypes.c_py_ssize_t_type
)
parameters = self._unpack_encoding_and_error_mode(node.pos, args)
if parameters is None:
return node
encoding, encoding_node, error_handling, error_handling_node = parameters
# try to find a specific encoder function
codec_name = None
if encoding is not None:
codec_name = self._find_special_codec_name(encoding)
if codec_name is not None:
decode_function = "PyUnicode_Decode%s" % codec_name
return ExprNodes.PythonCapiCallNode(
node = ExprNodes.PythonCapiCallNode(
node.pos, decode_function,
self.PyUnicode_DecodeXyz_func_type,
args = [string_node, stop, error_handling_node],
is_temp = node.is_temp,
)
return ExprNodes.PythonCapiCallNode(
else:
node = ExprNodes.PythonCapiCallNode(
node.pos, "PyUnicode_Decode",
self.PyUnicode_Decode_func_type,
args = [string_node, stop, encoding_node, error_handling_node],
is_temp = node.is_temp,
)
for temp in temps[::-1]:
node = UtilNodes.EvalWithTempExprNode(temp, node)
return node
def _find_special_codec_name(self, encoding):
try:
requested_codec = codecs.getencoder(encoding)
......@@ -1323,22 +1524,24 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
encoding_node = args[1]
if isinstance(encoding_node, ExprNodes.CoerceToPyTypeNode):
encoding_node = encoding_node.arg
if not isinstance(encoding_node, (ExprNodes.UnicodeNode, ExprNodes.StringNode,
if isinstance(encoding_node, (ExprNodes.UnicodeNode, ExprNodes.StringNode,
ExprNodes.BytesNode)):
return None
encoding = encoding_node.value
encoding_node = ExprNodes.BytesNode(encoding_node.pos, value=encoding,
type=PyrexTypes.c_char_ptr_type)
elif encoding_node.type.is_string:
encoding = None
else:
return None
null_node = ExprNodes.NullNode(pos)
if len(args) == 3:
error_handling_node = args[2]
if isinstance(error_handling_node, ExprNodes.CoerceToPyTypeNode):
error_handling_node = error_handling_node.arg
if not isinstance(error_handling_node,
if isinstance(error_handling_node,
(ExprNodes.UnicodeNode, ExprNodes.StringNode,
ExprNodes.BytesNode)):
return None
error_handling = error_handling_node.value
if error_handling == 'strict':
error_handling_node = null_node
......@@ -1346,6 +1549,10 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
error_handling_node = ExprNodes.BytesNode(
error_handling_node.pos, value=error_handling,
type=PyrexTypes.c_char_ptr_type)
elif error_handling_node.type.is_string:
error_handling = None
else:
return None
else:
error_handling = 'strict'
error_handling_node = null_node
......@@ -1376,7 +1583,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
append_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
if (likely(PyList_CheckExact(L))) {
if (PyList_Append(L, x) < 0) return NULL;
Py_INCREF(Py_None);
......@@ -1398,7 +1605,7 @@ impl = ""
pop_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
if (likely(PyList_CheckExact(L))
/* Check that both the size is positive and no reallocation shrinking needs to be done. */
&& likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
......@@ -1466,20 +1673,55 @@ bad:
)
pytype_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_Type(PyObject* o) {
PyObject* type = (PyObject*) Py_TYPE(o);
Py_INCREF(type);
return type;
pyobject_as_double_utility_code = UtilityCode(
proto = '''
static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */
#define __Pyx_PyObject_AsDouble(obj) \\
((likely(PyFloat_CheckExact(obj))) ? \\
PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj))
''',
impl='''
static double __Pyx__PyObject_AsDouble(PyObject* obj) {
PyObject* float_value;
if (Py_TYPE(obj)->tp_as_number && Py_TYPE(obj)->tp_as_number->nb_float) {
return PyFloat_AsDouble(obj);
} else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
#if PY_MAJOR_VERSION >= 3
float_value = PyFloat_FromString(obj);
#else
float_value = PyFloat_FromString(obj, 0);
#endif
} else {
PyObject* args = PyTuple_New(1);
if (unlikely(!args)) goto bad;
PyTuple_SET_ITEM(args, 0, obj);
float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
PyTuple_SET_ITEM(args, 0, 0);
Py_DECREF(args);
}
if (likely(float_value)) {
double value = PyFloat_AS_DOUBLE(float_value);
Py_DECREF(float_value);
return value;
}
bad:
return (double)-1;
}
'''
)
include_string_h_utility_code = UtilityCode(
proto = """
#include <string.h>
"""
)
tpnew_utility_code = UtilityCode(
proto = """
static INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) {
static CYTHON_INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) {
return (PyObject*) (((PyTypeObject*)(type_obj))->tp_new(
(PyTypeObject*)(type_obj), %(TUPLE)s, NULL));
}
......@@ -1515,7 +1757,7 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
node.calculate_constant_result()
# if node.constant_result is not ExprNodes.not_a_constant:
# print node.__class__.__name__, node.constant_result
except (ValueError, TypeError, KeyError, IndexError, AttributeError):
except (ValueError, TypeError, KeyError, IndexError, AttributeError, ArithmeticError):
# ignore all 'normal' errors here => no constant result
pass
except Exception:
......
......@@ -63,15 +63,21 @@ directive_defaults = {
'callspec' : "",
'profile': False,
'infer_types': False,
'infer_types.verbose': False,
'autotestdict': True,
'warn': None,
'warn.undeclared': False,
# test support
'test_assert_path_exists' : [],
'test_fail_if_path_exists' : [],
}
# Override types possibilities above, if needed
directive_types = {}
directive_types = {
'infer_types' : bool, # values can be True/None/False
}
for key, val in directive_defaults.items():
if key not in directive_types:
......@@ -84,7 +90,7 @@ directive_scopes = { # defaults to available everywhere
'test_fail_if_path_exists' : ('function',),
}
def parse_directive_value(name, value):
def parse_directive_value(name, value, relaxed_bool=False):
"""
Parses value as an option value for the given name and returns
the interpreted value. None is returned if the option does not exist.
......@@ -102,18 +108,25 @@ def parse_directive_value(name, value):
type = directive_types.get(name)
if not type: return None
if type is bool:
if value == "True": return True
elif value == "False": return False
else: raise ValueError("%s directive must be set to True or False" % name)
value = str(value)
if value == 'True': return True
if value == 'False': return False
if relaxed_bool:
value = value.lower()
if value in ("true", "yes"): return True
elif value in ("false", "no"): return False
raise ValueError("%s directive must be set to True or False" % name)
elif type is int:
try:
return int(value)
except ValueError:
raise ValueError("%s directive must be set to an integer" % name)
elif type is str:
return str(value)
else:
assert False
def parse_directive_list(s):
def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False):
"""
Parses a comma-seperated list of pragma options. Whitespace
is not considered.
......@@ -130,7 +143,7 @@ def parse_directive_list(s):
>>> parse_directive_list('boundscheck=hey')
Traceback (most recent call last):
...
ValueError: Must pass a boolean value for option "boundscheck"
ValueError: boundscheck directive must be set to True or False
>>> parse_directive_list('unknown=True')
Traceback (most recent call last):
...
......@@ -141,19 +154,11 @@ def parse_directive_list(s):
item = item.strip()
if not item: continue
if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item)
name, value = item.strip().split('=')
try:
type = directive_types[name]
except KeyError:
name, value = [ s.strip() for s in item.strip().split('=', 1) ]
parsed_value = parse_directive_value(name, value, relaxed_bool=relaxed_bool)
if parsed_value is None:
if not ignore_unknown:
raise ValueError('Unknown option: "%s"' % name)
if type is bool:
value = value.lower()
if value in ('true', 'yes'):
value = True
elif value in ('false', 'no'):
value = False
else: raise ValueError('Must pass a boolean value for option "%s"' % name)
result[name] = value
else:
assert False
result[name] = parsed_value
return result
......@@ -447,44 +447,74 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
node.cython_attribute = self.directive_names.get(node.name)
return node
def try_to_parse_directive(self, node):
def try_to_parse_directives(self, node):
# If node is the contents of an directive (in a with statement or
# decorator), returns (directivename, value).
# decorator), returns a list of (directivename, value) pairs.
# Otherwise, returns None
optname = None
if isinstance(node, CallNode):
self.visit(node.function)
optname = node.function.as_cython_attribute()
if optname:
directivetype = Options.directive_types.get(optname)
if directivetype:
args, kwds = node.explicit_args_kwds()
if directivetype is bool:
directives = []
key_value_pairs = []
if kwds is not None and directivetype is not dict:
for keyvalue in kwds.key_value_pairs:
key, value = keyvalue
sub_optname = "%s.%s" % (optname, key.value)
if Options.directive_types.get(sub_optname):
directives.append(self.try_to_parse_directive(sub_optname, [value], None, keyvalue.pos))
else:
key_value_pairs.append(keyvalue)
if not key_value_pairs:
kwds = None
else:
kwds.key_value_pairs = key_value_pairs
if directives and not kwds and not args:
return directives
directives.append(self.try_to_parse_directive(optname, args, kwds, node.function.pos))
return directives
return None
def try_to_parse_directive(self, optname, args, kwds, pos):
directivetype = Options.directive_types.get(optname)
if optname == 'infer_types':
if kwds is not None or len(args) != 1:
raise PostParseError(pos,
'The %s directive takes one compile-time boolean argument' % optname)
elif isinstance(args[0], BoolNode):
return (optname, args[0].value)
elif isinstance(args[0], NoneNode):
return (optname, None)
else:
raise PostParseError(pos,
'The %s directive takes one compile-time boolean argument' % optname)
elif directivetype is bool:
if kwds is not None or len(args) != 1 or not isinstance(args[0], BoolNode):
raise PostParseError(node.function.pos,
raise PostParseError(pos,
'The %s directive takes one compile-time boolean argument' % optname)
return (optname, args[0].value)
elif directivetype is str:
if kwds is not None or len(args) != 1 or not isinstance(args[0], (StringNode, UnicodeNode)):
raise PostParseError(node.function.pos,
raise PostParseError(pos,
'The %s directive takes one compile-time string argument' % optname)
return (optname, str(args[0].value))
elif directivetype is dict:
if len(args) != 0:
raise PostParseError(node.function.pos,
raise PostParseError(pos,
'The %s directive takes no prepositional arguments' % optname)
return optname, dict([(key.value, value) for key, value in kwds.key_value_pairs])
elif directivetype is list:
if kwds and len(kwds) != 0:
raise PostParseError(node.function.pos,
raise PostParseError(pos,
'The %s directive takes no keyword arguments' % optname)
return optname, [ str(arg.value) for arg in args ]
else:
assert False
return None
def visit_with_directives(self, body, directives):
olddirectives = self.directives
newdirectives = copy.copy(olddirectives)
......@@ -504,9 +534,9 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
# Split the decorators into two lists -- real decorators and directives
realdecs = []
for dec in node.decorators:
directive = self.try_to_parse_directive(dec.decorator)
if directive is not None:
directives.append(directive)
new_directives = self.try_to_parse_directives(dec.decorator)
if new_directives is not None:
directives.extend(new_directives)
else:
realdecs.append(dec)
if realdecs and isinstance(node, CFuncDefNode):
......@@ -542,18 +572,18 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
def visit_CVarDefNode(self, node):
if node.decorators:
for dec in node.decorators:
directive = self.try_to_parse_directive(dec.decorator)
for directive in self.try_to_parse_directives(dec.decorator) or []:
if directive is not None and directive[0] == u'locals':
node.directive_locals = directive[1]
else:
self.context.nonfatal_error(PostParseError(dec.pos,
"Cdef functions can only take cython.locals() decorator."))
continue
return node
# Handle with statements
def visit_WithStatNode(self, node):
directive = self.try_to_parse_directive(node.manager)
directive_dict = {}
for directive in self.try_to_parse_directives(node.manager) or []:
if directive is not None:
if node.target is not None:
self.context.nonfatal_error(
......@@ -561,7 +591,9 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
else:
name, value = directive
if self.check_directive_scope(node.pos, name, 'with statement'):
return self.visit_with_directives(node.body, {name:value})
directive_dict[name] = value
if directive_dict:
return self.visit_with_directives(node.body, directive_dict)
return self.visit_Node(node)
class WithTransform(CythonTransform, SkipDeclarations):
......@@ -750,6 +782,11 @@ property NAME:
self.seen_vars_stack.pop()
return node
def visit_ComprehensionNode(self, node):
self.visitchildren(node)
node.analyse_declarations(self.env_stack[-1])
return node
# Some nodes are no longer needed after declaration
# analysis and can be dropped. The analysis was performed
# on these nodes in a seperate recursive process from the
......@@ -1035,7 +1072,7 @@ class TransformBuiltinMethods(EnvTransform):
if function:
if function == u'cast':
if len(node.args) != 2:
error(node.function.pos, u"cast takes exactly two arguments")
error(node.function.pos, u"cast() takes exactly two arguments")
else:
type = node.args[0].analyse_as_type(self.env_stack[-1])
if type:
......@@ -1044,7 +1081,7 @@ class TransformBuiltinMethods(EnvTransform):
error(node.args[0].pos, "Not a type")
elif function == u'sizeof':
if len(node.args) != 1:
error(node.function.pos, u"sizeof takes exactly one argument" % function)
error(node.function.pos, u"sizeof() takes exactly one argument")
else:
type = node.args[0].analyse_as_type(self.env_stack[-1])
if type:
......@@ -1053,23 +1090,23 @@ class TransformBuiltinMethods(EnvTransform):
node = SizeofVarNode(node.function.pos, operand=node.args[0])
elif function == 'typeof':
if len(node.args) != 1:
error(node.function.pos, u"sizeof takes exactly one argument" % function)
error(node.function.pos, u"typeof() takes exactly one argument")
else:
node = TypeofNode(node.function.pos, operand=node.args[0])
elif function == 'address':
if len(node.args) != 1:
error(node.function.pos, u"sizeof takes exactly one argument" % function)
error(node.function.pos, u"address() takes exactly one argument")
else:
node = AmpersandNode(node.function.pos, operand=node.args[0])
elif function == 'cmod':
if len(node.args) != 2:
error(node.function.pos, u"cmod takes exactly one argument" % function)
error(node.function.pos, u"cmod() takes exactly two arguments")
else:
node = binop_node(node.function.pos, '%', node.args[0], node.args[1])
node.cdivision = True
elif function == 'cdiv':
if len(node.args) != 2:
error(node.function.pos, u"cmod takes exactly one argument" % function)
error(node.function.pos, u"cdiv() takes exactly two arguments")
else:
node = binop_node(node.function.pos, '/', node.args[0], node.args[1])
node.cdivision = True
......
# cython: auto_cpdef=True
# cython: auto_cpdef=True, infer_types=True
#
# Pyrex Parser
#
......@@ -2647,18 +2647,17 @@ def p_code(s, level=None):
repr(s.sy), repr(s.systring)))
return body
COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+)\s*=(.*)$")
COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*((\w|[.])+\s*=.*)$")
def p_compiler_directive_comments(s):
result = {}
while s.sy == 'commentline':
m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring)
if m:
name = m.group(1)
directives = m.group(1).strip()
try:
value = Options.parse_directive_value(str(name), str(m.group(2).strip()))
if value is not None: # can be False!
result[name] = value
result.update( Options.parse_directive_list(
directives, ignore_unknown=True) )
except ValueError, e:
s.error(e.args[0], fatal=False)
s.next()
......
......@@ -11,6 +11,9 @@ class BaseType(object):
#
# Base class for all Pyrex types including pseudo-types.
def can_coerce_to_pyobject(self, env):
return False
def cast_code(self, expr_code):
return "((%s)%s)" % (self.declaration_code(""), expr_code)
......@@ -342,6 +345,8 @@ class PyObjectType(PyrexType):
default_value = "0"
pymemberdef_typecode = "T_OBJECT"
buffer_defaults = None
is_extern = False
is_subclassed = False
def __str__(self):
return "Python object"
......@@ -349,6 +354,9 @@ class PyObjectType(PyrexType):
def __repr__(self):
return "<PyObjectType>"
def can_coerce_to_pyobject(self, env):
return True
def assignable_from(self, src_type):
# except for pointers, conversion will be attempted
return not src_type.is_ptr or src_type.is_string
......@@ -400,8 +408,11 @@ class BuiltinObjectType(PyObjectType):
return src_type.name == self.name or (
src_type.name == self.alternative_name and
src_type.name is not None)
elif src_type.is_extension_type:
return (src_type.module_name == '__builtin__' and
src_type.name == self.name)
else:
return not src_type.is_extension_type
return True
def typeobj_is_available(self):
return True
......@@ -463,10 +474,12 @@ class PyExtensionType(PyObjectType):
objtypedef_cname = None
def __init__(self, name, typedef_flag, base_type):
def __init__(self, name, typedef_flag, base_type, is_external=0):
self.name = name
self.scope = None
self.typedef_flag = typedef_flag
if base_type is not None:
base_type.is_subclassed = True
self.base_type = base_type
self.module_name = None
self.objstruct_cname = None
......@@ -476,6 +489,7 @@ class PyExtensionType(PyObjectType):
self.vtabstruct_cname = None
self.vtabptr_cname = None
self.vtable_cname = None
self.is_external = is_external
def set_scope(self, scope):
self.scope = scope
......@@ -553,6 +567,9 @@ class CType(PyrexType):
def create_from_py_utility_code(self, env):
return self.from_py_function is not None
def can_coerce_to_pyobject(self, env):
return self.create_to_py_utility_code(env)
def error_condition(self, result_code):
conds = []
if self.is_string:
......@@ -621,10 +638,10 @@ type_conversion_functions = ""
c_int_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) < sizeof(long)) {
......@@ -646,10 +663,10 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
c_long_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
static CYTHON_INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
#if PY_VERSION_HEX < 0x03000000
......@@ -687,10 +704,10 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
c_typedef_int_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
static CYTHON_INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) == sizeof(char)) {
......@@ -734,10 +751,10 @@ static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
c_typedef_int_to_py_function = UtilityCode(
proto="""
static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
""",
impl="""
static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
const int is_unsigned = neg_one > const_zero;
if (sizeof(%(type)s) < sizeof(long)) {
......@@ -800,6 +817,9 @@ class CBIntType(CIntType):
from_py_function = "__Pyx_PyObject_IsTrue"
exception_check = 0
def __repr__(self):
return "<CNumericType bint>"
class CAnonEnumType(CIntType):
......@@ -859,6 +879,8 @@ class CFloatType(CNumericType):
to_py_function = "PyFloat_FromDouble"
from_py_function = "__pyx_PyFloat_AsDouble"
exception_value = -1
def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
self.math_h_modifier = math_h_modifier
......@@ -1041,6 +1063,11 @@ proto="""
#include <complex.h>
#endif
#endif
#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
#undef _Complex_I
#define _Complex_I 1.0fj
#endif
""")
complex_real_imag_utility_code = UtilityCode(
......@@ -1084,29 +1111,21 @@ proto="""
complex_from_parts_utility_code = UtilityCode(
proto_block='utility_code_proto',
proto="""
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#endif
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#endif
static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
""",
impl="""
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
return ::std::complex< %(real_type)s >(x, y);
}
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
return x + y*(%(type)s)_Complex_I;
}
#endif
#else
static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
%(type)s z;
z.real = x;
z.imag = y;
......@@ -1158,65 +1177,65 @@ proto="""
/*#define __Pyx_c_abs%(m)s(z) (cabs%(m)s(z))*/
#endif
#else
static INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
static INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
/*static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
/*static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
#endif
""",
impl="""
#if CYTHON_CCOMPLEX
#else
static INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
return (a.real == b.real) && (a.imag == b.imag);
}
static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
%(type)s z;
z.real = a.real + b.real;
z.imag = a.imag + b.imag;
return z;
}
static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
%(type)s z;
z.real = a.real - b.real;
z.imag = a.imag - b.imag;
return z;
}
static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
%(type)s z;
z.real = a.real * b.real - a.imag * b.imag;
z.imag = a.real * b.imag + a.imag * b.real;
return z;
}
static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
%(type)s z;
%(real_type)s denom = b.real * b.real + b.imag * b.imag;
z.real = (a.real * b.real + a.imag * b.imag) / denom;
z.imag = (a.imag * b.real - a.real * b.imag) / denom;
return z;
}
static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
%(type)s z;
z.real = -a.real;
z.imag = -a.imag;
return z;
}
static INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
return (a.real == 0) && (a.imag == 0);
}
static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
%(type)s z;
z.real = a.real;
z.imag = -a.imag;
return z;
}
/*
static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
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
......@@ -2005,7 +2024,6 @@ def widest_numeric_type(type1, type2):
return type1
else:
return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
return widest_type
def spanning_type(type1, type2):
# Return a type assignable from both type1 and type2.
......@@ -2015,11 +2033,21 @@ def spanning_type(type1, type2):
return type1
elif type1.is_numeric and type2.is_numeric:
return widest_numeric_type(type1, type2)
elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric:
return widest_numeric_type(c_double_type, type2)
elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric:
return widest_numeric_type(type1, c_double_type)
elif type1.is_pyobject ^ type2.is_pyobject:
return py_object_type
elif type1.assignable_from(type2):
if type1.is_extension_type and type1.typeobj_is_imported():
# external types are unsafe, so we use PyObject instead
return py_object_type
return type1
elif type2.assignable_from(type1):
if type2.is_extension_type and type2.typeobj_is_imported():
# external types are unsafe, so we use PyObject instead
return py_object_type
return type2
else:
return py_object_type
......@@ -2099,8 +2127,8 @@ type_conversion_predeclarations = """
#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) __Pyx_PyBytes_AsString(s))
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
#if !defined(T_PYSSIZET)
#if PY_VERSION_HEX < 0x02050000
......@@ -2164,9 +2192,9 @@ static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
#endif
#endif
static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
......@@ -2175,13 +2203,13 @@ static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
type_conversion_functions = """
/* Type Conversion Functions */
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
if (x == Py_True) return 1;
else if ((x == Py_False) | (x == Py_None)) return 0;
else return PyObject_IsTrue(x);
}
static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
PyNumberMethods *m;
const char *name = NULL;
PyObject *res = NULL;
......@@ -2227,7 +2255,7 @@ static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
return res;
}
static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
if (!x) return -1;
......@@ -2236,7 +2264,7 @@ static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
return ival;
}
static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
#if PY_VERSION_HEX < 0x02050000
if (ival <= LONG_MAX)
return PyInt_FromLong((long)ival);
......@@ -2250,7 +2278,7 @@ static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
#endif
}
static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
return (size_t)-1;
......
#
# Pyrex Scanner
# Cython Scanner
#
#import pickle
import cPickle as pickle
import os
import platform
import stat
......@@ -23,132 +20,17 @@ from Lexicon import string_prefixes, raw_prefixes, make_lexicon, IDENT
from StringEncoding import EncodedString
try:
plex_version = Plex._version
except AttributeError:
plex_version = None
#print "Plex version:", plex_version ###
debug_scanner = 0
trace_scanner = 0
scanner_debug_flags = 0
scanner_dump_file = None
binary_lexicon_pickle = 1
notify_lexicon_unpickling = 0
notify_lexicon_pickling = 1
lexicon = None
#-----------------------------------------------------------------
def hash_source_file(path):
# Try to calculate a hash code for the given source file.
# Returns an empty string if the file cannot be accessed.
#print "Hashing", path ###
try:
from hashlib import md5 as new_md5
except ImportError:
from md5 import new as new_md5
f = None
try:
try:
f = open(path, "rU")
text = f.read()
except IOError, e:
print("Unable to hash scanner source file (%s)" % e)
return ""
finally:
if f:
f.close()
# Normalise spaces/tabs. We don't know what sort of
# space-tab substitution the file may have been
# through, so we replace all spans of spaces and
# tabs by a single space.
import re
text = re.sub("[ \t]+", " ", text)
hash = new_md5(text.encode("ASCII")).hexdigest()
return hash
def open_pickled_lexicon(expected_hash):
# Try to open pickled lexicon file and verify that
# it matches the source file. Returns the opened
# file if successful, otherwise None. ???
global lexicon_pickle
f = None
result = None
if os.path.exists(lexicon_pickle):
try:
f = open(lexicon_pickle, "rb")
actual_hash = pickle.load(f)
if actual_hash == expected_hash:
result = f
f = None
else:
print("Lexicon hash mismatch:") ###
print(" expected " + expected_hash) ###
print(" got " + actual_hash) ###
except (IOError, pickle.UnpicklingError), e:
print("Warning: Unable to read pickled lexicon " + lexicon_pickle)
print(e)
if f:
f.close()
return result
def try_to_unpickle_lexicon():
global lexicon, lexicon_pickle, lexicon_hash
dir = os.path.dirname(__file__)
source_file = os.path.join(dir, "Lexicon.py")
lexicon_hash = hash_source_file(source_file)
lexicon_pickle = os.path.join(dir, "Lexicon.pickle")
f = open_pickled_lexicon(lexicon_hash)
if f:
if notify_lexicon_unpickling:
t0 = time()
print("Unpickling lexicon...")
try:
lexicon = pickle.load(f)
except Exception, e:
print "WARNING: Exception while loading lexicon pickle, regenerating"
print e
lexicon = None
f.close()
if notify_lexicon_unpickling:
t1 = time()
print("Done (%.2f seconds)" % (t1 - t0))
def create_new_lexicon():
global lexicon
t0 = time()
print("Creating lexicon...")
lexicon = make_lexicon()
t1 = time()
print("Done (%.2f seconds)" % (t1 - t0))
def pickle_lexicon():
f = None
try:
f = open(lexicon_pickle, "wb")
except IOError:
print("Warning: Unable to save pickled lexicon in " + lexicon_pickle)
if f:
if notify_lexicon_pickling:
t0 = time()
print("Pickling lexicon...")
pickle.dump(lexicon_hash, f, binary_lexicon_pickle)
pickle.dump(lexicon, f, binary_lexicon_pickle)
f.close()
if notify_lexicon_pickling:
t1 = time()
print("Done (%.2f seconds)" % (t1 - t0))
def get_lexicon():
global lexicon
if not lexicon and plex_version is None:
try_to_unpickle_lexicon()
if not lexicon:
create_new_lexicon()
if plex_version is None:
pickle_lexicon()
lexicon = make_lexicon()
return lexicon
#------------------------------------------------------------------
......
......@@ -637,6 +637,7 @@ class BuiltinScope(Scope):
var_entry.is_variable = 1
var_entry.is_cglobal = 1
var_entry.is_readonly = 1
var_entry.is_builtin = 1
var_entry.utility_code = utility_code
entry.as_variable = var_entry
......@@ -739,7 +740,8 @@ class ModuleScope(Scope):
return self
def declare_builtin(self, name, pos):
if not hasattr(builtins, name):
if not hasattr(builtins, name) and name != 'xrange':
# 'xrange' is special cased in Code.py
if self.has_import_star:
entry = self.declare_var(name, py_object_type, pos)
return entry
......@@ -899,7 +901,7 @@ class ModuleScope(Scope):
# Make a new entry if needed
#
if not entry:
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type)
type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
type.pos = pos
type.buffer_defaults = buffer_defaults
if objtypedef_cname is not None:
......@@ -1230,6 +1232,9 @@ class ClassScope(Scope):
return self.outer_scope.add_string_const(value, identifier)
def lookup(self, name):
entry = Scope.lookup(self, name)
if entry:
return entry
if name == "classmethod":
# We don't want to use the builtin classmethod here 'cause it won't do the
# right thing in this scope (as the class memebers aren't still functions).
......@@ -1244,8 +1249,6 @@ class ClassScope(Scope):
[PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
entry.is_cfunction = 1
return entry
else:
return Scope.lookup(self, name)
class PyClassScope(ClassScope):
......
......@@ -36,6 +36,11 @@ class TestTreePath(TransformTest):
self.assertEquals(2, len(find_all(t, "//NameNode/@name")))
self.assertEquals(['fun', 'decorator'], find_all(t, "//NameNode/@name"))
def test_node_path_attribute_dotted(self):
t = self._build_tree()
self.assertEquals(1, len(find_all(t, "//ReturnStatNode/@value.name")))
self.assertEquals(['fun'], find_all(t, "//ReturnStatNode/@value.name"))
def test_node_path_child(self):
t = self._build_tree()
self.assertEquals(1, len(find_all(t, "//DefNode/ReturnStatNode/NameNode")))
......
......@@ -7,6 +7,7 @@ specific descendant or a node that holds an attribute.
"""
import re
import sys
path_tokenizer = re.compile(
"("
......@@ -144,11 +145,21 @@ def handle_attribute(next, token):
else:
if token[0] == '=':
value = parse_path_value(next)
if sys.version_info >= (2,6) or (sys.version_info >= (2,4) and '.' not in name):
import operator
readattr = operator.attrgetter(name)
else:
name_path = name.split('.')
def readattr(node):
attr_value = node
for attr in name_path:
attr_value = getattr(attr_value, attr)
return attr_value
if value is None:
def select(result):
for node in result:
try:
attr_value = getattr(node, name)
attr_value = readattr(node)
except AttributeError:
continue
if attr_value is not None:
......@@ -157,11 +168,11 @@ def handle_attribute(next, token):
def select(result):
for node in result:
try:
attr_value = getattr(node, name)
attr_value = readattr(node)
except AttributeError:
continue
if attr_value == value:
yield value
yield attr_value
return select
def parse_path_value(next):
......
from Errors import error, warning, warn_once, InternalError
import ExprNodes
from PyrexTypes import py_object_type, unspecified_type, spanning_type
import Nodes
import Builtin
import PyrexTypes
from PyrexTypes import py_object_type, unspecified_type
from Visitor import CythonTransform
try:
......@@ -19,10 +23,9 @@ object_expr = TypedExprNode(py_object_type)
class MarkAssignments(CythonTransform):
def mark_assignment(self, lhs, rhs):
if isinstance(lhs, ExprNodes.NameNode):
if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)):
if lhs.entry is None:
# TODO: This shouldn't happen...
# It looks like comprehension loop targets are not declared soon enough.
return
lhs.entry.assignments.append(rhs)
elif isinstance(lhs, ExprNodes.SequenceNode):
......@@ -50,24 +53,23 @@ class MarkAssignments(CythonTransform):
def visit_ForInStatNode(self, node):
# TODO: Remove redundancy with range optimization...
is_range = False
is_special = False
sequence = node.iterator.sequence
if isinstance(sequence, ExprNodes.SimpleCallNode):
function = sequence.function
if sequence.self is None and \
isinstance(function, ExprNodes.NameNode) and \
function.name in ('range', 'xrange'):
is_range = True
self.mark_assignment(node.target, sequence.args[0])
if len(sequence.args) > 1:
self.mark_assignment(node.target, sequence.args[1])
if sequence.self is None and function.is_name:
if function.name in ('range', 'xrange'):
is_special = True
for arg in sequence.args[:2]:
self.mark_assignment(node.target, arg)
if len(sequence.args) > 2:
self.mark_assignment(node.target,
self.mark_assignment(
node.target,
ExprNodes.binop_node(node.pos,
'+',
sequence.args[0],
sequence.args[2]))
if not is_range:
if not is_special:
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
......@@ -99,6 +101,17 @@ class MarkAssignments(CythonTransform):
self.visitchildren(node)
return node
def visit_DefNode(self, node):
# use fake expressions with the right result type
if node.star_arg:
self.mark_assignment(
node.star_arg, TypedExprNode(Builtin.tuple_type))
if node.starstar_arg:
self.mark_assignment(
node.starstar_arg, TypedExprNode(Builtin.dict_type))
self.visitchildren(node)
return node
class PyObjectTypeInferer:
"""
......@@ -119,6 +132,18 @@ class SimpleAssignmentTypeInferer:
# TODO: Implement a real type inference algorithm.
# (Something more powerful than just extending this one...)
def infer_types(self, scope):
enabled = scope.directives['infer_types']
verbose = scope.directives['infer_types.verbose']
if enabled == True:
spanning_type = aggressive_spanning_type
elif enabled is None: # safe mode
spanning_type = safe_spanning_type
else:
for entry in scope.entries.values():
if entry.type is unspecified_type:
entry.type = py_object_type
return
dependancies_by_entry = {} # entry -> dependancies
entries_by_dependancy = {} # dependancy -> entries
ready_to_infer = []
......@@ -150,20 +175,22 @@ class SimpleAssignmentTypeInferer:
entry = ready_to_infer.pop()
types = [expr.infer_type(scope) for expr in entry.assignments]
if types:
entry.type = reduce(spanning_type, types)
entry.type = spanning_type(types)
else:
# List comprehension?
# FIXME: raise a warning?
# print "No assignments", entry.pos, entry
entry.type = py_object_type
if verbose:
warning(entry.pos, "inferred '%s' to be of type '%s'" % (entry.name, entry.type), 1)
resolve_dependancy(entry)
# Deal with simple circular dependancies...
for entry, deps in dependancies_by_entry.items():
if len(deps) == 1 and deps == set([entry]):
types = [expr.infer_type(scope) for expr in entry.assignments if expr.type_dependencies(scope) == ()]
if types:
entry.type = reduce(spanning_type, types)
entry.type = spanning_type(types)
types = [expr.infer_type(scope) for expr in entry.assignments]
entry.type = reduce(spanning_type, types) # might be wider...
entry.type = spanning_type(types) # might be wider...
resolve_dependancy(entry)
del dependancies_by_entry[entry]
if ready_to_infer:
......@@ -174,6 +201,42 @@ class SimpleAssignmentTypeInferer:
# We can't figure out the rest with this algorithm, let them be objects.
for entry in dependancies_by_entry:
entry.type = py_object_type
if verbose:
warning(entry.pos, "inferred '%s' to be of type '%s' (default)" % (entry.name, entry.type), 1)
def find_spanning_type(type1, type2):
if type1 is type2:
return type1
elif type1 is PyrexTypes.c_bint_type or type2 is PyrexTypes.c_bint_type:
# type inference can break the coercion back to a Python bool
# if it returns an arbitrary int type here
return py_object_type
result_type = PyrexTypes.spanning_type(type1, type2)
if result_type in (PyrexTypes.c_double_type, PyrexTypes.c_float_type, Builtin.float_type):
# Python's float type is just a C double, so it's safe to
# use the C type instead
return PyrexTypes.c_double_type
return result_type
def aggressive_spanning_type(types):
result_type = reduce(find_spanning_type, types)
return result_type
def safe_spanning_type(types):
result_type = reduce(find_spanning_type, types)
if result_type.is_pyobject:
# any specific Python type is always safe to infer
return result_type
elif result_type is PyrexTypes.c_double_type:
# Python's float type is just a C double, so it's safe to use
# the C type instead
return result_type
elif result_type is PyrexTypes.c_bint_type:
# find_spanning_type() only returns 'bint' for clean boolean
# operations without other int types, so this is safe, too
return result_type
return py_object_type
def get_type_inferer():
return SimpleAssignmentTypeInferer()
......@@ -83,6 +83,7 @@ class Signature(object):
return len(self.fixed_arg_format)
def is_self_arg(self, i):
# argument is 'self' for methods or 'class' for classmethods
return self.fixed_arg_format[i] == 'T'
def fixed_arg_type(self, i):
......
......@@ -127,6 +127,9 @@ class ResultRefNode(AtomicExprNode):
def analyse_types(self, env):
self.type = self.expression.type
def infer_type(self, env):
return self.expression.infer_type(env)
def result(self):
return self.result_code
......@@ -164,9 +167,9 @@ class LetNodeMixin:
def setup_temp_expr(self, code):
self.temp_expression.generate_evaluation_code(code)
self.result_in_temp = self.temp_expression.result_in_temp()
self._result_in_temp = self.temp_expression.result_in_temp()
self.temp_type = self.temp_expression.type
if self.result_in_temp:
if self._result_in_temp:
self.temp = self.temp_expression.result()
else:
self.temp_expression.make_owned_reference(code)
......@@ -176,7 +179,7 @@ class LetNodeMixin:
self.lazy_temp.result_code = self.temp
def teardown_temp_expr(self, code):
if not self.result_in_temp:
if not self._result_in_temp:
if self.temp_type.is_pyobject:
code.put_decref_clear(self.temp, self.temp_type)
code.funcstate.release_temp(self.temp)
......@@ -191,6 +194,11 @@ class EvalWithTempExprNode(ExprNodes.ExprNode, LetNodeMixin):
self.set_temp_expr(lazy_temp)
self.pos = subexpression.pos
self.subexpression = subexpression
# if called after type analysis, we already know the type here
self.type = self.subexpression.type
def infer_type(self, env):
return self.subexpression.infer_type(env)
def result(self):
return self.subexpression.result()
......
version = '0.12'
version = '0.12.1.beta0'
cimport cython
cdef class BasicVisitor:
cdef dict dispatch_table
cpdef visit(self, obj)
cpdef find_handler(self, obj)
cdef class TreeVisitor(BasicVisitor):
cdef public list access_path
cpdef visitchild(self, child, parent, attrname, idx)
@cython.locals(idx=int)
cpdef dict _visitchildren(self, parent, attrs)
# cpdef visitchildren(self, parent, attrs=*)
cdef class VisitorTransform(TreeVisitor):
......
# cython: infer_types=True
#
# Tree visitor and transform framework
#
......@@ -8,7 +10,6 @@ import ExprNodes
import Naming
import Errors
import DebugFlags
from StringEncoding import EncodedString
class BasicVisitor(object):
"""A generic visitor base class which can be used for visiting any kind of object."""
......@@ -19,10 +20,15 @@ class BasicVisitor(object):
self.dispatch_table = {}
def visit(self, obj):
cls = type(obj)
try:
handler_method = self.dispatch_table[cls]
handler_method = self.dispatch_table[type(obj)]
except KeyError:
handler_method = self.find_handler(obj)
self.dispatch_table[type(obj)] = handler_method
return handler_method(obj)
def find_handler(self, obj):
cls = type(obj)
#print "Cache miss for class %s in visitor %s" % (
# cls.__name__, type(self).__name__)
# Must resolve, try entire hierarchy
......@@ -34,7 +40,7 @@ class BasicVisitor(object):
handler_method = getattr(self, pattern % mro_cls.__name__)
break
if handler_method is None:
print type(self), type(obj)
print type(self), cls
if hasattr(self, 'access_path') and self.access_path:
print self.access_path
if self.access_path:
......@@ -42,8 +48,7 @@ class BasicVisitor(object):
print self.access_path[-1][0].__dict__
raise RuntimeError("Visitor does not accept object: %s" % obj)
#print "Caching " + cls.__name__
self.dispatch_table[cls] = handler_method
return handler_method(obj)
return handler_method
class TreeVisitor(BasicVisitor):
"""
......@@ -144,16 +149,8 @@ class TreeVisitor(BasicVisitor):
stacktrace = stacktrace.tb_next
return (last_traceback, nodes)
def visitchild(self, child, parent, attrname, idx):
self.access_path.append((parent, attrname, idx))
try:
result = self.visit(child)
except Errors.CompileError:
raise
except Exception, e:
def _raise_compiler_error(self, child, e):
import sys
if DebugFlags.debug_no_exception_intercept:
raise
trace = ['']
for parent, attribute, index in self.access_path:
node = getattr(parent, attribute)
......@@ -174,10 +171,24 @@ class TreeVisitor(BasicVisitor):
raise Errors.CompilerCrash(
last_node.pos, self.__class__.__name__,
u'\n'.join(trace), e, stacktrace)
def visitchild(self, child, parent, attrname, idx):
self.access_path.append((parent, attrname, idx))
try:
result = self.visit(child)
except Errors.CompileError:
raise
except Exception, e:
if DebugFlags.debug_no_exception_intercept:
raise
self._raise_compiler_error(child, e)
self.access_path.pop()
return result
def visitchildren(self, parent, attrs=None):
return self._visitchildren(parent, attrs)
def _visitchildren(self, parent, attrs):
"""
Visits the children of the given parent. If parent is None, returns
immediately (returning None).
......@@ -223,8 +234,7 @@ class VisitorTransform(TreeVisitor):
are within a StatListNode or similar before doing this.)
"""
def visitchildren(self, parent, attrs=None):
result = cython.declare(dict)
result = TreeVisitor.visitchildren(self, parent, attrs)
result = self._visitchildren(parent, attrs)
for attr, newnode in result.iteritems():
if not type(newnode) is list:
setattr(parent, attr, newnode)
......
......@@ -146,6 +146,7 @@ from python_getargs cimport *
# Python <= 2.x
from python_cobject cimport *
from python_oldbuffer cimport *
# Python >= 2.4
from python_set cimport *
......
# Legacy Python 2 buffer interface.
#
# These functions are no longer available in Python 3, use the new
# buffer interface instead.
cdef extern from "Python.h":
cdef enum _:
Py_END_OF_BUFFER
# This constant may be passed as the size parameter to
# PyBuffer_FromObject() or PyBuffer_FromReadWriteObject(). It
# indicates that the new PyBufferObject should refer to base object
# from the specified offset to the end of its exported
# buffer. Using this enables the caller to avoid querying the base
# object for its length.
bint PyBuffer_Check(object p)
# Return true if the argument has type PyBuffer_Type.
object PyBuffer_FromObject(object base, Py_ssize_t offset, Py_ssize_t size)
# Return value: New reference.
#
# Return a new read-only buffer object. This raises TypeError if
# base doesn't support the read-only buffer protocol or doesn't
# provide exactly one buffer segment, or it raises ValueError if
# offset is less than zero. The buffer will hold a reference to the
# base object, and the buffer's contents will refer to the base
# object's buffer interface, starting as position offset and
# extending for size bytes. If size is Py_END_OF_BUFFER, then the
# new buffer's contents extend to the length of the base object's
# exported buffer data.
object PyBuffer_FromReadWriteObject(object base, Py_ssize_t offset, Py_ssize_t size)
# Return value: New reference.
#
# Return a new writable buffer object. Parameters and exceptions
# are similar to those for PyBuffer_FromObject(). If the base
# object does not export the writeable buffer protocol, then
# TypeError is raised.
object PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
# Return value: New reference.
#
# Return a new read-only buffer object that reads from a specified
# location in memory, with a specified size. The caller is
# responsible for ensuring that the memory buffer, passed in as
# ptr, is not deallocated while the returned buffer object
# exists. Raises ValueError if size is less than zero. Note that
# Py_END_OF_BUFFER may not be passed for the size parameter;
# ValueError will be raised in that case.
object PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
# Return value: New reference.
#
# Similar to PyBuffer_FromMemory(), but the returned buffer is
# writable.
object PyBuffer_New(Py_ssize_t size)
# Return value: New reference.
#
# Return a new writable buffer object that maintains its own memory
# buffer of size bytes. ValueError is returned if size is not zero
# or positive. Note that the memory buffer (as returned by
# PyObject_AsWriteBuffer()) is not specifically aligned.
#
# Pyrex - Darwin system interface
#
verbose = 0
gcc_pendantic = True
gcc_warnings_are_errors = True
gcc_all_warnings = True
gcc_optimize = False
import os, sys
from Cython.Utils import replace_suffix
from Cython.Compiler.Errors import PyrexError
version_string = "%s.%s" % sys.version_info[:2]
py_include_dirs = [
"/Library/Frameworks/Python.framework/Versions/%s/Headers" % version_string
]
osx_version = os.popen('sw_vers | grep ProductVersion').read().split()[1]
# MACOSX_DEPLOYMENT_TARGET can be set to 10.3 in most cases.
# But for the built-in Python 2.5.1 on Leopard, it needs to be set for 10.5.
# This looks like a bug that will be fixed in 2.5.2. If Apple updates their
# Python to 2.5.2, this fix should be OK.
import distutils.sysconfig as sc
python_prefix = sc.get_config_var('prefix')
leopard_python_prefix = '/System/Library/Frameworks/Python.framework/Versions/2.5'
full_version = "%s.%s.%s" % sys.version_info[:3]
if python_prefix == leopard_python_prefix and full_version == '2.5.1':
os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.5"
elif osx_version >= "10.6":
os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.4"
else:
os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.3"
compilers = ["gcc", "g++"]
compiler_options = \
"-g -c -fno-strict-aliasing -no-cpp-precomp " \
"-mno-fused-madd -fno-common -dynamic " \
.split()
if gcc_pendantic:
compiler_options.extend(["-pedantic", "-Wno-long-long"])
if gcc_warnings_are_errors:
compiler_options.append("-Werror")
if gcc_all_warnings:
compiler_options.append("-Wall")
compiler_options.append("-Wno-unused-function")
if gcc_optimize:
compiler_options.append("-O")
linkers = ["gcc", "g++"]
linker_options = \
"-Wl,-F.,-w -bundle -undefined dynamic_lookup" \
.split()
#linker_options = \
# "-Wl,-F.,-w -bundle -framework Python" \
# .split()
class CCompilerError(PyrexError):
pass
def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
# Compile the given C source file to produce
# an object file. Returns the pathname of the
# resulting file.
c_file = os.path.join(os.getcwd(), c_file)
o_file = replace_suffix(c_file, obj_suffix)
include_options = []
for dir in py_include_dirs:
include_options.append("-I%s" % dir)
compiler = compilers[bool(cplus)]
args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
if verbose_flag or verbose:
print(" ".join(args))
#print compiler, args ###
status = os.spawnvp(os.P_WAIT, compiler, args)
if status != 0:
raise CCompilerError("C compiler returned status %s" % status)
return o_file
def c_link(obj_file, verbose_flag = 0, extra_objects = [], cplus = 0):
return c_link_list([obj_file] + extra_objects, verbose_flag, cplus)
def c_link_list(obj_files, verbose_flag = 0, cplus = 0):
# Link the given object files into a dynamically
# loadable extension file. Returns the pathname
# of the resulting file.
out_file = replace_suffix(obj_files[0], ".so")
linker = linkers[bool(cplus)]
args = [linker] + linker_options + obj_files + ["-o", out_file]
if verbose_flag or verbose:
print(" ".join(args))
status = os.spawnvp(os.P_WAIT, linker, args)
if status != 0:
raise CCompilerError("Linker returned status %s" % status)
return out_file
#
# Pyrex -- Mac system interface
#
import os, sys
import aetools
from aetools import TalkTo
from StdSuites.Standard_Suite import Standard_Suite_Events as Standard_Suite
from Cython.Utils import replace_suffix
from Cython.Compiler.Errors import PyrexError
c_compiler = "MWCPPC"
c_optimizations = "off"
#c_linker = "PPCLink"
c_linker = "MWLinkPPC"
shared_lib_suffix = ".slb"
#py_home = "Python2.2:Home:"
py_home = sys.exec_prefix
py_include_dirs = (
py_home + "Include:",
py_home + "Mac:Include:"
)
pythoncore = py_home + "PythonCore"
mwlibdir = "MPW:Interfaces&Libraries:Libraries:MWPPCLibraries:"
libraries = (
#mwlibdir + "'MSL C.PPC.Lib'",
#mwlibdir + "'MSL RuntimePPC.Lib'",
mwlibdir + "'MSL ShLibRuntime.Lib'",
mwlibdir + "InterfaceLib",
#mwlibdir + "MathLib",
)
class CCompilerError(PyrexError):
pass
#---------------- ToolServer ---------------------------
from TS_Misc_Suite import TS_Misc_Suite
class ToolServer(Standard_Suite, TS_Misc_Suite, TalkTo):
pass
def send_toolserver_command(cmd):
ts = ToolServer('MPSX', start = 1)
return ts.DoScript(cmd)
def do_toolserver_command(command):
try:
result = send_toolserver_command(command)
except aetools.Error, e:
raise CCompilerError("Apple Event error: %s" % e)
errn, stat, stdout, stderr = result
if errn:
raise CCompilerError("ToolServer error: %s" % errn)
stdout = stdout.replace("\r", "\n")
stderr = stderr.replace("\r", "\n")
if stdout:
#print "<<< Begin ToolServer StdOut >>>"
sys.stderr.write(stdout)
#print "<<< End ToolServer StdOut >>>"
if stderr:
#print "<<< Begin ToolServer StdErr >>>"
sys.stderr.write(stderr)
#print "<<< End ToolServer StdErr >>>"
return stat
#-------------------------------------------------------
def c_compile(c_file):
# Compile the given C source file to produce
# an object file. Returns the pathname of the
# resulting file.
c_file = os.path.join(os.getcwd(), c_file)
#print "c_compile: c_file =", repr(c_file) ###
c_file_dir = os.path.dirname(c_file)
o_file = replace_suffix(c_file, ".o")
include_options = ["-i %s" % c_file_dir]
for dir in py_include_dirs:
include_options.append("-i %s" % dir)
command = "%s -opt %s -nomapcr -w off -r %s %s -o %s" % (
c_compiler,
c_optimizations,
' '.join(include_options),
c_file,
o_file,
#e_file
)
#print "...command =", repr(command) ###
stat = do_toolserver_command(command)
if stat:
raise CCompilerError("C compiler returned status %s" % stat)
return o_file
def c_link(obj_file):
return c_link_list([obj_file])
def c_link_list(obj_files):
# Link the given object files into a dynamically
# loadable extension file. Returns the pathname
# of the resulting file.
out_file = replace_suffix(obj_files[0], shared_lib_suffix)
command = "%s -xm s -export all %s %s %s -o %s" % (
c_linker,
' '.join(obj_files),
pythoncore,
' '.join(libraries),
out_file)
stat = do_toolserver_command(command)
if stat:
raise CCompilerError("Linker returned status %s" % stat)
return out_file
def test_c_compile(link = 0):
objs = []
for arg in sys.argv[1:]:
if arg.endswith(".c"):
try:
obj = c_compile(arg)
except PyrexError, e:
#print "Caught a PyrexError:" ###
#print repr(e) ###
print("%s.%s: %s" % (e.__class__.__module__,
e.__class__.__name__, e))
sys.exit(1)
else:
obj = arg
objs.append(obj)
if link:
c_link_list(objs)
#
# Pyrex -- Misc Mac-specific things
#
import os, MacOS, macfs
def open_new_file(path):
# On the Mac, try to preserve Finder position
# of previously existing file.
fsspec = macfs.FSSpec(path)
try:
old_finfo = fsspec.GetFInfo()
except MacOS.Error, e:
#print "MacUtils.open_new_file:", e ###
old_finfo = None
try:
os.unlink(path)
except OSError:
pass
file = open(path, "w")
new_finfo = fsspec.GetFInfo()
if old_finfo:
#print "MacUtils.open_new_file:", path ###
#print "...old file info =", old_finfo.Creator, old_finfo.Type, old_finfo.Location ###
#print "...new file info =", new_finfo.Creator, new_finfo.Type, new_finfo.Location ###
new_finfo.Location = old_finfo.Location
new_finfo.Flags = old_finfo.Flags
# Make darn sure the type and creator are right. There seems
# to be a bug in MacPython 2.2 that screws them up sometimes.
new_finfo.Creator = "R*ch"
new_finfo.Type = "TEXT"
fsspec.SetFInfo(new_finfo)
return file
# Makefile for Darwin
# Change this to your Python source location
PYTHON := /Local/Build/Pythonic/python/2.3
INCLUDE := -I$(PYTHON) -I$(PYTHON)/Include -I$(PYTHON)/Mac/Include
CCOPTS := -fno-strict-aliasing -no-cpp-precomp \
-mno-fused-madd -fno-common -dynamic
LDOPTS := -Wl,-F.,-w -bundle -framework Python -framework Carbon
all: _File.so
_File.o: _Filemodule_patched.c
gcc -c $(INCLUDE) $(OPTS) $< -o $@
_File.so: _File.o
gcc $(LDOPTS) $< -o $@
"""Suite Misc Suite: Suite that adds additional features to the Application.
Level 1, version 1
Generated from Macintosh HD:Desktop Folder:ToolServer 3.4.1:ToolServer
AETE/AEUT resource version 1/0, language 0, script 0
"""
import aetools
import MacOS
_code = 'misc'
class TS_Misc_Suite(object):
def DoScript(self, _object, _attributes={}, **_arguments):
"""DoScript: Execute an MPW command, any command that could be executed from the command line can be sent as a script.
Required argument: The script to execute
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'misc'
_subcode = 'dosc'
if _arguments: raise TypeError('No optional args expected')
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
#if _arguments.has_key('errn'):
# raise aetools.Error, aetools.decodeerror(_arguments)
# XXXX Optionally decode result
#if _arguments.has_key('----'):
# return _arguments['----']
errn = 0
stat = 0
stdout = ""
stderr = ""
if 'errn' in _arguments:
errn = _arguments['errn']
if errn:
errn = aetools.decodeerror(_arguments)
if 'stat' in _arguments:
stat = _arguments['stat']
if '----' in _arguments:
stdout = _arguments['----']
if 'diag' in _arguments:
stderr = _arguments['diag']
return (errn, stat, stdout, stderr)
#
# Indices of types declared in this module
#
_classdeclarations = {
}
_propdeclarations = {
}
_compdeclarations = {
}
_enumdeclarations = {
}
/*
* This is a hacked version of _Filemodule.c from the Python 2.3
* distribution to support access to the finderInfo field of the
* FSCatalogInfo data structure.
*/
/* ========================== Module _File ========================== */
#include "Python.h"
#ifdef _WIN32
#include "pywintoolbox.h"
#else
#include "macglue.h"
#include "pymactoolbox.h"
#endif
/* Macro to test whether a weak-loaded CFM function exists */
#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\
PyErr_SetString(PyExc_NotImplementedError, \
"Not available in this shared library/OS version"); \
return NULL; \
}} while(0)
#ifdef WITHOUT_FRAMEWORKS
#include <Files.h>
#else
#include <Carbon/Carbon.h>
#endif
#ifdef USE_TOOLBOX_OBJECT_GLUE
extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
#define PyMac_GetFSSpec _PyMac_GetFSSpec
#define PyMac_GetFSRef _PyMac_GetFSRef
#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
#define PyMac_BuildFSRef _PyMac_BuildFSRef
#else
extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
extern PyObject *PyMac_BuildFSRef(FSRef *spec);
#endif
/* Forward declarations */
static PyObject *FInfo_New(FInfo *itself);
static PyObject *FSRef_New(FSRef *itself);
static PyObject *FSSpec_New(FSSpec *itself);
static PyObject *Alias_New(AliasHandle itself);
static int FInfo_Convert(PyObject *v, FInfo *p_itself);
#define FSRef_Convert PyMac_GetFSRef
#define FSSpec_Convert PyMac_GetFSSpec
static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
/*
** UTCDateTime records
*/
static int
UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
{
return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
}
static PyObject *
UTCDateTime_New(UTCDateTime *ptr)
{
return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction);
}
/*
** Optional fsspec and fsref pointers. None will pass NULL
*/
static int
myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
{
if (v == Py_None) {
*spec = NULL;
return 1;
}
return PyMac_GetFSSpec(v, *spec);
}
static int
myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
{
if (v == Py_None) {
*ref = NULL;
return 1;
}
return PyMac_GetFSRef(v, *ref);
}
/*
** Parse/generate objsect
*/
static PyObject *
PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
{
return Py_BuildValue("u#", itself->unicode, itself->length);
}
static PyObject *File_Error;
static PyTypeObject FInfo_Type;
#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
typedef struct FInfoObject {
PyObject_HEAD
FInfo ob_itself;
} FInfoObject;
/* ------------------- Object type FSCatalogInfo -------------------- */
static PyTypeObject FSCatalogInfo_Type;
#define FSCatalogInfo_Check(x) ((x)->ob_type == &FSCatalogInfo_Type || PyObject_TypeCheck((x), &FSCatalogInfo_Type))
typedef struct FSCatalogInfoObject {
PyObject_HEAD
FSCatalogInfo ob_itself;
} FSCatalogInfoObject;
static PyObject *FSCatalogInfo_New(FSCatalogInfo *itself)
{
FSCatalogInfoObject *it;
if (itself == NULL) return Py_None;
it = PyObject_NEW(FSCatalogInfoObject, &FSCatalogInfo_Type);
if (it == NULL) return NULL;
it->ob_itself = *itself;
return (PyObject *)it;
}
static int FSCatalogInfo_Convert(PyObject *v, FSCatalogInfo *p_itself)
{
if (!FSCatalogInfo_Check(v))
{
PyErr_SetString(PyExc_TypeError, "FSCatalogInfo required");
return 0;
}
*p_itself = ((FSCatalogInfoObject *)v)->ob_itself;
return 1;
}
static void FSCatalogInfo_dealloc(FSCatalogInfoObject *self)
{
/* Cleanup of self->ob_itself goes here */
self->ob_type->tp_free((PyObject *)self);
}
static PyMethodDef FSCatalogInfo_methods[] = {
{NULL, NULL, 0}
};
static PyObject *FSCatalogInfo_get_nodeFlags(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("H", self->ob_itself.nodeFlags);
}
static int FSCatalogInfo_set_nodeFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "H", &self->ob_itself.nodeFlags)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_volume(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("h", self->ob_itself.volume);
}
static int FSCatalogInfo_set_volume(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "h", &self->ob_itself.volume)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_parentDirID(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.parentDirID);
}
static int FSCatalogInfo_set_parentDirID(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.parentDirID)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_nodeID(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.nodeID);
}
static int FSCatalogInfo_set_nodeID(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.nodeID)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_createDate(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.createDate);
}
static int FSCatalogInfo_set_createDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.createDate)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_contentModDate(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.contentModDate);
}
static int FSCatalogInfo_set_contentModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_attributeModDate(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.attributeModDate);
}
static int FSCatalogInfo_set_attributeModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_accessDate(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.accessDate);
}
static int FSCatalogInfo_set_accessDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_backupDate(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.backupDate);
}
static int FSCatalogInfo_set_backupDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_permissions(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("(llll)", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);
}
static int FSCatalogInfo_set_permissions(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "(llll)", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;
return 0;
}
static PyObject *FSCatalogInfo_get_valence(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.valence);
}
static int FSCatalogInfo_set_valence(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.valence)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_dataLogicalSize(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.dataLogicalSize);
}
static int FSCatalogInfo_set_dataLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.dataLogicalSize)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_dataPhysicalSize(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.dataPhysicalSize);
}
static int FSCatalogInfo_set_dataPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.dataPhysicalSize)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_rsrcLogicalSize(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.rsrcLogicalSize);
}
static int FSCatalogInfo_set_rsrcLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.rsrcLogicalSize)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_rsrcPhysicalSize(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.rsrcPhysicalSize);
}
static int FSCatalogInfo_set_rsrcPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.rsrcPhysicalSize)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_sharingFlags(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("l", self->ob_itself.sharingFlags);
}
static int FSCatalogInfo_set_sharingFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "l", &self->ob_itself.sharingFlags)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_userPrivileges(FSCatalogInfoObject *self, void *closure)
{
return Py_BuildValue("b", self->ob_itself.userPrivileges);
}
static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "b", &self->ob_itself.userPrivileges)-1;
return 0;
}
static PyObject *FSCatalogInfo_get_finderInfo(FSCatalogInfoObject *self, void *closure)
{
return FInfo_New((FInfo *)self->ob_itself.finderInfo);
}
static int FSCatalogInfo_set_finderInfo(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
if (!FInfo_Check(v)) {
PyErr_SetString(PyExc_TypeError, "Expected an FInfo object");
return -1;
}
*(FInfo *)self->ob_itself.finderInfo = ((FInfoObject *)v)->ob_itself;
return 0;
}
static PyGetSetDef FSCatalogInfo_getsetlist[] = {
{"nodeFlags", (getter)FSCatalogInfo_get_nodeFlags, (setter)FSCatalogInfo_set_nodeFlags, NULL},
{"volume", (getter)FSCatalogInfo_get_volume, (setter)FSCatalogInfo_set_volume, NULL},
{"parentDirID", (getter)FSCatalogInfo_get_parentDirID, (setter)FSCatalogInfo_set_parentDirID, NULL},
{"nodeID", (getter)FSCatalogInfo_get_nodeID, (setter)FSCatalogInfo_set_nodeID, NULL},
{"createDate", (getter)FSCatalogInfo_get_createDate, (setter)FSCatalogInfo_set_createDate, NULL},
{"contentModDate", (getter)FSCatalogInfo_get_contentModDate, (setter)FSCatalogInfo_set_contentModDate, NULL},
{"attributeModDate", (getter)FSCatalogInfo_get_attributeModDate, (setter)FSCatalogInfo_set_attributeModDate, NULL},
{"accessDate", (getter)FSCatalogInfo_get_accessDate, (setter)FSCatalogInfo_set_accessDate, NULL},
{"backupDate", (getter)FSCatalogInfo_get_backupDate, (setter)FSCatalogInfo_set_backupDate, NULL},
{"permissions", (getter)FSCatalogInfo_get_permissions, (setter)FSCatalogInfo_set_permissions, NULL},
{"valence", (getter)FSCatalogInfo_get_valence, (setter)FSCatalogInfo_set_valence, NULL},
{"dataLogicalSize", (getter)FSCatalogInfo_get_dataLogicalSize, (setter)FSCatalogInfo_set_dataLogicalSize, NULL},
{"dataPhysicalSize", (getter)FSCatalogInfo_get_dataPhysicalSize, (setter)FSCatalogInfo_set_dataPhysicalSize, NULL},
{"rsrcLogicalSize", (getter)FSCatalogInfo_get_rsrcLogicalSize, (setter)FSCatalogInfo_set_rsrcLogicalSize, NULL},
{"rsrcPhysicalSize", (getter)FSCatalogInfo_get_rsrcPhysicalSize, (setter)FSCatalogInfo_set_rsrcPhysicalSize, NULL},
{"sharingFlags", (getter)FSCatalogInfo_get_sharingFlags, (setter)FSCatalogInfo_set_sharingFlags, NULL},
{"userPrivileges", (getter)FSCatalogInfo_get_userPrivileges, (setter)FSCatalogInfo_set_userPrivileges, NULL},
{"finderInfo", (getter)FSCatalogInfo_get_finderInfo, (setter)FSCatalogInfo_set_finderInfo, NULL},
{NULL, NULL, NULL, NULL},
};
#define FSCatalogInfo_compare NULL
#define FSCatalogInfo_repr NULL
#define FSCatalogInfo_hash NULL
static int FSCatalogInfo_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kw[] = {
"nodeFlags",
"volume",
"parentDirID",
"nodeID",
"createDate",
"contentModDate",
"atributeModDate",
"accessDate",
"backupDate",
"valence",
"dataLogicalSize",
"dataPhysicalSize",
"rsrcLogicalSize",
"rsrcPhysicalSize",
"sharingFlags",
"userPrivileges"
, 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|HhllO&O&O&O&O&llllllb", kw, &((FSCatalogInfoObject *)self)->ob_itself.nodeFlags,
&((FSCatalogInfoObject *)self)->ob_itself.volume,
&((FSCatalogInfoObject *)self)->ob_itself.parentDirID,
&((FSCatalogInfoObject *)self)->ob_itself.nodeID,
UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate,
UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate,
UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate,
UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate,
UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate,
&((FSCatalogInfoObject *)self)->ob_itself.valence,
&((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize,
&((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize,
&((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize,
&((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize,
&((FSCatalogInfoObject *)self)->ob_itself.sharingFlags,
&((FSCatalogInfoObject *)self)->ob_itself.userPrivileges))
{
return -1;
}
return 0;
}
#define FSCatalogInfo_tp_alloc PyType_GenericAlloc
static PyObject *FSCatalogInfo_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
memset(&((FSCatalogInfoObject *)self)->ob_itself, 0, sizeof(FSCatalogInfo));
return self;
}
#define FSCatalogInfo_tp_free PyObject_Del
static PyTypeObject FSCatalogInfo_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Carbon.File.FSCatalogInfo", /*tp_name*/
sizeof(FSCatalogInfoObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) FSCatalogInfo_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc) FSCatalogInfo_compare, /*tp_compare*/
(reprfunc) FSCatalogInfo_repr, /*tp_repr*/
(PyNumberMethods *)0, /* tp_as_number */
(PySequenceMethods *)0, /* tp_as_sequence */
(PyMappingMethods *)0, /* tp_as_mapping */
(hashfunc) FSCatalogInfo_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
PyObject_GenericGetAttr, /*tp_getattro*/
PyObject_GenericSetAttr, /*tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
FSCatalogInfo_methods, /* tp_methods */
0, /*tp_members*/
FSCatalogInfo_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
FSCatalogInfo_tp_init, /* tp_init */
FSCatalogInfo_tp_alloc, /* tp_alloc */
FSCatalogInfo_tp_new, /* tp_new */
FSCatalogInfo_tp_free, /* tp_free */
};
/* ----------------- End object type FSCatalogInfo ------------------ */
/* ----------------------- Object type FInfo ------------------------ */
static PyObject *FInfo_New(FInfo *itself)
{
FInfoObject *it;
if (itself == NULL) return PyMac_Error(resNotFound);
it = PyObject_NEW(FInfoObject, &FInfo_Type);
if (it == NULL) return NULL;
it->ob_itself = *itself;
return (PyObject *)it;
}
static int FInfo_Convert(PyObject *v, FInfo *p_itself)
{
if (!FInfo_Check(v))
{
PyErr_SetString(PyExc_TypeError, "FInfo required");
return 0;
}
*p_itself = ((FInfoObject *)v)->ob_itself;
return 1;
}
static void FInfo_dealloc(FInfoObject *self)
{
/* Cleanup of self->ob_itself goes here */
self->ob_type->tp_free((PyObject *)self);
}
static PyMethodDef FInfo_methods[] = {
{NULL, NULL, 0}
};
static PyObject *FInfo_get_Type(FInfoObject *self, void *closure)
{
return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdType);
}
static int FInfo_set_Type(FInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdType)-1;
return 0;
}
static PyObject *FInfo_get_Creator(FInfoObject *self, void *closure)
{
return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdCreator);
}
static int FInfo_set_Creator(FInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;
return 0;
}
static PyObject *FInfo_get_Flags(FInfoObject *self, void *closure)
{
return Py_BuildValue("H", self->ob_itself.fdFlags);
}
static int FInfo_set_Flags(FInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "H", &self->ob_itself.fdFlags)-1;
return 0;
}
static PyObject *FInfo_get_Location(FInfoObject *self, void *closure)
{
return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself.fdLocation);
}
static int FInfo_set_Location(FInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "O&", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;
return 0;
}
static PyObject *FInfo_get_Fldr(FInfoObject *self, void *closure)
{
return Py_BuildValue("h", self->ob_itself.fdFldr);
}
static int FInfo_set_Fldr(FInfoObject *self, PyObject *v, void *closure)
{
return PyArg_Parse(v, "h", &self->ob_itself.fdFldr)-1;
return 0;
}
static PyGetSetDef FInfo_getsetlist[] = {
{"Type", (getter)FInfo_get_Type, (setter)FInfo_set_Type, "4-char file type"},
{"Creator", (getter)FInfo_get_Creator, (setter)FInfo_set_Creator, "4-char file creator"},
{"Flags", (getter)FInfo_get_Flags, (setter)FInfo_set_Flags, "Finder flag bits"},
{"Location", (getter)FInfo_get_Location, (setter)FInfo_set_Location, "(x, y) location of the file's icon in its parent finder window"},
{"Fldr", (getter)FInfo_get_Fldr, (setter)FInfo_set_Fldr, "Original folder, for 'put away'"},
{NULL, NULL, NULL, NULL},
};
#define FInfo_compare NULL
#define FInfo_repr NULL
#define FInfo_hash NULL
static int FInfo_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
{
FInfo *itself = NULL;
static char *kw[] = {"itself", 0};
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kw, FInfo_Convert, &itself))
{
if (itself) memcpy(&((FInfoObject *)self)->ob_itself, itself, sizeof(FInfo));
return 0;
}
return -1;
}
#define FInfo_tp_alloc PyType_GenericAlloc
static PyObject *FInfo_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
memset(&((FInfoObject *)self)->ob_itself, 0, sizeof(FInfo));
return self;
}
#define FInfo_tp_free PyObject_Del
static PyTypeObject FInfo_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Carbon.File.FInfo", /*tp_name*/
sizeof(FInfoObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) FInfo_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc) FInfo_compare, /*tp_compare*/
(reprfunc) FInfo_repr, /*tp_repr*/
(PyNumberMethods *)0, /* tp_as_number */
(PySequenceMethods *)0, /* tp_as_sequence */
(PyMappingMethods *)0, /* tp_as_mapping */
(hashfunc) FInfo_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
PyObject_GenericGetAttr, /*tp_getattro*/
PyObject_GenericSetAttr, /*tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
FInfo_methods, /* tp_methods */
0, /*tp_members*/
FInfo_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
FInfo_tp_init, /* tp_init */
FInfo_tp_alloc, /* tp_alloc */
FInfo_tp_new, /* tp_new */
FInfo_tp_free, /* tp_free */
};
/* --------------------- End object type FInfo ---------------------- */
/* ----------------------- Object type Alias ------------------------ */
static PyTypeObject Alias_Type;
#define Alias_Check(x) ((x)->ob_type == &Alias_Type || PyObject_TypeCheck((x), &Alias_Type))
typedef struct AliasObject {
PyObject_HEAD
AliasHandle ob_itself;
void (*ob_freeit)(AliasHandle ptr);
} AliasObject;
static PyObject *Alias_New(AliasHandle itself)
{
AliasObject *it;
if (itself == NULL) return PyMac_Error(resNotFound);
it = PyObject_NEW(AliasObject, &Alias_Type);
if (it == NULL) return NULL;
it->ob_itself = itself;
it->ob_freeit = NULL;
return (PyObject *)it;
}
static int Alias_Convert(PyObject *v, AliasHandle *p_itself)
{
if (!Alias_Check(v))
{
PyErr_SetString(PyExc_TypeError, "Alias required");
return 0;
}
*p_itself = ((AliasObject *)v)->ob_itself;
return 1;
}
static void Alias_dealloc(AliasObject *self)
{
if (self->ob_freeit && self->ob_itself)
{
self->ob_freeit(self->ob_itself);
}
self->ob_itself = NULL;
self->ob_type->tp_free((PyObject *)self);
}
static PyObject *Alias_ResolveAlias(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec fromFile__buf__;
FSSpec *fromFile = &fromFile__buf__;
FSSpec target;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "O&",
myPyMac_GetOptFSSpecPtr, &fromFile))
return NULL;
_err = ResolveAlias(fromFile,
_self->ob_itself,
&target,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSSpec_New, &target,
wasChanged);
return _res;
}
static PyObject *Alias_GetAliasInfo(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
AliasInfoType index;
Str63 theString;
if (!PyArg_ParseTuple(_args, "h",
&index))
return NULL;
_err = GetAliasInfo(_self->ob_itself,
index,
theString);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
PyMac_BuildStr255, theString);
return _res;
}
static PyObject *Alias_ResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec fromFile__buf__;
FSSpec *fromFile = &fromFile__buf__;
FSSpec target;
Boolean wasChanged;
unsigned long mountFlags;
if (!PyArg_ParseTuple(_args, "O&l",
myPyMac_GetOptFSSpecPtr, &fromFile,
&mountFlags))
return NULL;
_err = ResolveAliasWithMountFlags(fromFile,
_self->ob_itself,
&target,
&wasChanged,
mountFlags);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSSpec_New, &target,
wasChanged);
return _res;
}
static PyObject *Alias_FollowFinderAlias(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec fromFile__buf__;
FSSpec *fromFile = &fromFile__buf__;
Boolean logon;
FSSpec target;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "O&b",
myPyMac_GetOptFSSpecPtr, &fromFile,
&logon))
return NULL;
_err = FollowFinderAlias(fromFile,
_self->ob_itself,
logon,
&target,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSSpec_New, &target,
wasChanged);
return _res;
}
static PyObject *Alias_FSResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef fromFile__buf__;
FSRef *fromFile = &fromFile__buf__;
FSRef target;
Boolean wasChanged;
unsigned long mountFlags;
if (!PyArg_ParseTuple(_args, "O&l",
myPyMac_GetOptFSRefPtr, &fromFile,
&mountFlags))
return NULL;
_err = FSResolveAliasWithMountFlags(fromFile,
_self->ob_itself,
&target,
&wasChanged,
mountFlags);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSRef_New, &target,
wasChanged);
return _res;
}
static PyObject *Alias_FSResolveAlias(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef fromFile__buf__;
FSRef *fromFile = &fromFile__buf__;
FSRef target;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "O&",
myPyMac_GetOptFSRefPtr, &fromFile))
return NULL;
_err = FSResolveAlias(fromFile,
_self->ob_itself,
&target,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSRef_New, &target,
wasChanged);
return _res;
}
static PyObject *Alias_FSFollowFinderAlias(AliasObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef fromFile;
Boolean logon;
FSRef target;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "b",
&logon))
return NULL;
_err = FSFollowFinderAlias(&fromFile,
_self->ob_itself,
logon,
&target,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&O&b",
FSRef_New, &fromFile,
FSRef_New, &target,
wasChanged);
return _res;
}
static PyMethodDef Alias_methods[] = {
{"ResolveAlias", (PyCFunction)Alias_ResolveAlias, 1,
PyDoc_STR("(FSSpec fromFile) -> (FSSpec target, Boolean wasChanged)")},
{"GetAliasInfo", (PyCFunction)Alias_GetAliasInfo, 1,
PyDoc_STR("(AliasInfoType index) -> (Str63 theString)")},
{"ResolveAliasWithMountFlags", (PyCFunction)Alias_ResolveAliasWithMountFlags, 1,
PyDoc_STR("(FSSpec fromFile, unsigned long mountFlags) -> (FSSpec target, Boolean wasChanged)")},
{"FollowFinderAlias", (PyCFunction)Alias_FollowFinderAlias, 1,
PyDoc_STR("(FSSpec fromFile, Boolean logon) -> (FSSpec target, Boolean wasChanged)")},
{"FSResolveAliasWithMountFlags", (PyCFunction)Alias_FSResolveAliasWithMountFlags, 1,
PyDoc_STR("(FSRef fromFile, unsigned long mountFlags) -> (FSRef target, Boolean wasChanged)")},
{"FSResolveAlias", (PyCFunction)Alias_FSResolveAlias, 1,
PyDoc_STR("(FSRef fromFile) -> (FSRef target, Boolean wasChanged)")},
{"FSFollowFinderAlias", (PyCFunction)Alias_FSFollowFinderAlias, 1,
PyDoc_STR("(Boolean logon) -> (FSRef fromFile, FSRef target, Boolean wasChanged)")},
{NULL, NULL, 0}
};
static PyObject *Alias_get_data(AliasObject *self, void *closure)
{
int size;
PyObject *rv;
size = GetHandleSize((Handle)self->ob_itself);
HLock((Handle)self->ob_itself);
rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
HUnlock((Handle)self->ob_itself);
return rv;
}
#define Alias_set_data NULL
static PyGetSetDef Alias_getsetlist[] = {
{"data", (getter)Alias_get_data, (setter)Alias_set_data, "Raw data of the alias object"},
{NULL, NULL, NULL, NULL},
};
#define Alias_compare NULL
#define Alias_repr NULL
#define Alias_hash NULL
static int Alias_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
{
AliasHandle itself = NULL;
char *rawdata = NULL;
int rawdatalen = 0;
Handle h;
static char *kw[] = {"itself", "rawdata", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&s#", kw, Alias_Convert, &itself, &rawdata, &rawdatalen))
return -1;
if (itself && rawdata)
{
PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
return -1;
}
if (!itself && !rawdata)
{
PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
return -1;
}
if (rawdata)
{
if ((h = NewHandle(rawdatalen)) == NULL)
{
PyErr_NoMemory();
return -1;
}
HLock(h);
memcpy((char *)*h, rawdata, rawdatalen);
HUnlock(h);
((AliasObject *)self)->ob_itself = (AliasHandle)h;
return 0;
}
((AliasObject *)self)->ob_itself = itself;
return 0;
}
#define Alias_tp_alloc PyType_GenericAlloc
static PyObject *Alias_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
((AliasObject *)self)->ob_itself = NULL;
return self;
}
#define Alias_tp_free PyObject_Del
static PyTypeObject Alias_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Carbon.File.Alias", /*tp_name*/
sizeof(AliasObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) Alias_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc) Alias_compare, /*tp_compare*/
(reprfunc) Alias_repr, /*tp_repr*/
(PyNumberMethods *)0, /* tp_as_number */
(PySequenceMethods *)0, /* tp_as_sequence */
(PyMappingMethods *)0, /* tp_as_mapping */
(hashfunc) Alias_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
PyObject_GenericGetAttr, /*tp_getattro*/
PyObject_GenericSetAttr, /*tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
Alias_methods, /* tp_methods */
0, /*tp_members*/
Alias_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
Alias_tp_init, /* tp_init */
Alias_tp_alloc, /* tp_alloc */
Alias_tp_new, /* tp_new */
Alias_tp_free, /* tp_free */
};
/* --------------------- End object type Alias ---------------------- */
/* ----------------------- Object type FSSpec ----------------------- */
static PyTypeObject FSSpec_Type;
#define FSSpec_Check(x) ((x)->ob_type == &FSSpec_Type || PyObject_TypeCheck((x), &FSSpec_Type))
typedef struct FSSpecObject {
PyObject_HEAD
FSSpec ob_itself;
} FSSpecObject;
static PyObject *FSSpec_New(FSSpec *itself)
{
FSSpecObject *it;
if (itself == NULL) return PyMac_Error(resNotFound);
it = PyObject_NEW(FSSpecObject, &FSSpec_Type);
if (it == NULL) return NULL;
it->ob_itself = *itself;
return (PyObject *)it;
}
static void FSSpec_dealloc(FSSpecObject *self)
{
/* Cleanup of self->ob_itself goes here */
self->ob_type->tp_free((PyObject *)self);
}
static PyObject *FSSpec_FSpOpenDF(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt8 permission;
short refNum;
if (!PyArg_ParseTuple(_args, "b",
&permission))
return NULL;
_err = FSpOpenDF(&_self->ob_itself,
permission,
&refNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
refNum);
return _res;
}
static PyObject *FSSpec_FSpOpenRF(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt8 permission;
short refNum;
if (!PyArg_ParseTuple(_args, "b",
&permission))
return NULL;
_err = FSpOpenRF(&_self->ob_itself,
permission,
&refNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
refNum);
return _res;
}
static PyObject *FSSpec_FSpCreate(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
OSType creator;
OSType fileType;
ScriptCode scriptTag;
if (!PyArg_ParseTuple(_args, "O&O&h",
PyMac_GetOSType, &creator,
PyMac_GetOSType, &fileType,
&scriptTag))
return NULL;
_err = FSpCreate(&_self->ob_itself,
creator,
fileType,
scriptTag);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpDirCreate(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
ScriptCode scriptTag;
long createdDirID;
if (!PyArg_ParseTuple(_args, "h",
&scriptTag))
return NULL;
_err = FSpDirCreate(&_self->ob_itself,
scriptTag,
&createdDirID);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
createdDirID);
return _res;
}
static PyObject *FSSpec_FSpDelete(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSpDelete(&_self->ob_itself);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpGetFInfo(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FInfo fndrInfo;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSpGetFInfo(&_self->ob_itself,
&fndrInfo);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FInfo_New, &fndrInfo);
return _res;
}
static PyObject *FSSpec_FSpSetFInfo(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FInfo fndrInfo;
if (!PyArg_ParseTuple(_args, "O&",
FInfo_Convert, &fndrInfo))
return NULL;
_err = FSpSetFInfo(&_self->ob_itself,
&fndrInfo);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpSetFLock(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSpSetFLock(&_self->ob_itself);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpRstFLock(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSpRstFLock(&_self->ob_itself);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpRename(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Str255 newName;
if (!PyArg_ParseTuple(_args, "O&",
PyMac_GetStr255, newName))
return NULL;
_err = FSpRename(&_self->ob_itself,
newName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpCatMove(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec dest;
if (!PyArg_ParseTuple(_args, "O&",
FSSpec_Convert, &dest))
return NULL;
_err = FSpCatMove(&_self->ob_itself,
&dest);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpExchangeFiles(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec dest;
if (!PyArg_ParseTuple(_args, "O&",
FSSpec_Convert, &dest))
return NULL;
_err = FSpExchangeFiles(&_self->ob_itself,
&dest);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSSpec_FSpMakeFSRef(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef newRef;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSpMakeFSRef(&_self->ob_itself,
&newRef);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FSRef_New, &newRef);
return _res;
}
static PyObject *FSSpec_NewAliasMinimal(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
AliasHandle alias;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = NewAliasMinimal(&_self->ob_itself,
&alias);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
Alias_New, alias);
return _res;
}
static PyObject *FSSpec_IsAliasFile(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Boolean aliasFileFlag;
Boolean folderFlag;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = IsAliasFile(&_self->ob_itself,
&aliasFileFlag,
&folderFlag);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("bb",
aliasFileFlag,
folderFlag);
return _res;
}
static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
char strbuf[1024];
OSErr err;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
if ( err ) {
PyMac_Error(err);
return NULL;
}
_res = PyString_FromString(strbuf);
return _res;
}
static PyObject *FSSpec_as_tuple(FSSpecObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
&_self->ob_itself.name[1], _self->ob_itself.name[0]);
return _res;
}
static PyMethodDef FSSpec_methods[] = {
{"FSpOpenDF", (PyCFunction)FSSpec_FSpOpenDF, 1,
PyDoc_STR("(SInt8 permission) -> (short refNum)")},
{"FSpOpenRF", (PyCFunction)FSSpec_FSpOpenRF, 1,
PyDoc_STR("(SInt8 permission) -> (short refNum)")},
{"FSpCreate", (PyCFunction)FSSpec_FSpCreate, 1,
PyDoc_STR("(OSType creator, OSType fileType, ScriptCode scriptTag) -> None")},
{"FSpDirCreate", (PyCFunction)FSSpec_FSpDirCreate, 1,
PyDoc_STR("(ScriptCode scriptTag) -> (long createdDirID)")},
{"FSpDelete", (PyCFunction)FSSpec_FSpDelete, 1,
PyDoc_STR("() -> None")},
{"FSpGetFInfo", (PyCFunction)FSSpec_FSpGetFInfo, 1,
PyDoc_STR("() -> (FInfo fndrInfo)")},
{"FSpSetFInfo", (PyCFunction)FSSpec_FSpSetFInfo, 1,
PyDoc_STR("(FInfo fndrInfo) -> None")},
{"FSpSetFLock", (PyCFunction)FSSpec_FSpSetFLock, 1,
PyDoc_STR("() -> None")},
{"FSpRstFLock", (PyCFunction)FSSpec_FSpRstFLock, 1,
PyDoc_STR("() -> None")},
{"FSpRename", (PyCFunction)FSSpec_FSpRename, 1,
PyDoc_STR("(Str255 newName) -> None")},
{"FSpCatMove", (PyCFunction)FSSpec_FSpCatMove, 1,
PyDoc_STR("(FSSpec dest) -> None")},
{"FSpExchangeFiles", (PyCFunction)FSSpec_FSpExchangeFiles, 1,
PyDoc_STR("(FSSpec dest) -> None")},
{"FSpMakeFSRef", (PyCFunction)FSSpec_FSpMakeFSRef, 1,
PyDoc_STR("() -> (FSRef newRef)")},
{"NewAliasMinimal", (PyCFunction)FSSpec_NewAliasMinimal, 1,
PyDoc_STR("() -> (AliasHandle alias)")},
{"IsAliasFile", (PyCFunction)FSSpec_IsAliasFile, 1,
PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
{"as_pathname", (PyCFunction)FSSpec_as_pathname, 1,
PyDoc_STR("() -> string")},
{"as_tuple", (PyCFunction)FSSpec_as_tuple, 1,
PyDoc_STR("() -> (vRefNum, dirID, name)")},
{NULL, NULL, 0}
};
static PyObject *FSSpec_get_data(FSSpecObject *self, void *closure)
{
return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
}
#define FSSpec_set_data NULL
static PyGetSetDef FSSpec_getsetlist[] = {
{"data", (getter)FSSpec_get_data, (setter)FSSpec_set_data, "Raw data of the FSSpec object"},
{NULL, NULL, NULL, NULL},
};
#define FSSpec_compare NULL
static PyObject * FSSpec_repr(FSSpecObject *self)
{
char buf[512];
PyOS_snprintf(buf, sizeof(buf), "%s((%d, %ld, '%.*s'))",
self->ob_type->tp_name,
self->ob_itself.vRefNum,
self->ob_itself.parID,
self->ob_itself.name[0], self->ob_itself.name+1);
return PyString_FromString(buf);
}
#define FSSpec_hash NULL
static int FSSpec_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *v = NULL;
char *rawdata = NULL;
int rawdatalen = 0;
static char *kw[] = {"itself", "rawdata", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
return -1;
if (v && rawdata)
{
PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
return -1;
}
if (!v && !rawdata)
{
PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
return -1;
}
if (rawdata)
{
if (rawdatalen != sizeof(FSSpec))
{
PyErr_SetString(PyExc_TypeError, "FSSpec rawdata incorrect size");
return -1;
}
memcpy(&((FSSpecObject *)self)->ob_itself, rawdata, rawdatalen);
return 0;
}
if (PyMac_GetFSSpec(v, &((FSSpecObject *)self)->ob_itself)) return 0;
return -1;
}
#define FSSpec_tp_alloc PyType_GenericAlloc
static PyObject *FSSpec_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
memset(&((FSSpecObject *)self)->ob_itself, 0, sizeof(FSSpec));
return self;
}
#define FSSpec_tp_free PyObject_Del
static PyTypeObject FSSpec_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Carbon.File.FSSpec", /*tp_name*/
sizeof(FSSpecObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) FSSpec_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc) FSSpec_compare, /*tp_compare*/
(reprfunc) FSSpec_repr, /*tp_repr*/
(PyNumberMethods *)0, /* tp_as_number */
(PySequenceMethods *)0, /* tp_as_sequence */
(PyMappingMethods *)0, /* tp_as_mapping */
(hashfunc) FSSpec_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
PyObject_GenericGetAttr, /*tp_getattro*/
PyObject_GenericSetAttr, /*tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
FSSpec_methods, /* tp_methods */
0, /*tp_members*/
FSSpec_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
FSSpec_tp_init, /* tp_init */
FSSpec_tp_alloc, /* tp_alloc */
FSSpec_tp_new, /* tp_new */
FSSpec_tp_free, /* tp_free */
};
/* --------------------- End object type FSSpec --------------------- */
/* ----------------------- Object type FSRef ------------------------ */
static PyTypeObject FSRef_Type;
#define FSRef_Check(x) ((x)->ob_type == &FSRef_Type || PyObject_TypeCheck((x), &FSRef_Type))
typedef struct FSRefObject {
PyObject_HEAD
FSRef ob_itself;
} FSRefObject;
static PyObject *FSRef_New(FSRef *itself)
{
FSRefObject *it;
if (itself == NULL) return PyMac_Error(resNotFound);
it = PyObject_NEW(FSRefObject, &FSRef_Type);
if (it == NULL) return NULL;
it->ob_itself = *itself;
return (PyObject *)it;
}
static void FSRef_dealloc(FSRefObject *self)
{
/* Cleanup of self->ob_itself goes here */
self->ob_type->tp_free((PyObject *)self);
}
static PyObject *FSRef_FSMakeFSRefUnicode(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *nameLength__in__;
UniCharCount nameLength__len__;
int nameLength__in_len__;
TextEncoding textEncodingHint;
FSRef newRef;
if (!PyArg_ParseTuple(_args, "u#l",
&nameLength__in__, &nameLength__in_len__,
&textEncodingHint))
return NULL;
nameLength__len__ = nameLength__in_len__;
_err = FSMakeFSRefUnicode(&_self->ob_itself,
nameLength__len__, nameLength__in__,
textEncodingHint,
&newRef);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FSRef_New, &newRef);
return _res;
}
static PyObject *FSRef_FSCompareFSRefs(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef ref2;
if (!PyArg_ParseTuple(_args, "O&",
FSRef_Convert, &ref2))
return NULL;
_err = FSCompareFSRefs(&_self->ob_itself,
&ref2);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSCreateFileUnicode(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *nameLength__in__;
UniCharCount nameLength__len__;
int nameLength__in_len__;
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
FSRef newRef;
FSSpec newSpec;
if (!PyArg_ParseTuple(_args, "u#lO&",
&nameLength__in__, &nameLength__in_len__,
&whichInfo,
FSCatalogInfo_Convert, &catalogInfo))
return NULL;
nameLength__len__ = nameLength__in_len__;
_err = FSCreateFileUnicode(&_self->ob_itself,
nameLength__len__, nameLength__in__,
whichInfo,
&catalogInfo,
&newRef,
&newSpec);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&O&",
FSRef_New, &newRef,
FSSpec_New, &newSpec);
return _res;
}
static PyObject *FSRef_FSCreateDirectoryUnicode(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *nameLength__in__;
UniCharCount nameLength__len__;
int nameLength__in_len__;
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
FSRef newRef;
FSSpec newSpec;
UInt32 newDirID;
if (!PyArg_ParseTuple(_args, "u#lO&",
&nameLength__in__, &nameLength__in_len__,
&whichInfo,
FSCatalogInfo_Convert, &catalogInfo))
return NULL;
nameLength__len__ = nameLength__in_len__;
_err = FSCreateDirectoryUnicode(&_self->ob_itself,
nameLength__len__, nameLength__in__,
whichInfo,
&catalogInfo,
&newRef,
&newSpec,
&newDirID);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&O&l",
FSRef_New, &newRef,
FSSpec_New, &newSpec,
newDirID);
return _res;
}
static PyObject *FSRef_FSDeleteObject(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSDeleteObject(&_self->ob_itself);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSMoveObject(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef destDirectory;
FSRef newRef;
if (!PyArg_ParseTuple(_args, "O&",
FSRef_Convert, &destDirectory))
return NULL;
_err = FSMoveObject(&_self->ob_itself,
&destDirectory,
&newRef);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FSRef_New, &newRef);
return _res;
}
static PyObject *FSRef_FSExchangeObjects(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef destRef;
if (!PyArg_ParseTuple(_args, "O&",
FSRef_Convert, &destRef))
return NULL;
_err = FSExchangeObjects(&_self->ob_itself,
&destRef);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSRenameUnicode(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *nameLength__in__;
UniCharCount nameLength__len__;
int nameLength__in_len__;
TextEncoding textEncodingHint;
FSRef newRef;
if (!PyArg_ParseTuple(_args, "u#l",
&nameLength__in__, &nameLength__in_len__,
&textEncodingHint))
return NULL;
nameLength__len__ = nameLength__in_len__;
_err = FSRenameUnicode(&_self->ob_itself,
nameLength__len__, nameLength__in__,
textEncodingHint,
&newRef);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FSRef_New, &newRef);
return _res;
}
static PyObject *FSRef_FSGetCatalogInfo(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
HFSUniStr255 outName;
FSSpec fsSpec;
FSRef parentRef;
if (!PyArg_ParseTuple(_args, "l",
&whichInfo))
return NULL;
_err = FSGetCatalogInfo(&_self->ob_itself,
whichInfo,
&catalogInfo,
&outName,
&fsSpec,
&parentRef);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&O&O&O&",
FSCatalogInfo_New, &catalogInfo,
PyMac_BuildHFSUniStr255, &outName,
FSSpec_New, &fsSpec,
FSRef_New, &parentRef);
return _res;
}
static PyObject *FSRef_FSSetCatalogInfo(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSCatalogInfoBitmap whichInfo;
FSCatalogInfo catalogInfo;
if (!PyArg_ParseTuple(_args, "lO&",
&whichInfo,
FSCatalogInfo_Convert, &catalogInfo))
return NULL;
_err = FSSetCatalogInfo(&_self->ob_itself,
whichInfo,
&catalogInfo);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSCreateFork(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *forkNameLength__in__;
UniCharCount forkNameLength__len__;
int forkNameLength__in_len__;
if (!PyArg_ParseTuple(_args, "u#",
&forkNameLength__in__, &forkNameLength__in_len__))
return NULL;
forkNameLength__len__ = forkNameLength__in_len__;
_err = FSCreateFork(&_self->ob_itself,
forkNameLength__len__, forkNameLength__in__);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSDeleteFork(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *forkNameLength__in__;
UniCharCount forkNameLength__len__;
int forkNameLength__in_len__;
if (!PyArg_ParseTuple(_args, "u#",
&forkNameLength__in__, &forkNameLength__in_len__))
return NULL;
forkNameLength__len__ = forkNameLength__in_len__;
_err = FSDeleteFork(&_self->ob_itself,
forkNameLength__len__, forkNameLength__in__);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *FSRef_FSOpenFork(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
UniChar *forkNameLength__in__;
UniCharCount forkNameLength__len__;
int forkNameLength__in_len__;
SInt8 permissions;
SInt16 forkRefNum;
if (!PyArg_ParseTuple(_args, "u#b",
&forkNameLength__in__, &forkNameLength__in_len__,
&permissions))
return NULL;
forkNameLength__len__ = forkNameLength__in_len__;
_err = FSOpenFork(&_self->ob_itself,
forkNameLength__len__, forkNameLength__in__,
permissions,
&forkRefNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
forkRefNum);
return _res;
}
#if TARGET_API_MAC_OSX
static PyObject *FSRef_FNNotify(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSStatus _err;
FNMessage message;
OptionBits flags;
if (!PyArg_ParseTuple(_args, "ll",
&message,
&flags))
return NULL;
_err = FNNotify(&_self->ob_itself,
message,
flags);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
#endif
static PyObject *FSRef_FSNewAliasMinimal(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
AliasHandle inAlias;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSNewAliasMinimal(&_self->ob_itself,
&inAlias);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
Alias_New, inAlias);
return _res;
}
static PyObject *FSRef_FSIsAliasFile(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Boolean aliasFileFlag;
Boolean folderFlag;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSIsAliasFile(&_self->ob_itself,
&aliasFileFlag,
&folderFlag);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("bb",
aliasFileFlag,
folderFlag);
return _res;
}
static PyObject *FSRef_FSRefMakePath(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSStatus _err;
#define MAXPATHNAME 1024
UInt8 path[MAXPATHNAME];
UInt32 maxPathSize = MAXPATHNAME;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSRefMakePath(&_self->ob_itself,
path,
maxPathSize);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("s", path);
return _res;
}
static PyObject *FSRef_as_pathname(FSRefObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
#if TARGET_API_MAC_OSX
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_res = FSRef_FSRefMakePath(_self, _args);
#else
char strbuf[1024];
OSErr err;
FSSpec fss;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
if ( !PyMac_GetFSSpec((PyObject *)_self, &fss))
return NULL;
err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf));
if ( err ) {
PyMac_Error(err);
return NULL;
}
_res = PyString_FromString(strbuf);
#endif
return _res;
}
static PyMethodDef FSRef_methods[] = {
{"FSMakeFSRefUnicode", (PyCFunction)FSRef_FSMakeFSRefUnicode, 1,
PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
{"FSCompareFSRefs", (PyCFunction)FSRef_FSCompareFSRefs, 1,
PyDoc_STR("(FSRef ref2) -> None")},
{"FSCreateFileUnicode", (PyCFunction)FSRef_FSCreateFileUnicode, 1,
PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec)")},
{"FSCreateDirectoryUnicode", (PyCFunction)FSRef_FSCreateDirectoryUnicode, 1,
PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec, UInt32 newDirID)")},
{"FSDeleteObject", (PyCFunction)FSRef_FSDeleteObject, 1,
PyDoc_STR("() -> None")},
{"FSMoveObject", (PyCFunction)FSRef_FSMoveObject, 1,
PyDoc_STR("(FSRef destDirectory) -> (FSRef newRef)")},
{"FSExchangeObjects", (PyCFunction)FSRef_FSExchangeObjects, 1,
PyDoc_STR("(FSRef destRef) -> None")},
{"FSRenameUnicode", (PyCFunction)FSRef_FSRenameUnicode, 1,
PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
{"FSGetCatalogInfo", (PyCFunction)FSRef_FSGetCatalogInfo, 1,
PyDoc_STR("(FSCatalogInfoBitmap whichInfo) -> (FSCatalogInfo catalogInfo, HFSUniStr255 outName, FSSpec fsSpec, FSRef parentRef)")},
{"FSSetCatalogInfo", (PyCFunction)FSRef_FSSetCatalogInfo, 1,
PyDoc_STR("(FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> None")},
{"FSCreateFork", (PyCFunction)FSRef_FSCreateFork, 1,
PyDoc_STR("(Buffer forkNameLength) -> None")},
{"FSDeleteFork", (PyCFunction)FSRef_FSDeleteFork, 1,
PyDoc_STR("(Buffer forkNameLength) -> None")},
{"FSOpenFork", (PyCFunction)FSRef_FSOpenFork, 1,
PyDoc_STR("(Buffer forkNameLength, SInt8 permissions) -> (SInt16 forkRefNum)")},
#if TARGET_API_MAC_OSX
{"FNNotify", (PyCFunction)FSRef_FNNotify, 1,
PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
#endif
{"FSNewAliasMinimal", (PyCFunction)FSRef_FSNewAliasMinimal, 1,
PyDoc_STR("() -> (AliasHandle inAlias)")},
{"FSIsAliasFile", (PyCFunction)FSRef_FSIsAliasFile, 1,
PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
{"FSRefMakePath", (PyCFunction)FSRef_FSRefMakePath, 1,
PyDoc_STR("() -> string")},
{"as_pathname", (PyCFunction)FSRef_as_pathname, 1,
PyDoc_STR("() -> string")},
{NULL, NULL, 0}
};
static PyObject *FSRef_get_data(FSRefObject *self, void *closure)
{
return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
}
#define FSRef_set_data NULL
static PyGetSetDef FSRef_getsetlist[] = {
{"data", (getter)FSRef_get_data, (setter)FSRef_set_data, "Raw data of the FSRef object"},
{NULL, NULL, NULL, NULL},
};
#define FSRef_compare NULL
#define FSRef_repr NULL
#define FSRef_hash NULL
static int FSRef_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *v = NULL;
char *rawdata = NULL;
int rawdatalen = 0;
static char *kw[] = {"itself", "rawdata", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
return -1;
if (v && rawdata)
{
PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
return -1;
}
if (!v && !rawdata)
{
PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
return -1;
}
if (rawdata)
{
if (rawdatalen != sizeof(FSRef))
{
PyErr_SetString(PyExc_TypeError, "FSRef rawdata incorrect size");
return -1;
}
memcpy(&((FSRefObject *)self)->ob_itself, rawdata, rawdatalen);
return 0;
}
if (PyMac_GetFSRef(v, &((FSRefObject *)self)->ob_itself)) return 0;
return -1;
}
#define FSRef_tp_alloc PyType_GenericAlloc
static PyObject *FSRef_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
memset(&((FSRefObject *)self)->ob_itself, 0, sizeof(FSRef));
return self;
}
#define FSRef_tp_free PyObject_Del
static PyTypeObject FSRef_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Carbon.File.FSRef", /*tp_name*/
sizeof(FSRefObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) FSRef_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/
(cmpfunc) FSRef_compare, /*tp_compare*/
(reprfunc) FSRef_repr, /*tp_repr*/
(PyNumberMethods *)0, /* tp_as_number */
(PySequenceMethods *)0, /* tp_as_sequence */
(PyMappingMethods *)0, /* tp_as_mapping */
(hashfunc) FSRef_hash, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
PyObject_GenericGetAttr, /*tp_getattro*/
PyObject_GenericSetAttr, /*tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
FSRef_methods, /* tp_methods */
0, /*tp_members*/
FSRef_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
FSRef_tp_init, /* tp_init */
FSRef_tp_alloc, /* tp_alloc */
FSRef_tp_new, /* tp_new */
FSRef_tp_free, /* tp_free */
};
/* --------------------- End object type FSRef ---------------------- */
static PyObject *File_UnmountVol(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Str63 volName;
short vRefNum;
if (!PyArg_ParseTuple(_args, "O&h",
PyMac_GetStr255, volName,
&vRefNum))
return NULL;
_err = UnmountVol(volName,
vRefNum);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FlushVol(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Str63 volName;
short vRefNum;
if (!PyArg_ParseTuple(_args, "O&h",
PyMac_GetStr255, volName,
&vRefNum))
return NULL;
_err = FlushVol(volName,
vRefNum);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_HSetVol(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
Str63 volName;
short vRefNum;
long dirID;
if (!PyArg_ParseTuple(_args, "O&hl",
PyMac_GetStr255, volName,
&vRefNum,
&dirID))
return NULL;
_err = HSetVol(volName,
vRefNum,
dirID);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSClose(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
if (!PyArg_ParseTuple(_args, "h",
&refNum))
return NULL;
_err = FSClose(refNum);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_Allocate(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
long count;
if (!PyArg_ParseTuple(_args, "h",
&refNum))
return NULL;
_err = Allocate(refNum,
&count);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
count);
return _res;
}
static PyObject *File_GetEOF(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
long logEOF;
if (!PyArg_ParseTuple(_args, "h",
&refNum))
return NULL;
_err = GetEOF(refNum,
&logEOF);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
logEOF);
return _res;
}
static PyObject *File_SetEOF(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
long logEOF;
if (!PyArg_ParseTuple(_args, "hl",
&refNum,
&logEOF))
return NULL;
_err = SetEOF(refNum,
logEOF);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_GetFPos(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
long filePos;
if (!PyArg_ParseTuple(_args, "h",
&refNum))
return NULL;
_err = GetFPos(refNum,
&filePos);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
filePos);
return _res;
}
static PyObject *File_SetFPos(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
short posMode;
long posOff;
if (!PyArg_ParseTuple(_args, "hhl",
&refNum,
&posMode,
&posOff))
return NULL;
_err = SetFPos(refNum,
posMode,
posOff);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_GetVRefNum(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short fileRefNum;
short vRefNum;
if (!PyArg_ParseTuple(_args, "h",
&fileRefNum))
return NULL;
_err = GetVRefNum(fileRefNum,
&vRefNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
vRefNum);
return _res;
}
static PyObject *File_HGetVol(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
StringPtr volName;
short vRefNum;
long dirID;
if (!PyArg_ParseTuple(_args, "O&",
PyMac_GetStr255, &volName))
return NULL;
_err = HGetVol(volName,
&vRefNum,
&dirID);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("hl",
vRefNum,
dirID);
return _res;
}
static PyObject *File_HOpen(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
SInt8 permission;
short refNum;
if (!PyArg_ParseTuple(_args, "hlO&b",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName,
&permission))
return NULL;
_err = HOpen(vRefNum,
dirID,
fileName,
permission,
&refNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
refNum);
return _res;
}
static PyObject *File_HOpenDF(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
SInt8 permission;
short refNum;
if (!PyArg_ParseTuple(_args, "hlO&b",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName,
&permission))
return NULL;
_err = HOpenDF(vRefNum,
dirID,
fileName,
permission,
&refNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
refNum);
return _res;
}
static PyObject *File_HOpenRF(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
SInt8 permission;
short refNum;
if (!PyArg_ParseTuple(_args, "hlO&b",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName,
&permission))
return NULL;
_err = HOpenRF(vRefNum,
dirID,
fileName,
permission,
&refNum);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("h",
refNum);
return _res;
}
static PyObject *File_AllocContig(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short refNum;
long count;
if (!PyArg_ParseTuple(_args, "h",
&refNum))
return NULL;
_err = AllocContig(refNum,
&count);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
count);
return _res;
}
static PyObject *File_HCreate(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
OSType creator;
OSType fileType;
if (!PyArg_ParseTuple(_args, "hlO&O&O&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName,
PyMac_GetOSType, &creator,
PyMac_GetOSType, &fileType))
return NULL;
_err = HCreate(vRefNum,
dirID,
fileName,
creator,
fileType);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_DirCreate(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long parentDirID;
Str255 directoryName;
long createdDirID;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&parentDirID,
PyMac_GetStr255, directoryName))
return NULL;
_err = DirCreate(vRefNum,
parentDirID,
directoryName,
&createdDirID);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("l",
createdDirID);
return _res;
}
static PyObject *File_HDelete(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName))
return NULL;
_err = HDelete(vRefNum,
dirID,
fileName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_HGetFInfo(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
FInfo fndrInfo;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName))
return NULL;
_err = HGetFInfo(vRefNum,
dirID,
fileName,
&fndrInfo);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FInfo_New, &fndrInfo);
return _res;
}
static PyObject *File_HSetFInfo(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
FInfo fndrInfo;
if (!PyArg_ParseTuple(_args, "hlO&O&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName,
FInfo_Convert, &fndrInfo))
return NULL;
_err = HSetFInfo(vRefNum,
dirID,
fileName,
&fndrInfo);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_HSetFLock(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName))
return NULL;
_err = HSetFLock(vRefNum,
dirID,
fileName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_HRstFLock(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName))
return NULL;
_err = HRstFLock(vRefNum,
dirID,
fileName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_HRename(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 oldName;
Str255 newName;
if (!PyArg_ParseTuple(_args, "hlO&O&",
&vRefNum,
&dirID,
PyMac_GetStr255, oldName,
PyMac_GetStr255, newName))
return NULL;
_err = HRename(vRefNum,
dirID,
oldName,
newName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_CatMove(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 oldName;
long newDirID;
Str255 newName;
if (!PyArg_ParseTuple(_args, "hlO&lO&",
&vRefNum,
&dirID,
PyMac_GetStr255, oldName,
&newDirID,
PyMac_GetStr255, newName))
return NULL;
_err = CatMove(vRefNum,
dirID,
oldName,
newDirID,
newName);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSMakeFSSpec(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
short vRefNum;
long dirID;
Str255 fileName;
FSSpec spec;
if (!PyArg_ParseTuple(_args, "hlO&",
&vRefNum,
&dirID,
PyMac_GetStr255, fileName))
return NULL;
_err = FSMakeFSSpec(vRefNum,
dirID,
fileName,
&spec);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
FSSpec_New, &spec);
return _res;
}
static PyObject *File_FSGetForkPosition(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
SInt64 position;
if (!PyArg_ParseTuple(_args, "h",
&forkRefNum))
return NULL;
_err = FSGetForkPosition(forkRefNum,
&position);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("L",
position);
return _res;
}
static PyObject *File_FSSetForkPosition(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
UInt16 positionMode;
SInt64 positionOffset;
if (!PyArg_ParseTuple(_args, "hHL",
&forkRefNum,
&positionMode,
&positionOffset))
return NULL;
_err = FSSetForkPosition(forkRefNum,
positionMode,
positionOffset);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSGetForkSize(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
SInt64 forkSize;
if (!PyArg_ParseTuple(_args, "h",
&forkRefNum))
return NULL;
_err = FSGetForkSize(forkRefNum,
&forkSize);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("L",
forkSize);
return _res;
}
static PyObject *File_FSSetForkSize(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
UInt16 positionMode;
SInt64 positionOffset;
if (!PyArg_ParseTuple(_args, "hHL",
&forkRefNum,
&positionMode,
&positionOffset))
return NULL;
_err = FSSetForkSize(forkRefNum,
positionMode,
positionOffset);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSAllocateFork(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
FSAllocationFlags flags;
UInt16 positionMode;
SInt64 positionOffset;
UInt64 requestCount;
UInt64 actualCount;
if (!PyArg_ParseTuple(_args, "hHHLL",
&forkRefNum,
&flags,
&positionMode,
&positionOffset,
&requestCount))
return NULL;
_err = FSAllocateFork(forkRefNum,
flags,
positionMode,
positionOffset,
requestCount,
&actualCount);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("L",
actualCount);
return _res;
}
static PyObject *File_FSFlushFork(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
if (!PyArg_ParseTuple(_args, "h",
&forkRefNum))
return NULL;
_err = FSFlushFork(forkRefNum);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSCloseFork(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
SInt16 forkRefNum;
if (!PyArg_ParseTuple(_args, "h",
&forkRefNum))
return NULL;
_err = FSCloseFork(forkRefNum);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
static PyObject *File_FSGetDataForkName(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
HFSUniStr255 dataForkName;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSGetDataForkName(&dataForkName);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
PyMac_BuildHFSUniStr255, &dataForkName);
return _res;
}
static PyObject *File_FSGetResourceForkName(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
HFSUniStr255 resourceForkName;
if (!PyArg_ParseTuple(_args, ""))
return NULL;
_err = FSGetResourceForkName(&resourceForkName);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
PyMac_BuildHFSUniStr255, &resourceForkName);
return _res;
}
static PyObject *File_FSPathMakeRef(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSStatus _err;
UInt8 * path;
FSRef ref;
Boolean isDirectory;
if (!PyArg_ParseTuple(_args, "s",
&path))
return NULL;
_err = FSPathMakeRef(path,
&ref,
&isDirectory);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&b",
FSRef_New, &ref,
isDirectory);
return _res;
}
#if TARGET_API_MAC_OSX
static PyObject *File_FNNotifyByPath(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSStatus _err;
UInt8 * path;
FNMessage message;
OptionBits flags;
if (!PyArg_ParseTuple(_args, "sll",
&path,
&message,
&flags))
return NULL;
_err = FNNotifyByPath(path,
message,
flags);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
#endif
#if TARGET_API_MAC_OSX
static PyObject *File_FNNotifyAll(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSStatus _err;
FNMessage message;
OptionBits flags;
if (!PyArg_ParseTuple(_args, "ll",
&message,
&flags))
return NULL;
_err = FNNotifyAll(message,
flags);
if (_err != noErr) return PyMac_Error(_err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
}
#endif
static PyObject *File_NewAlias(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec fromFile__buf__;
FSSpec *fromFile = &fromFile__buf__;
FSSpec target;
AliasHandle alias;
if (!PyArg_ParseTuple(_args, "O&O&",
myPyMac_GetOptFSSpecPtr, &fromFile,
FSSpec_Convert, &target))
return NULL;
_err = NewAlias(fromFile,
&target,
&alias);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
Alias_New, alias);
return _res;
}
static PyObject *File_NewAliasMinimalFromFullPath(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
char *fullPath__in__;
int fullPath__len__;
int fullPath__in_len__;
Str32 zoneName;
Str31 serverName;
AliasHandle alias;
if (!PyArg_ParseTuple(_args, "s#O&O&",
&fullPath__in__, &fullPath__in_len__,
PyMac_GetStr255, zoneName,
PyMac_GetStr255, serverName))
return NULL;
fullPath__len__ = fullPath__in_len__;
_err = NewAliasMinimalFromFullPath(fullPath__len__, fullPath__in__,
zoneName,
serverName,
&alias);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
Alias_New, alias);
return _res;
}
static PyObject *File_ResolveAliasFile(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec theSpec;
Boolean resolveAliasChains;
Boolean targetIsFolder;
Boolean wasAliased;
if (!PyArg_ParseTuple(_args, "O&b",
FSSpec_Convert, &theSpec,
&resolveAliasChains))
return NULL;
_err = ResolveAliasFile(&theSpec,
resolveAliasChains,
&targetIsFolder,
&wasAliased);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&bb",
FSSpec_New, &theSpec,
targetIsFolder,
wasAliased);
return _res;
}
static PyObject *File_ResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec theSpec;
Boolean resolveAliasChains;
Boolean targetIsFolder;
Boolean wasAliased;
unsigned long mountFlags;
if (!PyArg_ParseTuple(_args, "O&bl",
FSSpec_Convert, &theSpec,
&resolveAliasChains,
&mountFlags))
return NULL;
_err = ResolveAliasFileWithMountFlags(&theSpec,
resolveAliasChains,
&targetIsFolder,
&wasAliased,
mountFlags);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&bb",
FSSpec_New, &theSpec,
targetIsFolder,
wasAliased);
return _res;
}
static PyObject *File_UpdateAlias(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec fromFile__buf__;
FSSpec *fromFile = &fromFile__buf__;
FSSpec target;
AliasHandle alias;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "O&O&O&",
myPyMac_GetOptFSSpecPtr, &fromFile,
FSSpec_Convert, &target,
Alias_Convert, &alias))
return NULL;
_err = UpdateAlias(fromFile,
&target,
alias,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("b",
wasChanged);
return _res;
}
static PyObject *File_ResolveAliasFileWithMountFlagsNoUI(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSSpec theSpec;
Boolean resolveAliasChains;
Boolean targetIsFolder;
Boolean wasAliased;
unsigned long mountFlags;
if (!PyArg_ParseTuple(_args, "O&bl",
FSSpec_Convert, &theSpec,
&resolveAliasChains,
&mountFlags))
return NULL;
_err = ResolveAliasFileWithMountFlagsNoUI(&theSpec,
resolveAliasChains,
&targetIsFolder,
&wasAliased,
mountFlags);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&bb",
FSSpec_New, &theSpec,
targetIsFolder,
wasAliased);
return _res;
}
static PyObject *File_FSNewAlias(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef fromFile__buf__;
FSRef *fromFile = &fromFile__buf__;
FSRef target;
AliasHandle inAlias;
if (!PyArg_ParseTuple(_args, "O&O&",
myPyMac_GetOptFSRefPtr, &fromFile,
FSRef_Convert, &target))
return NULL;
_err = FSNewAlias(fromFile,
&target,
&inAlias);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&",
Alias_New, inAlias);
return _res;
}
static PyObject *File_FSResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef theRef;
Boolean resolveAliasChains;
Boolean targetIsFolder;
Boolean wasAliased;
unsigned long mountFlags;
if (!PyArg_ParseTuple(_args, "O&bl",
FSRef_Convert, &theRef,
&resolveAliasChains,
&mountFlags))
return NULL;
_err = FSResolveAliasFileWithMountFlags(&theRef,
resolveAliasChains,
&targetIsFolder,
&wasAliased,
mountFlags);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&bb",
FSRef_New, &theRef,
targetIsFolder,
wasAliased);
return _res;
}
static PyObject *File_FSResolveAliasFile(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef theRef;
Boolean resolveAliasChains;
Boolean targetIsFolder;
Boolean wasAliased;
if (!PyArg_ParseTuple(_args, "O&b",
FSRef_Convert, &theRef,
&resolveAliasChains))
return NULL;
_err = FSResolveAliasFile(&theRef,
resolveAliasChains,
&targetIsFolder,
&wasAliased);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("O&bb",
FSRef_New, &theRef,
targetIsFolder,
wasAliased);
return _res;
}
static PyObject *File_FSUpdateAlias(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
OSErr _err;
FSRef fromFile__buf__;
FSRef *fromFile = &fromFile__buf__;
FSRef target;
AliasHandle alias;
Boolean wasChanged;
if (!PyArg_ParseTuple(_args, "O&O&O&",
myPyMac_GetOptFSRefPtr, &fromFile,
FSRef_Convert, &target,
Alias_Convert, &alias))
return NULL;
_err = FSUpdateAlias(fromFile,
&target,
alias,
&wasChanged);
if (_err != noErr) return PyMac_Error(_err);
_res = Py_BuildValue("b",
wasChanged);
return _res;
}
static PyObject *File_pathname(PyObject *_self, PyObject *_args)
{
PyObject *_res = NULL;
PyObject *obj;
if (!PyArg_ParseTuple(_args, "O", &obj))
return NULL;
if (PyString_Check(obj)) {
Py_INCREF(obj);
return obj;
}
if (PyUnicode_Check(obj))
return PyUnicode_AsEncodedString(obj, "utf8", "strict");
_res = PyObject_CallMethod(obj, "as_pathname", NULL);
return _res;
}
static PyMethodDef File_methods[] = {
{"UnmountVol", (PyCFunction)File_UnmountVol, 1,
PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
{"FlushVol", (PyCFunction)File_FlushVol, 1,
PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
{"HSetVol", (PyCFunction)File_HSetVol, 1,
PyDoc_STR("(Str63 volName, short vRefNum, long dirID) -> None")},
{"FSClose", (PyCFunction)File_FSClose, 1,
PyDoc_STR("(short refNum) -> None")},
{"Allocate", (PyCFunction)File_Allocate, 1,
PyDoc_STR("(short refNum) -> (long count)")},
{"GetEOF", (PyCFunction)File_GetEOF, 1,
PyDoc_STR("(short refNum) -> (long logEOF)")},
{"SetEOF", (PyCFunction)File_SetEOF, 1,
PyDoc_STR("(short refNum, long logEOF) -> None")},
{"GetFPos", (PyCFunction)File_GetFPos, 1,
PyDoc_STR("(short refNum) -> (long filePos)")},
{"SetFPos", (PyCFunction)File_SetFPos, 1,
PyDoc_STR("(short refNum, short posMode, long posOff) -> None")},
{"GetVRefNum", (PyCFunction)File_GetVRefNum, 1,
PyDoc_STR("(short fileRefNum) -> (short vRefNum)")},
{"HGetVol", (PyCFunction)File_HGetVol, 1,
PyDoc_STR("(StringPtr volName) -> (short vRefNum, long dirID)")},
{"HOpen", (PyCFunction)File_HOpen, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
{"HOpenDF", (PyCFunction)File_HOpenDF, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
{"HOpenRF", (PyCFunction)File_HOpenRF, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
{"AllocContig", (PyCFunction)File_AllocContig, 1,
PyDoc_STR("(short refNum) -> (long count)")},
{"HCreate", (PyCFunction)File_HCreate, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, OSType creator, OSType fileType) -> None")},
{"DirCreate", (PyCFunction)File_DirCreate, 1,
PyDoc_STR("(short vRefNum, long parentDirID, Str255 directoryName) -> (long createdDirID)")},
{"HDelete", (PyCFunction)File_HDelete, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
{"HGetFInfo", (PyCFunction)File_HGetFInfo, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FInfo fndrInfo)")},
{"HSetFInfo", (PyCFunction)File_HSetFInfo, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, FInfo fndrInfo) -> None")},
{"HSetFLock", (PyCFunction)File_HSetFLock, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
{"HRstFLock", (PyCFunction)File_HRstFLock, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
{"HRename", (PyCFunction)File_HRename, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, Str255 newName) -> None")},
{"CatMove", (PyCFunction)File_CatMove, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, long newDirID, Str255 newName) -> None")},
{"FSMakeFSSpec", (PyCFunction)File_FSMakeFSSpec, 1,
PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FSSpec spec)")},
{"FSGetForkPosition", (PyCFunction)File_FSGetForkPosition, 1,
PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 position)")},
{"FSSetForkPosition", (PyCFunction)File_FSSetForkPosition, 1,
PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
{"FSGetForkSize", (PyCFunction)File_FSGetForkSize, 1,
PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 forkSize)")},
{"FSSetForkSize", (PyCFunction)File_FSSetForkSize, 1,
PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
{"FSAllocateFork", (PyCFunction)File_FSAllocateFork, 1,
PyDoc_STR("(SInt16 forkRefNum, FSAllocationFlags flags, UInt16 positionMode, SInt64 positionOffset, UInt64 requestCount) -> (UInt64 actualCount)")},
{"FSFlushFork", (PyCFunction)File_FSFlushFork, 1,
PyDoc_STR("(SInt16 forkRefNum) -> None")},
{"FSCloseFork", (PyCFunction)File_FSCloseFork, 1,
PyDoc_STR("(SInt16 forkRefNum) -> None")},
{"FSGetDataForkName", (PyCFunction)File_FSGetDataForkName, 1,
PyDoc_STR("() -> (HFSUniStr255 dataForkName)")},
{"FSGetResourceForkName", (PyCFunction)File_FSGetResourceForkName, 1,
PyDoc_STR("() -> (HFSUniStr255 resourceForkName)")},
{"FSPathMakeRef", (PyCFunction)File_FSPathMakeRef, 1,
PyDoc_STR("(UInt8 * path) -> (FSRef ref, Boolean isDirectory)")},
#if TARGET_API_MAC_OSX
{"FNNotifyByPath", (PyCFunction)File_FNNotifyByPath, 1,
PyDoc_STR("(UInt8 * path, FNMessage message, OptionBits flags) -> None")},
#endif
#if TARGET_API_MAC_OSX
{"FNNotifyAll", (PyCFunction)File_FNNotifyAll, 1,
PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
#endif
{"NewAlias", (PyCFunction)File_NewAlias, 1,
PyDoc_STR("(FSSpec fromFile, FSSpec target) -> (AliasHandle alias)")},
{"NewAliasMinimalFromFullPath", (PyCFunction)File_NewAliasMinimalFromFullPath, 1,
PyDoc_STR("(Buffer fullPath, Str32 zoneName, Str31 serverName) -> (AliasHandle alias)")},
{"ResolveAliasFile", (PyCFunction)File_ResolveAliasFile, 1,
PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
{"ResolveAliasFileWithMountFlags", (PyCFunction)File_ResolveAliasFileWithMountFlags, 1,
PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
{"UpdateAlias", (PyCFunction)File_UpdateAlias, 1,
PyDoc_STR("(FSSpec fromFile, FSSpec target, AliasHandle alias) -> (Boolean wasChanged)")},
{"ResolveAliasFileWithMountFlagsNoUI", (PyCFunction)File_ResolveAliasFileWithMountFlagsNoUI, 1,
PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
{"FSNewAlias", (PyCFunction)File_FSNewAlias, 1,
PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")},
{"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1,
PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
{"FSResolveAliasFile", (PyCFunction)File_FSResolveAliasFile, 1,
PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
{"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1,
PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")},
{"pathname", (PyCFunction)File_pathname, 1,
PyDoc_STR("(str|unicode|FSSpec|FSref) -> pathname")},
{NULL, NULL, 0}
};
int
PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
{
Str255 path;
short refnum;
long parid;
OSErr err;
FSRef fsr;
if (FSSpec_Check(v)) {
*spec = ((FSSpecObject *)v)->ob_itself;
return 1;
}
if (PyArg_Parse(v, "(hlO&)",
&refnum, &parid, PyMac_GetStr255, &path)) {
err = FSMakeFSSpec(refnum, parid, path, spec);
if ( err && err != fnfErr ) {
PyMac_Error(err);
return 0;
}
return 1;
}
PyErr_Clear();
#if !TARGET_API_MAC_OSX
/* On OS9 we now try a pathname */
if ( PyString_Check(v) ) {
/* It's a pathname */
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
return 0;
refnum = 0; /* XXXX Should get CurWD here?? */
parid = 0;
err = FSMakeFSSpec(refnum, parid, path, spec);
if ( err && err != fnfErr ) {
PyMac_Error(err);
return 0;
}
return 1;
}
PyErr_Clear();
#endif
/* Otherwise we try to go via an FSRef. On OSX we go all the way,
** on OS9 we accept only a real FSRef object
*/
#if TARGET_API_MAC_OSX
if ( PyMac_GetFSRef(v, &fsr) ) {
#else
if (FSRef_Check(v)) {
fsr = ((FSRefObject *)v)->ob_itself;
#endif
err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
if (err != noErr) {
PyMac_Error(err);
return 0;
}
return 1;
}
#if !TARGET_API_MAC_OSX
PyErr_SetString(PyExc_TypeError, "FSSpec, FSRef, pathname or (refnum, parid, path) required");
#endif
return 0;
}
int
PyMac_GetFSRef(PyObject *v, FSRef *fsr)
{
OSStatus err;
FSSpec fss;
if (FSRef_Check(v)) {
*fsr = ((FSRefObject *)v)->ob_itself;
return 1;
}
#if TARGET_API_MAC_OSX
/* On OSX we now try a pathname */
if ( PyString_Check(v) || PyUnicode_Check(v)) {
char *path = NULL;
if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
return 0;
if ( (err=FSPathMakeRef((unsigned char *)path, fsr, NULL)) ) {
PyMac_Error(err);
return 0;
}
return 1;
}
/* XXXX Should try unicode here too */
#endif
/* Otherwise we try to go via an FSSpec */
#if TARGET_API_MAC_OSX
if (FSSpec_Check(v)) {
fss = ((FSSpecObject *)v)->ob_itself;
#else
if (PyMac_GetFSSpec(v, &fss)) {
#endif
if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
return 1;
PyMac_Error(err);
return 0;
}
PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
return 0;
}
extern PyObject *
PyMac_BuildFSSpec(FSSpec *spec)
{
return FSSpec_New(spec);
}
extern PyObject *
PyMac_BuildFSRef(FSRef *spec)
{
return FSRef_New(spec);
}
void init_File(void)
{
PyObject *m;
PyObject *d;
PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
m = Py_InitModule("_File", File_methods);
d = PyModule_GetDict(m);
File_Error = PyMac_GetOSErrException();
if (File_Error == NULL ||
PyDict_SetItemString(d, "Error", File_Error) != 0)
return;
FSCatalogInfo_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FSCatalogInfo_Type) < 0) return;
Py_INCREF(&FSCatalogInfo_Type);
PyModule_AddObject(m, "FSCatalogInfo", (PyObject *)&FSCatalogInfo_Type);
/* Backward-compatible name */
Py_INCREF(&FSCatalogInfo_Type);
PyModule_AddObject(m, "FSCatalogInfoType", (PyObject *)&FSCatalogInfo_Type);
FInfo_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FInfo_Type) < 0) return;
Py_INCREF(&FInfo_Type);
PyModule_AddObject(m, "FInfo", (PyObject *)&FInfo_Type);
/* Backward-compatible name */
Py_INCREF(&FInfo_Type);
PyModule_AddObject(m, "FInfoType", (PyObject *)&FInfo_Type);
Alias_Type.ob_type = &PyType_Type;
if (PyType_Ready(&Alias_Type) < 0) return;
Py_INCREF(&Alias_Type);
PyModule_AddObject(m, "Alias", (PyObject *)&Alias_Type);
/* Backward-compatible name */
Py_INCREF(&Alias_Type);
PyModule_AddObject(m, "AliasType", (PyObject *)&Alias_Type);
FSSpec_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FSSpec_Type) < 0) return;
Py_INCREF(&FSSpec_Type);
PyModule_AddObject(m, "FSSpec", (PyObject *)&FSSpec_Type);
/* Backward-compatible name */
Py_INCREF(&FSSpec_Type);
PyModule_AddObject(m, "FSSpecType", (PyObject *)&FSSpec_Type);
FSRef_Type.ob_type = &PyType_Type;
if (PyType_Ready(&FSRef_Type) < 0) return;
Py_INCREF(&FSRef_Type);
PyModule_AddObject(m, "FSRef", (PyObject *)&FSRef_Type);
/* Backward-compatible name */
Py_INCREF(&FSRef_Type);
PyModule_AddObject(m, "FSRefType", (PyObject *)&FSRef_Type);
}
/* ======================== End module _File ======================== */
#
# Pyrex - Linux system interface
#
verbose = 0
gcc_pendantic = True
gcc_warnings_are_errors = True
gcc_all_warnings = True
import os, sys
from Cython.Utils import replace_suffix
from Cython.Compiler.Errors import PyrexError
version = "%s.%s" % sys.version_info[:2]
py_include_dirs = [
"%s/include/python%s" % (sys.prefix, version)
]
compilers = ["gcc", "g++"]
compiler_options = \
"-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp " \
"-mno-fused-madd -fno-common -dynamic " \
.split()
if gcc_pendantic:
compiler_options.extend(["-pedantic", "-Wno-long-long"])
if gcc_warnings_are_errors:
compiler_options.append("-Werror")
if gcc_all_warnings:
compiler_options.append("-Wall")
compiler_options.append("-Wno-unused-function")
linkers = ["gcc", "g++"]
linker_options = \
"-shared" \
.split()
class CCompilerError(PyrexError):
pass
def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
# Compile the given C source file to produce
# an object file. Returns the pathname of the
# resulting file.
c_file = os.path.join(os.getcwd(), c_file)
o_file = replace_suffix(c_file, obj_suffix)
include_options = []
for dir in py_include_dirs:
include_options.append("-I%s" % dir)
compiler = compilers[bool(cplus)]
args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
if verbose_flag or verbose:
print(" ".join(args))
#print compiler, args ###
status = os.spawnvp(os.P_WAIT, compiler, args)
if status != 0:
raise CCompilerError("C compiler returned status %s" % status)
return o_file
def c_link(obj_file, verbose_flag = 0, extra_objects = [], cplus = 0):
return c_link_list([obj_file] + extra_objects, verbose_flag, cplus)
def c_link_list(obj_files, verbose_flag = 0, cplus = 0):
# Link the given object files into a dynamically
# loadable extension file. Returns the pathname
# of the resulting file.
out_file = replace_suffix(obj_files[0], ".so")
linker = linkers[bool(cplus)]
args = [linker] + linker_options + obj_files + ["-o", out_file]
if verbose_flag or verbose:
print(" ".join(args))
status = os.spawnvp(os.P_WAIT, linker, args)
if status != 0:
raise CCompilerError("Linker returned status %s" % status)
return out_file
# Makefile for creating our standalone Cython program
PYVERSION=$(shell python -c "import sys; print sys.version[:3]")
PYPREFIX=$(shell python -c "import sys; print sys.prefix")
PYVERSION=$(shell python -c "import sys; print(sys.version[:3])")
PYPREFIX=$(shell python -c "import sys; print(sys.prefix)")
LINKFORSHARED=$(shell python -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKFORSHARED'))")
INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION)
embedded: embedded.o
gcc -o $@ $^ -lpython$(PYVERSION)
gcc -o $@ $^ $(LINKFORSHARED) -lpython$(PYVERSION) -lm -lpthread -ldl -lutil -L$(PYPREFIX)/lib
embedded.o: embedded.c
gcc -c $^ $(INCLUDES)
......
cdef extern from "mymath.h":
double sinc(double)
def call_sinc(x):
return sinc(x)
#include "math.h"
double sinc(double x) {
return x == 0 ? 1 : sin(x)/x;
}
\ No newline at end of file
double sinc(double);
import os
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
# For demo purposes, we build our own tiny library.
try:
print "building libmymath.a"
assert os.system("gcc -c mymath.c -o mymath.o") == 0
assert os.system("ar rcs libmymath.a mymath.o") == 0
except:
if not os.path.exists("libmymath.a"):
print "Error building external library, please create libmymath.a manually."
sys.exit(1)
# Here is how to use the library built above.
ext_modules=[
Extension("call_mymath",
sources = ["call_mymath.pyx"],
include_dirs = [os.getcwd()], # path to .h file(s)
library_dirs = [os.getcwd()], # path to .a or .so file(s)
libraries = ['mymath'])
]
setup(
name = 'Demos',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
)
include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt
include COPYING.txt LICENSE.txt Makefile
recursive-include .hg *
include .hgignore .hgtags
include .hgrev
include setup.py
include bin/*
include cython.py
......
PYTHON?=python
REPO = http://hg.cython.org/cython-devel
all: local
local:
${PYTHON} setup.py build_ext --inplace
.hg: REV := $(shell cat .hgrev)
.hg: TMPDIR := $(shell mktemp -d tmprepo.XXXXXX)
.hg:
hg clone --rev $(REV) $(REPO) $(TMPDIR)
hg -R $(TMPDIR) update
mv $(TMPDIR)/.hg .
mv $(TMPDIR)/.hgignore .
mv $(TMPDIR)/.hgtags .
rm -rf $(TMPDIR)
repo: .hg
clean:
@echo Cleaning Source
@rm -fr build
......
......@@ -34,7 +34,8 @@ TEST_RUN_DIRS = ['run', 'pyregr']
# Lists external modules, and a matcher matching tests
# which should be excluded if the module is not present.
EXT_DEP_MODULES = {
'numpy' : re.compile('.*\.numpy_.*').match
'numpy' : re.compile('.*\.numpy_.*').match,
'pstats' : re.compile('.*\.pstats_.*').match
}
def get_numpy_include_dirs():
......@@ -403,11 +404,12 @@ class CythonRunTestCase(CythonCompileTestCase):
# fork to make sure we do not keep the tested module loaded
result_handle, result_file = tempfile.mkstemp()
os.close(result_handle)
child_id = os.fork()
if not child_id:
result_code = 0
try:
output = os.fdopen(result_handle, 'wb')
try:
tests = None
try:
partial_result = PartialTestResult(result)
......@@ -423,6 +425,7 @@ class CythonRunTestCase(CythonCompileTestCase):
**{module_name: None})
partial_result.addError(tests, sys.exc_info())
result_code = 1
output = open(result_file, 'wb')
pickle.dump(partial_result.data(), output)
except:
import traceback
......@@ -740,7 +743,12 @@ if __name__ == '__main__':
''')
sys.path.insert(0, cy3_dir)
elif sys.version_info[0] >= 3:
# make sure we do not import (or run) Cython itself
# make sure we do not import (or run) Cython itself (unless
# 2to3 was already run)
cy3_dir = os.path.join(WORKDIR, 'Cy3')
if os.path.isdir(cy3_dir):
sys.path.insert(0, cy3_dir)
else:
options.with_cython = False
options.doctests = False
options.unittests = False
......@@ -856,7 +864,7 @@ if __name__ == '__main__':
os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'),
'pyregr'))
unittest.TextTestRunner(verbosity=options.verbosity).run(test_suite)
result = unittest.TextTestRunner(verbosity=options.verbosity).run(test_suite)
if options.coverage:
coverage.stop()
......@@ -875,3 +883,5 @@ if __name__ == '__main__':
if options.with_refnanny:
import refnanny
sys.stderr.write("\n".join([repr(x) for x in refnanny.reflog]))
sys.exit(not result.wasSuccessful())
......@@ -3,6 +3,17 @@ from distutils.sysconfig import get_python_lib
import os, os.path
import sys
if 'sdist' in sys.argv:
# Record the current revision in .hgrev
import subprocess # os.popen is cleaner but depricated
changset = subprocess.Popen("hg log --rev tip | grep changeset",
shell=True,
stdout=subprocess.PIPE).stdout.read()
rev = changset.split(':')[-1].strip()
hgrev = open('.hgrev', 'w')
hgrev.write(rev)
hgrev.close()
compiler_dir = os.path.join(get_python_lib(prefix=''), 'Cython/Compiler')
if sys.platform == "win32":
compiler_dir = compiler_dir[len(sys.prefix)+1:]
......@@ -31,7 +42,6 @@ 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, [ f for pattern in
['Cython/Includes/*.pxd',
'Cython/Plex/*.pxd',
......@@ -39,8 +49,7 @@ if sys.version_info < (2,4):
'Cython/Runtime/*.pyx']
for f in glob.glob(pattern) ])]
else:
setup_args['package_data'] = {'Cython.Compiler' : ['Lexicon.pickle'],
'Cython' : ['Includes/*.pxd',
setup_args['package_data'] = {'Cython' : ['Includes/*.pxd',
'Plex/*.pxd',
'Compiler/*.pxd',
'Runtime/*.pyx']}
......@@ -161,8 +170,6 @@ setup(
'Cython.Compiler',
'Cython.Runtime',
'Cython.Distutils',
'Cython.Mac',
'Cython.Unix',
'Cython.Plex',
'Cython.Tests',
......
......@@ -6,4 +6,5 @@ class_attribute_init_values_T18
numpy_ValueError_T172
unsignedbehaviour_T184
missing_baseclass_in_predecl_T262
tp_new_T454
cfunc_call_tuple_args_T408
cascaded_list_unpacking_T467
# cython: boundscheck = False
# cython: ignoreme = OK
# cython: warn.undeclared = False
# This testcase is most useful if you inspect the generated C file
......@@ -32,3 +33,8 @@ def i(object[int] buf):
with bc(True):
print buf[3] # bs
from cython cimport warn as my_warn
@my_warn(undeclared=True)
def j():
pass
......@@ -9,6 +9,7 @@ cdef class Swallow:
def f(Grail g):
cdef int i = 0
cdef Swallow s
cdef object x
g = x
x = g
g = i
......
cdef class vector:
def __div__(vector self, double factor):
result = vector()
cdef object result = vector()
return result
cdef extern from *:
ctypedef class __builtin__.list [object PyListObject]:
pass
cdef list foo = []
# This is too invasive for Python 0.11.x, re-enable in 0.12
NEW_ERRORS = u"""
:2:4: list already a builtin Cython type
"""
_ERRORS = u"""
5:16: Cannot coerce list to type 'list'
"""
......@@ -15,17 +15,17 @@ cdef void eggs(Spam s):
j = s.k # error - undef attribute
j = s.p # type error
s.p = j # type error
j = j.i # error - no attributes
j.i = j # error - no attributes
j = j.i # no error - coercion to Python object
j.i = j # no error - coercion to Python object
j = gp.x # error - incomplete type
gp.x = j # error - incomplete type
_ERRORS = u"""
5:36: C struct/union member cannot be a Python object
15:6: Object of type 'Spam' has no attribute 'k'
16:6: Cannot assign type 'float *[42]' to 'int'
17:21: Cannot assign type 'int' to 'float *[42]'
18:6: Object of type 'int' has no attribute 'i'
19:2: Object of type 'int' has no attribute 'i'
20:7: Cannot select attribute of incomplete type 'Grail'
21:3: Cannot select attribute of incomplete type 'Grail'
"""
......@@ -8,6 +8,7 @@ def test():
neg
pos
"""
cdef object D
cdef long neg = -1
cdef unsigned long pos = -2 # will be a large positive number
......
......@@ -177,7 +177,7 @@ def char3int(fmt):
...
ValueError: Buffer dtype mismatch, expected 'int' but got end in 'Char3Int.d'
"""
obj = MockBuffer(fmt, sizeof(Char3Int))
cdef object obj = MockBuffer(fmt, sizeof(Char3Int))
cdef object[Char3Int, ndim=1] buf = obj
@testcase
......@@ -195,7 +195,7 @@ def unpacked_struct(fmt):
assert (sizeof(UnpackedStruct1) == sizeof(UnpackedStruct2)
== sizeof(UnpackedStruct3) == sizeof(UnpackedStruct4))
obj = MockBuffer(fmt, sizeof(UnpackedStruct1))
cdef object obj = MockBuffer(fmt, sizeof(UnpackedStruct1))
cdef object[UnpackedStruct1, ndim=1] buf1 = obj
cdef object[UnpackedStruct2, ndim=1] buf2 = obj
cdef object[UnpackedStruct3, ndim=1] buf3 = obj
......@@ -218,7 +218,7 @@ def complex_test(fmt):
ValueError: Buffer dtype mismatch, expected 'float' but got 'complex float' in 'ComplexFloat.imag'
"""
obj = MockBuffer(fmt, sizeof(ComplexTest))
cdef object obj = MockBuffer(fmt, sizeof(ComplexTest))
cdef object[ComplexTest] buf1 = obj
......
__doc__ = u"""
>>> test_xrange()
0
1
2
>>> test_range()
0
1
2
>>> test_long() == 12
True
>>> test_int() == 12
True
"""
# the builtins 'xrange' and 'long' are not available in Py3, but they
# can safely be replaced by 'range' and 'int' on that platform
import sys
IS_PY3 = sys.version_info[0] >= 3
def test_xrange():
r = xrange(3)
assert type(r) is xrange
for i in r:
print i
def test_range():
r = range(3)
assert (type(r) is range) if IS_PY3 else (type(r) is list)
for i in r:
print i
def test_long():
long_val = long(12)
assert type(long_val) is long
return long_val
def test_int():
int_val = int(12)
assert type(int_val) is int
return int_val
cimport cython
@cython.test_assert_path_exists(
'//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
def get_type_of(a):
"""
>>> get_type_of(object()) is object
True
"""
return type(a)
@cython.test_assert_path_exists(
'//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
def get_type_through_local(a):
"""
>>> get_type_of(object()) is object
True
"""
t = type(a)
return t
@cython.test_assert_path_exists(
'//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]')
@cython.test_fail_if_path_exists(
'//PythonCapiCallNode/PythonCapiFunctionNode[@cname="__Pyx_Type"]',
'//NameNode[@name="type"]')
def test_type(a, t):
"""
>>> test_type(object(), object)
True
"""
return type(a) and type(a) is t and type(a) == t
@cython.test_assert_path_exists('//NameNode[@name="type"]')
def type_type():
"""
>>> type_type()(object()) is object
True
"""
return type
cimport cython
def test_file_py(file):
assert isinstance(file, (str, unicode)), \
u"not a string, found '%s' instead" % file.__class__.__name__
......@@ -12,19 +14,45 @@ cdef test_file_c(file):
def range(arg):
return u'range' + arg
def len(arg):
return u'len' + arg
cdef type(arg):
return u'type' + arg
@cython.test_fail_if_path_exists(
'//SimpleCallNode/NameNode[@name="type" and @entry.is_cfunction=False]',
'//SimpleCallNode/NameNode[@name="len" and @entry.is_cfunction=True]',
)
@cython.test_assert_path_exists(
'//SimpleCallNode/NameNode[@name="type"]',
'//SimpleCallNode/NameNode[@name="type" and @entry.is_cfunction=True]',
'//SimpleCallNode/NameNode[@name="len"]',
)
def test_c(arg):
"""
>>> test_c('abc')
fileabc
lenabc
typeabc
>>> print(test_file_py('abc'))
abc
>>> print(range('abc'))
rangeabc
>>> print(len('abc'))
lenabc
"""
print test_file_c(arg)
print len(arg)
print type(arg)
def test_for_in_range(arg):
"""
>>> print(str(test_for_in_range('abc')).replace("u'", "'"))
['r', 'a', 'n', 'g', 'e', 'a', 'b', 'c']
"""
l = []
for c in range(arg):
l.append(c)
return l
__doc__ = ''
import sys
if sys.version_info >= (2,6):
__doc__ += '''
>>> float_is_integer(1.0)
True
>>> float_is_integer(1.1)
False
'''
if sys.version_info >= (3,1):
__doc__ += '''
>>> int_bit_length(1) == (1).bit_length()
True
>>> int_bit_length(1234) == (1234).bit_length()
True
'''
def float_is_integer(float f):
# requires Python 2.6+
return f.is_integer()
def int_bit_length(int i):
# requires Python 3.x
return i.bit_length()
def float__add__(float f):
"""
>>> float__add__(5.0)
7.0
"""
return f.__add__(2)
def int__add__(int i):
"""
>>> int__add__(5)
7
"""
return i.__add__(2)
......@@ -13,39 +13,6 @@ def slice_charptr_end():
"""
return cstring[:1], cstring[:3], cstring[:9]
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode():
"""
>>> print(str(slice_charptr_decode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8'),
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_unbound():
"""
>>> print(str(slice_charptr_decode_unbound()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (bytes.decode(cstring[:1], 'UTF-8'),
bytes.decode(cstring[:3], 'UTF-8', 'replace'),
bytes.decode(cstring[:9], 'UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_errormode():
"""
>>> print(str(slice_charptr_decode_errormode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8', 'strict'),
cstring[:3].decode('UTF-8', 'replace'),
cstring[:9].decode('UTF-8', 'unicode_escape'))
@cython.test_assert_path_exists("//ForFromStatNode",
"//ForFromStatNode//SliceIndexNode")
@cython.test_fail_if_path_exists("//ForInStatNode")
......@@ -95,7 +62,7 @@ def slice_charptr_for_loop_c():
@cython.test_fail_if_path_exists("//ForInStatNode")
def slice_charptr_for_loop_c_dynamic_bounds():
"""
>>> slice_charptr_for_loop_c()
>>> slice_charptr_for_loop_c_dynamic_bounds()
['a', 'b', 'c']
['b', 'c', 'A', 'B']
['B', 'C', 'q', 't', 'p']
......
def simple_parallel_assignment_from_call():
"""
>>> simple_parallel_assignment_from_call()
(2, 1, 2, 1, 2, 1, 2, [1, 2], [1, 2])
"""
cdef int ai, bi
cdef long al, bl
cdef object ao, bo
cdef int side_effect_count = call_count
ai, bi = al, bl = ao, bo = c = d = [intval(1), intval(2)]
side_effect_count = call_count - side_effect_count
return side_effect_count, ao, bo, ai, bi, al, bl, c, d
def recursive_parallel_assignment_from_call():
"""
>>> recursive_parallel_assignment_from_call()
(3, 1, 2, 3, 1, 2, 3, (1, 2), 3, [(1, 2), 3])
"""
cdef int ai, bi, ci
cdef object ao, bo, co
cdef int side_effect_count = call_count
(ai, bi), ci = (ao, bo), co = t,o = d = [(intval(1), intval(2)), intval(3)]
side_effect_count = call_count - side_effect_count
return side_effect_count, ao, bo, co, ai, bi, ci, t, o, d
cdef int call_count = 0
cdef int intval(int x):
global call_count
call_count += 1
return x
# extension to T409
def simple_parallel_typed():
"""
>>> simple_parallel_typed()
(1, 2, [1, 2], [1, 2])
"""
cdef int a,c
a, c = d = e = [1,2]
return a, c, d, e
def simple_parallel_int_mix():
"""
>>> simple_parallel_int_mix()
(1, 2, 1, 2, 1, 2, [1, 2], [1, 2])
"""
cdef int ai,bi
cdef long al,bl
cdef object ao, bo
ai, bi = al, bl = ao, bo = c = d = [1,2]
return ao, bo, ai, bi, al, bl, c, d
cimport cython
cdef class cclass:
@classmethod
def test0(cls):
"""
>>> cclass.test0()
'type object'
"""
return cython.typeof(cls)
@classmethod
def test0_args(*args):
"""
>>> cclass.test0_args(1,2,3)
('Python object', (1, 2, 3))
"""
return cython.typeof(args[0]), args[1:]
@classmethod
def test1(cls, arg):
"""
>>> cclass.test1(1)
('type object', 1)
"""
return cython.typeof(cls), arg
@classmethod
def test2(cls, arg1, arg2):
"""
>>> cclass.test2(1,2)
('type object', 1, 2)
"""
return cython.typeof(cls), arg1, arg2
@classmethod
def test1_args(cls, *args):
"""
>>> cclass.test1_args(1,2,3)
('type object', (1, 2, 3))
"""
return cython.typeof(cls), args
@classmethod
def test2_args(cls, arg, *args):
"""
>>> cclass.test2_args(1,2,3)
('type object', 1, (2, 3))
"""
return cython.typeof(cls), arg, args
@classmethod
def test0_args_kwargs(*args, **kwargs):
"""
>>> cclass.test0_args_kwargs(1,2,3)
('Python object', (1, 2, 3), {})
"""
return cython.typeof(args[0]), args[1:], kwargs
@classmethod
def test1_args_kwargs(cls, *args, **kwargs):
"""
>>> cclass.test1_args_kwargs(1,2,3)
('type object', (1, 2, 3), {})
"""
return cython.typeof(cls), args, kwargs
@classmethod
def test2_args_kwargs(cls, arg, *args, **kwargs):
"""
>>> cclass.test2_args_kwargs(1,2,3)
('type object', 1, (2, 3), {})
"""
return cython.typeof(cls), arg, args, kwargs
cimport cython
cdef class cclass:
def test_self(self):
"""
>>> cclass().test_self()
'cclass'
"""
return cython.typeof(self)
def test_self_1(self, arg):
"""
>>> cclass().test_self_1(1)
('cclass', 1)
"""
return cython.typeof(self), arg
def test_self_args(self, *args):
"""
>>> cclass().test_self_args(1,2,3)
('cclass', (1, 2, 3))
"""
return cython.typeof(self), args
def test_args(*args):
"""
>>> cclass().test_args(1,2,3)
('Python object', (1, 2, 3))
"""
return cython.typeof(args[0]), args[1:]
def test_args_kwargs(*args, **kwargs):
"""
>>> cclass().test_args_kwargs(1,2,3, a=4)
('Python object', (1, 2, 3), {'a': 4})
"""
return cython.typeof(args[0]), args[1:], kwargs
......@@ -23,7 +23,7 @@ def call0():
>>> call0()
(True, u'yo')
"""
a = A()
cdef A a = A()
return a.foo()
def call1():
......@@ -31,7 +31,7 @@ def call1():
>>> call1()
(False, u'yo')
"""
a = A()
cdef A a = A()
return a.foo(False)
def call2():
......@@ -39,5 +39,5 @@ def call2():
>>> call2()
(False, u'go')
"""
a = A()
cdef A a = A()
return a.foo(False, u"go")
......@@ -2,10 +2,10 @@ def no_cdef():
"""
>>> no_cdef()
"""
lst = list(range(11))
cdef object lst = list(range(11))
ob = 10L
lst[ob] = -10
dd = {}
cdef object dd = {}
dd[ob] = -10
def with_cdef():
......
__doc__ = """
>>> call_with_tuple(1, 1.2, 'test', [1,2,3])
(1, 1.2, 'test', [1, 2, 3])
>>> call_with_list(1, 1.2, None, None)
(1, 1.2, None, None)
"""
cdef c_function(int a, float b, c, list d):
return a,b,c,d
def call_with_tuple(*args):
return c_function(*args)
def call_with_list(*args):
args = list(args)
return c_function(*args)
cimport cython
############################################################
# tests for char* slicing
cdef char* cstring = "abcABCqtp"
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode():
"""
>>> print(str(slice_charptr_decode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8'),
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_unknown_encoding():
"""
>>> print(str(slice_charptr_decode_unknown_encoding()).replace("u'", "'"))
('abcABCqtp', 'abcABCqtp', 'abc', 'abcABCqt')
"""
cdef char* enc = 'UTF-8'
cdef char* error_handling = 'strict'
return (cstring.decode(enc),
cstring.decode(enc, error_handling),
cstring[:3].decode(enc),
cstring[:8].decode(enc, error_handling))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_slice2():
"""
>>> print(str(slice_charptr_decode_slice2()).replace("u'", "'"))
('a', 'bc', 'tp')
"""
return (cstring[0:1].decode('UTF-8'),
cstring[1:3].decode('UTF-8'),
cstring[7:9].decode('UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_strlen():
"""
>>> print(str(slice_charptr_decode_strlen()).replace("u'", "'"))
('abcABCqtp', 'bcABCqtp', '')
"""
return (cstring.decode('UTF-8'),
cstring[1:].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_unbound():
"""
>>> print(str(slice_charptr_decode_unbound()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (bytes.decode(cstring[:1], 'UTF-8'),
bytes.decode(cstring[:3], 'UTF-8', 'replace'),
bytes.decode(cstring[:9], 'UTF-8'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_decode_errormode():
"""
>>> print(str(slice_charptr_decode_errormode()).replace("u'", "'"))
('a', 'abc', 'abcABCqtp')
"""
return (cstring[:1].decode('UTF-8', 'strict'),
cstring[:3].decode('UTF-8', 'replace'),
cstring[:9].decode('UTF-8', 'unicode_escape'))
@cython.test_assert_path_exists("//PythonCapiCallNode")
@cython.test_fail_if_path_exists("//AttributeNode")
def slice_charptr_dynamic_bounds():
"""
>>> print(str(slice_charptr_dynamic_bounds()).replace("u'", "'"))
('abc', 'abc', 'bcAB', 'BCqtp')
"""
return (cstring[:return3()].decode('UTF-8'),
cstring[0:return3()].decode('UTF-8'),
cstring[return1():return5()].decode('UTF-8'),
cstring[return4():return9()].decode('UTF-8'))
cdef return1(): return 1
cdef return3(): return 3
cdef return4(): return 4
cdef return5(): return 5
cdef return9(): return 9
__doc__ = """
>>> lentest_char()
7
>>> lentest_char_c()
7
>>> lentest_uchar()
7
>>> lentest_uchar_c()
7
>>> lentest_py()
7
>>> lentest_py_c()
7
"""
cimport cython
cdef char* s = b"abcdefg"
cdef unsigned char* us = b"abcdefg"
cdef bytes pystr = b"abcdefg"
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_char():
return len(s)
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_char_c():
cdef Py_ssize_t l = len(s)
return l
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_uchar():
return len(us)
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_uchar_c():
cdef Py_ssize_t l = len(us)
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
cdef class MyType:
def dup(self):
"""
>>> x1 = MyType()
>>> isinstance(x1, MyType)
True
>>> x2 = x1.dup()
>>> isinstance(x2, MyType)
True
>>> x1 != x2
True
"""
cdef MyType clone = <MyType>type(self)()
return clone
cdef extern from "Python.h":
ctypedef class __builtin__.str [object PyStringObject]:
cdef long ob_shash
ctypedef class __builtin__.list [object PyListObject]:
cdef Py_ssize_t ob_size
cdef Py_ssize_t allocated
ctypedef class __builtin__.dict [object PyDictObject]:
pass
cdef str s = "abc"
cdef list L = [1,2,4]
cdef dict d = {'A': 'a'}
def test_list(list L):
"""
>>> test_list(list(range(10)))
True
>>> class list_subclass(list): pass
>>> test_list(list_subclass([1,2,3]))
True
"""
return L.ob_size <= L.allocated
def test_str(str s):
"""
>>> test_str("abc")
True
>>> class str_subclass(str): pass
>>> test_str(str_subclass("xyz"))
True
"""
cdef char* ss = s
return hash(s) == s.ob_shash
def test_tuple(tuple t):
"""
Actual builtin types are restrictive wrt subclassing so optimizations can be safely performed.
>>> test_tuple((1,2))
2
>>> class tuple_subclass(tuple): pass
>>> test_tuple(tuple_subclass((1,2)))
Traceback (most recent call last):
...
TypeError: Argument 't' has incorrect type (expected tuple, got tuple_subclass)
"""
return len(t)
def f(x):
return x
def len_f(x):
"""
>>> len_f([1,2,3])
3
"""
return len(f(x))
def float_len_f(x):
"""
>>> float_len_f([1,2,3])
3.0
"""
return float(len(f(x)))
def cast_len_f(x):
"""
>>> cast_len_f([1,2,3])
3.0
"""
return <double>len(f(x))
......@@ -11,6 +11,7 @@ if sys.version_info[0] >= 3:
elif sys.version_info < (2,5):
__doc__ = __doc__.replace(u"'int' object is unsubscriptable", u'unsubscriptable object')
import cython
def index_tuple(tuple t, int i):
"""
......@@ -113,3 +114,15 @@ def test_long_long():
assert D[ix] is True
del D[ix]
assert len(D) == 0
@cython.boundscheck(False)
def test_boundscheck(list L, tuple t, object o, unsigned long ix):
"""
>>> test_boundscheck([1, 2, 4], (1, 2, 4), [1, 2, 4], 2)
(4, 4, 4)
>>> test_boundscheck([1, 2, 4], (1, 2, 4), "", 2)
Traceback (most recent call last):
...
IndexError: string index out of range
"""
return L[ix], t[ix], o[ix]
......@@ -7,7 +7,7 @@ def f(a,b):
>>> f(2,(1,2,3))
True
"""
result = a in b
cdef object result = a in b
return result
def g(a,b):
......@@ -19,8 +19,7 @@ def g(a,b):
>>> g(2,(1,2,3))
1
"""
cdef int result
result = a in b
cdef int result = a in b
return result
def h(b):
......@@ -30,7 +29,7 @@ def h(b):
>>> h([1,3,4])
False
"""
result = 2 in b
cdef object result = 2 in b
return result
def j(b):
......@@ -40,8 +39,7 @@ def j(b):
>>> j([1,3,4])
0
"""
cdef int result
result = 2 in b
cdef int result = 2 in b
return result
def k(a):
......@@ -104,8 +102,8 @@ def r(a):
>>> r(2)
1
"""
l = [1,2,3,4]
l2 = [l[1:],l[:-1],l]
cdef object l = [1,2,3,4]
cdef object l2 = [l[1:],l[:-1],l]
cdef int result = a in l in l2
return result
......
......@@ -107,7 +107,7 @@ def test_side_effects():
c side effect 4
([0, 11, 102, 3, 4], [0, 1, 2, 13, 104])
"""
a = list(range(5))
cdef object a = list(range(5))
a[side_effect(1)] += 10
a[c_side_effect(2)] += 100
cdef int i
......
cimport cython
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def double_to_short_int(double x):
"""
......@@ -13,7 +13,7 @@ def double_to_short_int(double x):
cdef short r = int(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def double_to_pyssizet_int(double x):
"""
......@@ -25,7 +25,7 @@ def double_to_pyssizet_int(double x):
cdef Py_ssize_t r = int(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def int_to_pyssizet_int(int x):
"""
......@@ -37,19 +37,19 @@ def int_to_pyssizet_int(int x):
cdef Py_ssize_t r = int(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def double_to_pyssizet_float(double x):
"""
>>> double_to_pyssizet_float(4.1)
4
>>> double_to_pyssizet_float(4)
4
"""
cdef Py_ssize_t r = float(x)
return r
## @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
## @cython.test_fail_if_path_exists("//SimpleCallNode")
## def double_to_pyssizet_float(double x):
## """
## >>> double_to_pyssizet_float(4.1)
## 4
## >>> double_to_pyssizet_float(4)
## 4
## """
## cdef Py_ssize_t r = float(x)
## return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def int_to_short_int(int x):
"""
......@@ -59,7 +59,7 @@ def int_to_short_int(int x):
cdef short r = int(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def short_to_float_float(short x):
"""
......@@ -69,7 +69,7 @@ def short_to_float_float(short x):
cdef float r = float(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def short_to_double_float(short x):
"""
......@@ -79,7 +79,7 @@ def short_to_double_float(short x):
cdef double r = float(x)
return r
@cython.test_assert_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def short_to_double_int(short x):
"""
......@@ -89,8 +89,7 @@ def short_to_double_int(short x):
cdef double r = int(x)
return r
@cython.test_fail_if_path_exists("//SimpleCallNode",
"//SingleAssignmentNode/CastNode")
@cython.test_fail_if_path_exists("//SimpleCallNode")
def float_to_float_float(float x):
"""
>>> 4.05 < float_to_float_float(4.1) < 4.15
......@@ -102,7 +101,7 @@ def float_to_float_float(float x):
return r
@cython.test_fail_if_path_exists("//SimpleCallNode",
"//SingleAssignmentNode/CastNode")
"//SingleAssignmentNode/TypecastNode")
def double_to_double_float(double x):
"""
>>> 4.05 < double_to_double_float(4.1) < 4.15
......@@ -115,7 +114,7 @@ def double_to_double_float(double x):
# tests that cannot be optimised
@cython.test_fail_if_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_fail_if_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_assert_path_exists("//SimpleCallNode")
def double_to_py_int(double x):
"""
......@@ -126,7 +125,7 @@ def double_to_py_int(double x):
"""
return int(x)
@cython.test_fail_if_path_exists("//SingleAssignmentNode/CastNode")
@cython.test_fail_if_path_exists("//SingleAssignmentNode/TypecastNode")
@cython.test_assert_path_exists("//SimpleCallNode")
def double_to_double_int(double x):
"""
......
cdef class A:
pass
import sys
IS_PY3 = sys.version_info[0] >= 3
def test_all():
"""
>>> test_all()
True
"""
if IS_PY3:
new_type = type(u'a',(),{})
else:
new_type = type('a',(),{})
# Optimized tests.
......
import sys
def test(**kw):
"""
......@@ -19,8 +18,5 @@ def test(**kw):
>>> d
{'arg': 2}
"""
if sys.version_info[0] >= 3:
kw[u'arg'] = 3
else:
kw['arg'] = 3
return kw
......@@ -10,7 +10,7 @@ class A:
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def simple_pop(L):
"""
>>> L = range(10)
>>> L = list(range(10))
>>> simple_pop(L)
9
>>> simple_pop(L)
......@@ -36,7 +36,7 @@ def simple_pop(L):
@cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode')
def index_pop(L, int i):
"""
>>> L = range(10)
>>> L = list(range(10))
>>> index_pop(L, 2)
2
>>> index_pop(L, -2)
......@@ -71,7 +71,7 @@ def index_pop(L, int i):
@cython.test_fail_if_path_exists('//PythonCapiCallNode')
def crazy_pop(L):
"""
>>> crazy_pop(range(10))
>>> crazy_pop(list(range(10)))
Traceback (most recent call last):
...
TypeError: pop() takes at most 1 argument (3 given)
......
......@@ -6,7 +6,7 @@ __doc__ = u"""
[('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)]
>>> sorted(get_locals_items_listcomp(1,2,3, k=5))
[('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)]
[('args', (2, 3)), ('item', None), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)]
"""
def get_locals(x, *args, **kwds):
......@@ -20,6 +20,7 @@ def get_locals_items(x, *args, **kwds):
return locals().items()
def get_locals_items_listcomp(x, *args, **kwds):
# FIXME: 'item' should *not* appear in locals() !
cdef int z = 5
y = "hi"
return [ item for item in locals().items() ]
......
......@@ -11,7 +11,7 @@ __doc__ = u"""
ctypedef long long foo
def set_longlong(long long ob, foo x, long y, val):
tank = {}
cdef object tank = {}
tank[ob] = val
tank[x] = val
tank[y] = val
......
__doc__ = u"""
>>> func(**{'a' : 7})
True
>>> func(**SubDict())
True
>>> call_non_dict_test()
True
>>> call_non_dict_test_kw()
True
>>> call_sub_dict_test()
True
>>> call_sub_dict_test_kw()
True
"""
import sys
if sys.version_info >= (2,6):
__doc__ += u"""
>>> func(**NonDict())
True
"""
def func(**kwargs):
return type(kwargs) is dict and kwargs['a'] == 7
class NonDict(object):
def __getitem__(self, k):
assert k == 'a'
return 7
def keys(self):
return ['a']
def call_non_dict_test():
return func(**NonDict())
def call_non_dict_test_kw():
return func(a=5, **NonDict())
class SubDict(dict):
def __init__(self):
self['a'] = 7
def call_sub_dict_test():
return func(**SubDict())
def call_sub_dict_test_kw():
return func(a=5, **SubDict())
......@@ -14,7 +14,7 @@ cdef extern from *:
def f():
cdef void* p1
cdef PyObject* p2
a = u"teststring"
cdef object a = u"teststring"
p1 = <void*>a
p2 = <PyObject*>a
return (<object>p1, <object>p2)
......@@ -9,6 +9,9 @@ TypeError
Traceback (most recent call last):
TypeError
>>> call_try_return_with_exception()
1
>>> def try_return_py():
... try:
... return 1
......@@ -18,6 +21,8 @@ TypeError
2
>>> try_return_cy()
2
>>> call_try_return_c()
2
>>> i=1
>>> for i in range(3):
......@@ -46,6 +51,24 @@ def try_return_cy():
finally:
return 2
cdef int try_return_c():
try:
return 1
finally:
return 2
def call_try_return_c():
return try_return_c()
cdef int try_return_with_exception():
try:
raise TypeError
finally:
return 1
def call_try_return_with_exception():
return try_return_with_exception()
def try_return_temp(a):
b = a+2
try:
......
# cython: infer_types = True
from cython cimport typeof
cimport cython
from cython cimport typeof, infer_types
##################################################
# type inference tests in 'full' mode
cdef class MyType:
pass
def simple():
"""
......@@ -26,6 +33,44 @@ def simple():
t = (4,5,6)
assert typeof(t) == "tuple object", typeof(t)
def builtin_types():
"""
>>> builtin_types()
"""
b = bytes()
assert typeof(b) == "bytes object", typeof(b)
u = unicode()
assert typeof(u) == "unicode object", typeof(u)
L = list()
assert typeof(L) == "list object", typeof(L)
t = tuple()
assert typeof(t) == "tuple object", typeof(t)
d = dict()
assert typeof(d) == "dict object", typeof(d)
B = bool()
assert typeof(B) == "bool object", typeof(B)
def slicing():
"""
>>> slicing()
"""
b = b"abc"
assert typeof(b) == "char *", typeof(b)
b1 = b[1:2]
assert typeof(b1) == "bytes object", typeof(b1)
u = u"xyz"
assert typeof(u) == "unicode object", typeof(u)
u1 = u[1:2]
assert typeof(u1) == "unicode object", typeof(u1)
L = [1,2,3]
assert typeof(L) == "list object", typeof(L)
L1 = L[1:2]
assert typeof(L1) == "list object", typeof(L1)
t = (4,5,6)
assert typeof(t) == "tuple object", typeof(t)
t1 = t[1:2]
assert typeof(t1) == "tuple object", typeof(t1)
def multiple_assignments():
"""
>>> multiple_assignments()
......@@ -43,9 +88,9 @@ def multiple_assignments():
c = [1,2,3]
assert typeof(c) == "Python object"
def arithmatic():
def arithmetic():
"""
>>> arithmatic()
>>> arithmetic()
"""
a = 1 + 2
assert typeof(a) == "long"
......@@ -105,3 +150,102 @@ def loop():
for d in range(0, 10L, 2):
pass
assert typeof(a) == "long"
cdef unicode retu():
return u"12345"
cdef bytes retb():
return b"12345"
def conditional(x):
"""
>>> conditional(True)
(True, 'Python object')
>>> conditional(False)
(False, 'Python object')
"""
if x:
a = retu()
else:
a = retb()
return type(a) is unicode, typeof(a)
##################################################
# type inference tests that work in 'safe' mode
@infer_types(None)
def double_inference():
"""
>>> values, types = double_inference()
>>> values == (1.0, 1.0*2, 1.0*2.0+2.0*2.0, 1.0*2.0)
True
>>> types
('double', 'double', 'double', 'Python object')
"""
d_a = 1.0
d_b = d_a * float(2)
d_c = d_a * float(some_float_value()) + d_b * float(some_float_value())
o_d = d_a * some_float_value()
return (d_a,d_b,d_c,o_d), (typeof(d_a), typeof(d_b), typeof(d_c), typeof(o_d))
cdef object some_float_value():
return 2.0
@cython.test_fail_if_path_exists('//NameNode[@type.is_pyobject = True]')
@cython.test_assert_path_exists('//InPlaceAssignmentNode/NameNode',
'//NameNode[@type.is_pyobject]',
'//NameNode[@type.is_pyobject = False]')
@infer_types(None)
def double_loop():
"""
>>> double_loop() == 1.0 * 10
True
"""
cdef int i
d = 1.0
for i in range(9):
d += 1.0
return d
@infer_types(None)
def safe_only():
"""
>>> safe_only()
"""
a = 1.0
assert typeof(a) == "double", typeof(c)
b = 1
assert typeof(b) == "Python object", typeof(b)
c = MyType()
assert typeof(c) == "MyType", typeof(c)
@infer_types(None)
def args_tuple_keywords(*args, **kwargs):
"""
>>> args_tuple_keywords(1,2,3, a=1, b=2)
"""
assert typeof(args) == "tuple object", typeof(args)
assert typeof(kwargs) == "dict object", typeof(kwargs)
@infer_types(None)
def args_tuple_keywords_reassign_same(*args, **kwargs):
"""
>>> args_tuple_keywords_reassign_same(1,2,3, a=1, b=2)
"""
assert typeof(args) == "tuple object", typeof(args)
assert typeof(kwargs) == "dict object", typeof(kwargs)
args = ()
kwargs = {}
@infer_types(None)
def args_tuple_keywords_reassign_pyobjects(*args, **kwargs):
"""
>>> args_tuple_keywords_reassign_pyobjects(1,2,3, a=1, b=2)
"""
assert typeof(args) == "Python object", typeof(args)
assert typeof(kwargs) == "Python object", typeof(kwargs)
args = []
kwargs = "test"
......@@ -53,7 +53,6 @@ def slice_list_assign(list l, value):
def slice_charp(py_string_arg):
"""
>>> l = [1,2,3,4]
>>> print("%s" % slice_charp('abcdefg'))
bc
"""
......@@ -63,7 +62,6 @@ def slice_charp(py_string_arg):
def slice_charp_repeat(py_string_arg):
"""
>>> l = [1,2,3,4]
>>> print("%s" % slice_charp_repeat('abcdefg'))
cd
"""
......
......@@ -44,7 +44,7 @@ def f():
42.0
42.0
"""
c = MyClass()
cdef object c = MyClass()
print c.actual_double
print c.float_isreally_double
......@@ -55,10 +55,10 @@ def longdouble_access():
...
SystemError: bad memberdescr type
"""
c = MyClass()
cdef object c = MyClass()
print c.float_isreally_longdouble
def readonly():
c = MyClass()
cdef object c = MyClass()
c.actual_double = 3
......@@ -4,6 +4,6 @@ def test():
True
"""
cdef int a,b
foo=(55,66)
a,b=foo
cdef object foo = (55,66)
a,b = foo
return a + b
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