From: Antoine Pitrou Date: Sat, 30 May 2009 21:41:10 +0000 (+0000) Subject: Merged revisions 73064 via svnmerge from X-Git-Tag: v3.1rc2~118 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e124f32442e46caab9e221d941510485b6e669a;p=python Merged revisions 73064 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73064 | antoine.pitrou | 2009-05-30 23:27:00 +0200 (sam., 30 mai 2009) | 4 lines Issue #5330: C functions called with keyword arguments were not reported by the various profiling modules (profile, cProfile). Patch by Hagen Fürstenau. ........ --- diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 349d342665..4586b36deb 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -9,6 +9,7 @@ from test.test_profile import ProfileTest, regenerate_expected_output class CProfileTest(ProfileTest): profilerclass = cProfile.Profile + expected_max_output = "{built-in method max}" def get_expected_output(self): return _ProfileOutput diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index c972fc6f62..243a322582 100755 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -16,6 +16,7 @@ class ProfileTest(unittest.TestCase): profilerclass = profile.Profile methodnames = ['print_stats', 'print_callers', 'print_callees'] + expected_max_output = ':0(max)' def get_expected_output(self): return _ProfileOutput @@ -53,6 +54,27 @@ class ProfileTest(unittest.TestCase): results[i+1].split('\n'), expected[method].split('\n')))) + def test_calling_conventions(self): + # Issue #5330: profile and cProfile wouldn't report C functions called + # with keyword arguments. We test all calling conventions. + stmts = [ + "max([0])", + "max([0], key=int)", + "max([0], **dict(key=int))", + "max(*([0],))", + "max(*([0],), key=int)", + "max(*([0],), **dict(key=int))", + ] + for stmt in stmts: + s = StringIO() + prof = self.profilerclass(timer, 0.001) + prof.runctx(stmt, globals(), locals()) + stats = pstats.Stats(prof, stream=s) + stats.print_stats() + res = s.getvalue() + self.assertTrue(self.expected_max_output in res, + "Profiling {0!r} didn't report max:\n{1}".format(stmt, res)) + def regenerate_expected_output(filename, cls): filename = filename.rstrip('co') diff --git a/Misc/NEWS b/Misc/NEWS index 6fa6d99a6f..b06767d071 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 3.1 Release Candidate 2? Core and Builtins ----------------- +- Issue #5330: C functions called with keyword arguments were not reported by + the various profiling modules (profile, cProfile). Patch by Hagen Fürstenau. + Library ------- diff --git a/Python/ceval.c b/Python/ceval.c index e693147c2a..b5b5c27272 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3951,10 +3951,17 @@ do_call(PyObject *func, PyObject ***pp_stack, int na, int nk) PCALL(PCALL_METHOD); else if (PyType_Check(func)) PCALL(PCALL_TYPE); + else if (PyCFunction_Check(func)) + PCALL(PCALL_CFUNCTION); else PCALL(PCALL_OTHER); #endif - result = PyObject_Call(func, callargs, kwdict); + if (PyCFunction_Check(func)) { + PyThreadState *tstate = PyThreadState_GET(); + C_TRACE(result, PyCFunction_Call(func, callargs, kwdict)); + } + else + result = PyObject_Call(func, callargs, kwdict); call_fail: Py_XDECREF(callargs); Py_XDECREF(kwdict); @@ -4039,10 +4046,17 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) PCALL(PCALL_METHOD); else if (PyType_Check(func)) PCALL(PCALL_TYPE); + else if (PyCFunction_Check(func)) + PCALL(PCALL_CFUNCTION); else PCALL(PCALL_OTHER); #endif - result = PyObject_Call(func, callargs, kwdict); + if (PyCFunction_Check(func)) { + PyThreadState *tstate = PyThreadState_GET(); + C_TRACE(result, PyCFunction_Call(func, callargs, kwdict)); + } + else + result = PyObject_Call(func, callargs, kwdict); ext_call_fail: Py_XDECREF(callargs); Py_XDECREF(kwdict);