Merge pull request #4586 from youknowone/trace

Update trace from CPython 3.11.2
This commit is contained in:
Jim Fasarakis-Hilliard
2023-02-28 12:30:33 +02:00
committed by GitHub
2 changed files with 30 additions and 30 deletions

View File

@@ -1,7 +1,8 @@
import os
from pickle import dump
import sys
from test.support import captured_stdout
from test.support.os_helper import TESTFN, TESTFN_UNICODE, FS_NONASCII, rmtree, unlink
from test.support.os_helper import (TESTFN, rmtree, unlink)
from test.support.script_helper import assert_python_ok, assert_python_failure
import textwrap
import unittest
@@ -11,6 +12,11 @@ from trace import Trace
from test.tracedmodules import testmod
##
## See also test_sys_settrace.py, which contains tests that cover
## tracing of many more code blocks.
##
#------------------------------- Utilities -----------------------------------#
def fix_ext_py(filename):
@@ -191,7 +197,7 @@ class TestLineCounts(unittest.TestCase):
firstlineno_called = get_firstlineno(traced_doubler)
expected = {
(self.my_py_filename, firstlineno_calling + 1): 1,
# List compehentions work differently in 3.x, so the count
# List comprehensions work differently in 3.x, so the count
# below changed compared to 2.x.
(self.my_py_filename, firstlineno_calling + 2): 12,
(self.my_py_filename, firstlineno_calling + 3): 1,
@@ -212,9 +218,9 @@ class TestLineCounts(unittest.TestCase):
(self.my_py_filename, firstlineno + 4): 1,
(self.my_py_filename, firstlineno + 5): 1,
(self.my_py_filename, firstlineno + 6): 1,
(self.my_py_filename, firstlineno + 7): 1,
(self.my_py_filename, firstlineno + 8): 1,
(self.my_py_filename, firstlineno + 9): 1,
(self.my_py_filename, firstlineno + 7): 2,
(self.my_py_filename, firstlineno + 8): 2,
(self.my_py_filename, firstlineno + 9): 2,
(self.my_py_filename, firstlineno + 10): 1,
(self.my_py_filename, firstlineno + 11): 1,
}
@@ -297,9 +303,8 @@ class TestFuncs(unittest.TestCase):
def test_arg_errors(self):
res = self.tracer.runfunc(traced_capturer, 1, 2, self=3, func=4)
self.assertEqual(res, ((1, 2), {'self': 3, 'func': 4}))
with self.assertWarns(DeprecationWarning):
res = self.tracer.runfunc(func=traced_capturer, arg=1)
self.assertEqual(res, ((), {'arg': 1}))
with self.assertRaises(TypeError):
self.tracer.runfunc(func=traced_capturer, arg=1)
with self.assertRaises(TypeError):
self.tracer.runfunc()
@@ -406,7 +411,7 @@ class TestCoverage(unittest.TestCase):
def test_coverage_ignore(self):
# Ignore all files, nothing should be traced nor printed
libpath = os.path.normpath(os.path.dirname(os.__file__))
libpath = os.path.normpath(os.path.dirname(os.path.dirname(__file__)))
# sys.prefix does not work when running from a checkout
tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,
libpath], trace=0, count=1)
@@ -439,6 +444,15 @@ class TestCoverage(unittest.TestCase):
self.assertIn(modname, coverage)
self.assertEqual(coverage[modname], (5, 100))
def test_coverageresults_update(self):
# Update empty CoverageResults with a non-empty infile.
infile = TESTFN + '-infile'
with open(infile, 'wb') as f:
dump(({}, {}, {'caller': 1}), f, protocol=1)
self.addCleanup(unlink, infile)
results = trace.CoverageResults({}, {}, infile, {})
self.assertEqual(results.callers, {'caller': 1})
### Tests that don't mess with sys.settrace and can be traced
### themselves TODO: Skip tests that do mess with sys.settrace when
### regrtest is invoked with -T option.
@@ -547,7 +561,8 @@ class TestCommandLine(unittest.TestCase):
fd.write("print(type(sys.argv))\n")
status, direct_stdout, stderr = assert_python_ok(TESTFN)
status, trace_stdout, stderr = assert_python_ok('-m', 'trace', '-l', TESTFN)
status, trace_stdout, stderr = assert_python_ok('-m', 'trace', '-l', TESTFN,
PYTHONIOENCODING='utf-8')
self.assertIn(direct_stdout.strip(), trace_stdout)
# TODO: RUSTPYTHON
@@ -569,7 +584,8 @@ class TestCommandLine(unittest.TestCase):
for i in range(10):
f()
"""))
status, stdout, _ = assert_python_ok('-m', 'trace', '-cs', filename)
status, stdout, _ = assert_python_ok('-m', 'trace', '-cs', filename,
PYTHONIOENCODING='utf-8')
stdout = stdout.decode()
self.assertEqual(status, 0)
self.assertIn('lines cov% module (path)', stdout)

22
Lib/trace.py vendored Normal file → Executable file
View File

@@ -116,7 +116,7 @@ class _Ignore:
return 0
def _modname(path):
"""Return a plausible module name for the patch."""
"""Return a plausible module name for the path."""
base = os.path.basename(path)
filename, ext = os.path.splitext(base)
@@ -172,7 +172,7 @@ class CoverageResults:
try:
with open(self.infile, 'rb') as f:
counts, calledfuncs, callers = pickle.load(f)
self.update(self.__class__(counts, calledfuncs, callers))
self.update(self.__class__(counts, calledfuncs, callers=callers))
except (OSError, EOFError, ValueError) as err:
print(("Skipping counts file %r: %s"
% (self.infile, err)), file=sys.stderr)
@@ -453,22 +453,7 @@ class Trace:
sys.settrace(None)
threading.settrace(None)
def runfunc(*args, **kw):
if len(args) >= 2:
self, func, *args = args
elif not args:
raise TypeError("descriptor 'runfunc' of 'Trace' object "
"needs an argument")
elif 'func' in kw:
func = kw.pop('func')
self, *args = args
import warnings
warnings.warn("Passing 'func' as keyword argument is deprecated",
DeprecationWarning, stacklevel=2)
else:
raise TypeError('runfunc expected at least 1 positional argument, '
'got %d' % (len(args)-1))
def runfunc(self, func, /, *args, **kw):
result = None
if not self.donothing:
sys.settrace(self.globaltrace)
@@ -478,7 +463,6 @@ class Trace:
if not self.donothing:
sys.settrace(None)
return result
runfunc.__text_signature__ = '($self, func, /, *args, **kw)'
def file_module_function_of(self, frame):
code = frame.f_code