forked from Rust-related/RustPython
Merge pull request #4586 from youknowone/trace
Update trace from CPython 3.11.2
This commit is contained in:
38
Lib/test/test_trace.py
vendored
38
Lib/test/test_trace.py
vendored
@@ -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
22
Lib/trace.py
vendored
Normal file → Executable 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
|
||||
|
||||
Reference in New Issue
Block a user