fix modifiers of functions with overrides in external .pxd files
authorStefan Behnel <stefan_ml@behnel.de>
Mon, 23 Jul 2012 08:30:45 +0000 (10:30 +0200)
committerStefan Behnel <stefan_ml@behnel.de>
Mon, 23 Jul 2012 08:30:45 +0000 (10:30 +0200)
Cython/Compiler/Code.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
tests/run/external_inline_declaration.srctree [new file with mode: 0644]

index 03a125c..174a867 100644 (file)
@@ -46,6 +46,10 @@ uncachable_builtins = [
     'WindowsError',
     ]
 
+modifier_output_mapper = {
+    'inline': 'CYTHON_INLINE'
+}.get
+
 def get_utility_dir():
     # make this a function and not global variables:
     # http://trac.cython.org/cython_trac/ticket/475
@@ -1566,6 +1570,11 @@ class CCodeWriter(object):
         else:
             return cond
 
+    def build_function_modifiers(self, modifiers, mapper=modifier_output_mapper):
+        if not modifiers:
+            return ''
+        return '%s ' % ' '.join([mapper(m,m) for m in modifiers])
+
     # Python objects and reference counting
 
     def entry_as_pyobject(self, entry):
index 6b0ce5b..802b867 100644 (file)
@@ -811,12 +811,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             if not method_entry.is_inherited and method_entry.final_func_cname:
                 declaration = method_entry.type.declaration_code(
                     method_entry.final_func_cname)
-                if method_entry.func_modifiers:
-                    modifiers = " %s " % ' '.join(method_entry.func_modifiers).upper()
-                    modifiers = modifiers.replace(" INLINE ", " CYTHON_INLINE ")
-                else:
-                    modifiers = " "
-                code.putln("static%s%s;" % (modifiers, declaration))
+                modifiers = code.build_function_modifiers(method_entry.func_modifiers)
+                code.putln("static %s%s;" % (modifiers, declaration))
 
     def generate_objstruct_predeclaration(self, type, code):
         if not type.scope:
@@ -2336,31 +2332,28 @@ def generate_cfunction_declaration(entry, env, code, definition):
     if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
             or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)):
         if entry.visibility == 'extern':
-            storage_class = "%s " % Naming.extern_c_macro
+            storage_class = Naming.extern_c_macro
             dll_linkage = "DL_IMPORT"
         elif entry.visibility == 'public':
-            storage_class = "%s " % Naming.extern_c_macro
+            storage_class = Naming.extern_c_macro
             dll_linkage = "DL_EXPORT"
         elif entry.visibility == 'private':
-            storage_class = "static "
+            storage_class = "static"
             dll_linkage = None
         else:
-            storage_class = "static "
+            storage_class = "static"
             dll_linkage = None
         type = entry.type
 
         if entry.defined_in_pxd and not definition:
-            storage_class = "static "
+            storage_class = "static"
             dll_linkage = None
             type = CPtrType(type)
 
-        header = type.declaration_code(entry.cname,
-                                       dll_linkage = dll_linkage)
-        if entry.func_modifiers:
-            modifiers = "%s " % ' '.join(entry.func_modifiers).upper()
-        else:
-            modifiers = ''
-        code.putln("%s%s%s; /*proto*/" % (
+        header = type.declaration_code(
+            entry.cname, dll_linkage = dll_linkage)
+        modifiers = code.build_function_modifiers(entry.func_modifiers)
+        code.putln("%s %s%s; /*proto*/" % (
             storage_class,
             modifiers,
             header))
index be4617e..75b3bfa 100644 (file)
@@ -2135,11 +2135,7 @@ class CFuncDefNode(FuncDefNode):
         else:
             storage_class = ""
         dll_linkage = None
-        modifiers = ""
-        if 'inline' in self.modifiers:
-            self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
-        if self.modifiers:
-            modifiers = "%s " % ' '.join(self.modifiers).upper()
+        modifiers = code.build_function_modifiers(self.entry.func_modifiers)
 
         header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage)
         #print (storage_class, modifiers, header)
diff --git a/tests/run/external_inline_declaration.srctree b/tests/run/external_inline_declaration.srctree
new file mode 100644 (file)
index 0000000..4050436
--- /dev/null
@@ -0,0 +1,24 @@
+PYTHON setup.py build_ext --inplace
+PYTHON -c "import a; assert a.test() == 1"
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+
+from distutils.core import setup
+
+setup(
+    ext_modules = cythonize("a.py"),
+)
+
+######## a.py ########
+
+def inlined_func(x):
+    return x
+
+def test():
+    return inlined_func(1)
+
+######## a.pxd ########
+
+cdef inline int inlined_func(int x)