summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Sottile <asottile@umich.edu>2020-10-18 21:16:22 (GMT)
committerGitHub <noreply@github.com>2020-10-18 21:16:22 (GMT)
commit7c949020ef2520d7a7cbc978f0b34423e6c2a94c (patch)
tree56d9e2f00a438eec67e38d9138ae4bc27f253987
parente5c7ac7a22629cc1d96cef256433f03088b2dd8a (diff)
downloadcpython-7c949020ef2520d7a7cbc978f0b34423e6c2a94c.zip
cpython-7c949020ef2520d7a7cbc978f0b34423e6c2a94c.tar.gz
cpython-7c949020ef2520d7a7cbc978f0b34423e6c2a94c.tar.bz2
bpo-40492: Fix --outfile with relative path when the program changes it working dir (GH-19910)
(cherry picked from commit 3c0ac18504cfeed822439024339d5717f42bdd66)
-rwxr-xr-xLib/cProfile.py5
-rwxr-xr-xLib/profile.py5
-rw-r--r--Lib/test/test_profile.py16
-rw-r--r--Misc/NEWS.d/next/Library/2020-05-04-12-16-00.bpo-40492.ONk9Na.rst3
4 files changed, 28 insertions, 1 deletions
diff --git a/Lib/cProfile.py b/Lib/cProfile.py
index 4f20203..59b4699 100755
--- a/Lib/cProfile.py
+++ b/Lib/cProfile.py
@@ -152,6 +152,11 @@ def main():
(options, args) = parser.parse_args()
sys.argv[:] = args
+ # The script that we're profiling may chdir, so capture the absolute path
+ # to the output file at startup.
+ if options.outfile is not None:
+ options.outfile = os.path.abspath(options.outfile)
+
if len(args) > 0:
if options.module:
code = "run_module(modname, run_name='__main__')"
diff --git a/Lib/profile.py b/Lib/profile.py
index aad458d..5cb017ed 100755
--- a/Lib/profile.py
+++ b/Lib/profile.py
@@ -571,6 +571,11 @@ def main():
(options, args) = parser.parse_args()
sys.argv[:] = args
+ # The script that we're profiling may chdir, so capture the absolute path
+ # to the output file at startup.
+ if options.outfile is not None:
+ options.outfile = os.path.abspath(options.outfile)
+
if len(args) > 0:
if options.module:
import runpy
diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py
index 01a8a6e..2336498 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -6,7 +6,7 @@ import unittest
import os
from difflib import unified_diff
from io import StringIO
-from test.support import TESTFN, run_unittest, unlink
+from test.support import TESTFN, run_unittest, unlink, temp_dir, change_cwd
from contextlib import contextmanager
import profile
@@ -111,6 +111,20 @@ class ProfileTest(unittest.TestCase):
assert_python_ok('-m', self.profilermodule.__name__,
'-m', 'timeit', '-n', '1')
+ def test_output_file_when_changing_directory(self):
+ with temp_dir() as tmpdir, change_cwd(tmpdir):
+ os.mkdir('dest')
+ with open('demo.py', 'w') as f:
+ f.write('import os; os.chdir("dest")')
+
+ assert_python_ok(
+ '-m', self.profilermodule.__name__,
+ '-o', 'out.pstats',
+ 'demo.py',
+ )
+
+ self.assertTrue(os.path.exists('out.pstats'))
+
def regenerate_expected_output(filename, cls):
filename = filename.rstrip('co')
diff --git a/Misc/NEWS.d/next/Library/2020-05-04-12-16-00.bpo-40492.ONk9Na.rst b/Misc/NEWS.d/next/Library/2020-05-04-12-16-00.bpo-40492.ONk9Na.rst
new file mode 100644
index 0000000..86bc08c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-05-04-12-16-00.bpo-40492.ONk9Na.rst
@@ -0,0 +1,3 @@
+Fix ``--outfile`` for :mod:`cProfile` / :mod:`profile` not writing the output
+file in the original directory when the program being profiled changes the
+working directory. PR by Anthony Sottile.