Commits

Anonymous committed 8c289fa

Handle FunctionAction signatures when the function is an object method.

Comments (0)

Files changed (3)

   - Change the order of the arguments to Configure.Checklib() to match
     the documentation.
 
+  - Handle signature calculation properly when the Python function used
+    for a FunctionAction is an object method.
+
   From Chen Lee:
 
   - Handle Visual Studio project and solution files in Unicode.

src/engine/SCons/Action.py

         So we remove the line number byte codes to prevent
         recompilations from moving a Python function.
         """
+        execfunction = self.execfunction
         try:
-            # "self.execfunction" is a function.
-            contents = str(self.execfunction.func_code.co_code)
+            # Test if execfunction is a function.
+            code = execfunction.func_code.co_code
         except AttributeError:
-            # "self.execfunction" is a callable object.
             try:
-                contents = str(self.execfunction.__call__.im_func.func_code.co_code)
+                # Test if execfunction is a method.
+                code = execfunction.im_func.func_code.co_code
             except AttributeError:
                 try:
-                    # See if execfunction will do the heavy lifting for us.
-                    gc = self.execfunction.get_contents
+                    # Test if execfunction is a callable object.
+                    code = execfunction.__call__.im_func.func_code.co_code
                 except AttributeError:
-                    # This is weird, just do the best we can.
-                    contents = str(self.execfunction)
+                    try:
+                        # See if execfunction will do the heavy lifting for us.
+                        gc = self.execfunction.get_contents
+                    except AttributeError:
+                        # This is weird, just do the best we can.
+                        contents = str(self.execfunction)
+                    else:
+                        contents = gc(target, source, env)
                 else:
-                    contents = gc(target, source, env)
+                    contents = str(code)
+            else:
+                contents = str(code)
+        else:
+            contents = str(code)
         contents = remove_set_lineno_codes(contents)
         return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
                                                      self.varlist)))

src/engine/SCons/ActionTests.py

         c = a.get_contents(target=[], source=[], env=Environment())
         assert c == 'xyzzy', repr(c)
 
+        class LocalClass:
+            def LocalMethod(self):
+                pass
+        lc = LocalClass()
+        a = SCons.Action.FunctionAction(lc.LocalMethod)
+        c = a.get_contents(target=[], source=[], env=Environment())
+        assert c in matches, repr(c)
+
 class ListActionTestCase(unittest.TestCase):
 
     def test___init__(self):