summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ModuleNode.py
diff options
context:
space:
mode:
authorStefan Behnel <scoder@users.berlios.de>2008-05-13 23:10:50 +0200
committerStefan Behnel <scoder@users.berlios.de>2008-05-13 23:10:50 +0200
commit211a89f09dfd70fab5a1f8e08e414242a9a00d0c (patch)
treec50a27f7d26a6991432505e88dcc0cfb4076a3e7 /Cython/Compiler/ModuleNode.py
parent138f21b3f3b7836e8d983f54d6b3e7011303aac4 (diff)
parenta927b5a7c933cef6daade90a9b6b3799e930bc15 (diff)
downloadcython-211a89f09dfd70fab5a1f8e08e414242a9a00d0c.tar.gz
merged trunk changes
Diffstat (limited to 'Cython/Compiler/ModuleNode.py')
-rw-r--r--Cython/Compiler/ModuleNode.py55
1 files changed, 37 insertions, 18 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index d94f886be..1ef54be06 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -209,7 +209,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_c_code(self, env, options, result):
modules = self.referenced_modules
- if Options.annotate:
+ if Options.annotate or options.annotate:
code = Annotate.AnnotationCCodeWriter(StringIO())
else:
code = Code.CCodeWriter(StringIO())
@@ -238,16 +238,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_declarations_for_modules(env, modules, code.h)
-
f = open_new_file(result.c_file)
f.write(code.h.f.getvalue())
f.write("\n")
f.write(code.f.getvalue())
f.close()
result.c_file_generated = 1
- if Options.annotate:
+ if Options.annotate or options.annotate:
self.annotate(code)
- code.save_annotation(result.c_file[:-1] + "pyx") # change?
+ code.save_annotation(result.main_source_file, result.c_file)
def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen:
@@ -709,7 +708,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__setslice__", "__delslice__"]):
self.generate_ass_slice_function(scope, code)
- if scope.defines_any(["__getattr__"]):
+ if scope.defines_any(["__getattr__","__getattribute__"]):
self.generate_getattro_function(scope, code)
if scope.defines_any(["__setattr__", "__delattr__"]):
self.generate_setattro_function(scope, code)
@@ -1073,27 +1072,47 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"}")
def generate_getattro_function(self, scope, code):
- # First try to get the attribute using PyObject_GenericGetAttr.
- # If that raises an AttributeError, call the user's __getattr__
- # method.
- entry = scope.lookup_here("__getattr__")
+ # First try to get the attribute using __getattribute__, if defined, or
+ # PyObject_GenericGetAttr.
+ #
+ # If that raises an AttributeError, call the __getattr__ if defined.
+ #
+ # In both cases, defined can be in this class, or any base class.
+ def lookup_here_or_base(n,type=None):
+ # Recursive lookup
+ if type is None:
+ type = scope.parent_type
+ r = type.scope.lookup_here(n)
+ if r is None and \
+ type.base_type is not None:
+ return lookup_here_or_base(n,type.base_type)
+ else:
+ return r
+ getattr_entry = lookup_here_or_base("__getattr__")
+ getattribute_entry = lookup_here_or_base("__getattribute__")
code.putln("")
code.putln(
"static PyObject *%s(PyObject *o, PyObject *n) {"
% scope.mangle_internal("tp_getattro"))
- code.putln(
+ if getattribute_entry is not None:
+ code.putln(
+ "PyObject *v = %s(o, n);" %
+ getattribute_entry.func_cname)
+ else:
+ code.putln(
"PyObject *v = PyObject_GenericGetAttr(o, n);")
- code.putln(
+ if getattr_entry is not None:
+ code.putln(
"if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
- code.putln(
- "PyErr_Clear();")
- code.putln(
- "v = %s(o, n);" %
- entry.func_cname)
- code.putln(
+ code.putln(
+ "PyErr_Clear();")
+ code.putln(
+ "v = %s(o, n);" %
+ getattr_entry.func_cname)
+ code.putln(
"}")
code.putln(
- "return v;")
+ "return v;")
code.putln(
"}")