Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
9d17da33
Kaydet (Commit)
9d17da33
authored
Eyl 13, 2010
tarafından
Alexander Belopolsky
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #9315: Fix for the trace module to record correct class name
when tracing methods. Unit tests. Patch by Eli Bendersky.
üst
c0c0b146
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
336 additions
and
8 deletions
+336
-8
test_trace.py
Lib/test/test_trace.py
+320
-0
__init__.py
Lib/test/tracedmodules/__init__.py
+4
-0
testmod.py
Lib/test/tracedmodules/testmod.py
+3
-0
trace.py
Lib/trace.py
+4
-8
NEWS
Misc/NEWS
+5
-0
No files found.
Lib/test/test_trace.py
0 → 100644
Dosyayı görüntüle @
9d17da33
import
os
import
sys
from
test.test_support
import
(
run_unittest
,
TESTFN
,
rmtree
,
unlink
,
captured_stdout
)
import
unittest
import
trace
from
trace
import
CoverageResults
,
Trace
from
test.tracedmodules
import
testmod
#------------------------------- Utilities -----------------------------------#
def
fix_ext_py
(
filename
):
"""Given a .pyc/.pyo filename converts it to the appropriate .py"""
if
filename
.
endswith
((
'.pyc'
,
'.pyo'
)):
filename
=
filename
[:
-
1
]
return
filename
def
my_file_and_modname
():
"""The .py file and module name of this file (__file__)"""
modname
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
__file__
))[
0
]
return
fix_ext_py
(
__file__
),
modname
def
get_firstlineno
(
func
):
return
func
.
__code__
.
co_firstlineno
#-------------------- Target functions for tracing ---------------------------#
#
# The relative line numbers of lines in these functions matter for verifying
# tracing. Please modify the appropriate tests if you change one of the
# functions. Absolute line numbers don't matter.
#
def
traced_func_linear
(
x
,
y
):
a
=
x
b
=
y
c
=
a
+
b
return
c
def
traced_func_loop
(
x
,
y
):
c
=
x
for
i
in
range
(
5
):
c
+=
y
return
c
def
traced_func_importing
(
x
,
y
):
return
x
+
y
+
testmod
.
func
(
1
)
def
traced_func_simple_caller
(
x
):
c
=
traced_func_linear
(
x
,
x
)
return
c
+
x
def
traced_func_importing_caller
(
x
):
k
=
traced_func_simple_caller
(
x
)
k
+=
traced_func_importing
(
k
,
x
)
return
k
def
traced_func_generator
(
num
):
c
=
5
# executed once
for
i
in
range
(
num
):
yield
i
+
c
def
traced_func_calling_generator
():
k
=
0
for
i
in
traced_func_generator
(
10
):
k
+=
i
def
traced_doubler
(
num
):
return
num
*
2
def
traced_caller_list_comprehension
():
k
=
10
mylist
=
[
traced_doubler
(
i
)
for
i
in
range
(
k
)]
return
mylist
class
TracedClass
(
object
):
def
__init__
(
self
,
x
):
self
.
a
=
x
def
inst_method_linear
(
self
,
y
):
return
self
.
a
+
y
def
inst_method_calling
(
self
,
x
):
c
=
self
.
inst_method_linear
(
x
)
return
c
+
traced_func_linear
(
x
,
c
)
@classmethod
def
class_method_linear
(
cls
,
y
):
return
y
*
2
@staticmethod
def
static_method_linear
(
y
):
return
y
*
2
#------------------------------ Test cases -----------------------------------#
class
TestLineCounts
(
unittest
.
TestCase
):
"""White-box testing of line-counting, via runfunc"""
def
setUp
(
self
):
self
.
tracer
=
Trace
(
count
=
1
,
trace
=
0
,
countfuncs
=
0
,
countcallers
=
0
)
self
.
my_py_filename
=
fix_ext_py
(
__file__
)
def
test_traced_func_linear
(
self
):
result
=
self
.
tracer
.
runfunc
(
traced_func_linear
,
2
,
5
)
self
.
assertEqual
(
result
,
7
)
# all lines are executed once
expected
=
{}
firstlineno
=
get_firstlineno
(
traced_func_linear
)
for
i
in
range
(
1
,
5
):
expected
[(
self
.
my_py_filename
,
firstlineno
+
i
)]
=
1
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
,
expected
)
def
test_traced_func_loop
(
self
):
self
.
tracer
.
runfunc
(
traced_func_loop
,
2
,
3
)
firstlineno
=
get_firstlineno
(
traced_func_loop
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno
+
1
):
1
,
(
self
.
my_py_filename
,
firstlineno
+
2
):
6
,
(
self
.
my_py_filename
,
firstlineno
+
3
):
5
,
(
self
.
my_py_filename
,
firstlineno
+
4
):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
,
expected
)
def
test_traced_func_importing
(
self
):
self
.
tracer
.
runfunc
(
traced_func_importing
,
2
,
5
)
firstlineno
=
get_firstlineno
(
traced_func_importing
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno
+
1
):
1
,
(
fix_ext_py
(
testmod
.
__file__
),
2
):
1
,
(
fix_ext_py
(
testmod
.
__file__
),
3
):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
,
expected
)
def
test_trace_func_generator
(
self
):
self
.
tracer
.
runfunc
(
traced_func_calling_generator
)
firstlineno_calling
=
get_firstlineno
(
traced_func_calling_generator
)
firstlineno_gen
=
get_firstlineno
(
traced_func_generator
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno_calling
+
1
):
1
,
(
self
.
my_py_filename
,
firstlineno_calling
+
2
):
11
,
(
self
.
my_py_filename
,
firstlineno_calling
+
3
):
10
,
(
self
.
my_py_filename
,
firstlineno_gen
+
1
):
1
,
(
self
.
my_py_filename
,
firstlineno_gen
+
2
):
11
,
(
self
.
my_py_filename
,
firstlineno_gen
+
3
):
10
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
,
expected
)
def
test_trace_list_comprehension
(
self
):
self
.
tracer
.
runfunc
(
traced_caller_list_comprehension
)
firstlineno_calling
=
get_firstlineno
(
traced_caller_list_comprehension
)
firstlineno_called
=
get_firstlineno
(
traced_doubler
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno_calling
+
1
):
1
,
(
self
.
my_py_filename
,
firstlineno_calling
+
2
):
11
,
(
self
.
my_py_filename
,
firstlineno_calling
+
3
):
1
,
(
self
.
my_py_filename
,
firstlineno_called
+
1
):
10
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
,
expected
)
def
test_linear_methods
(
self
):
# XXX todo: later add 'static_method_linear' and 'class_method_linear'
# here, once issue1764286 is resolved
#
for
methname
in
[
'inst_method_linear'
,]:
tracer
=
Trace
(
count
=
1
,
trace
=
0
,
countfuncs
=
0
,
countcallers
=
0
)
traced_obj
=
TracedClass
(
25
)
method
=
getattr
(
traced_obj
,
methname
)
tracer
.
runfunc
(
method
,
20
)
firstlineno
=
get_firstlineno
(
method
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno
+
1
):
1
,
}
self
.
assertEqual
(
tracer
.
results
()
.
counts
,
expected
)
class
TestRunExecCounts
(
unittest
.
TestCase
):
"""A simple sanity test of line-counting, via runctx (exec)"""
def
setUp
(
self
):
self
.
my_py_filename
=
fix_ext_py
(
__file__
)
def
test_exec_counts
(
self
):
self
.
tracer
=
Trace
(
count
=
1
,
trace
=
0
,
countfuncs
=
0
,
countcallers
=
0
)
code
=
r'''traced_func_loop(2, 5)'''
code
=
compile
(
code
,
__file__
,
'exec'
)
self
.
tracer
.
runctx
(
code
,
globals
(),
vars
())
firstlineno
=
get_firstlineno
(
traced_func_loop
)
expected
=
{
(
self
.
my_py_filename
,
firstlineno
+
1
):
1
,
(
self
.
my_py_filename
,
firstlineno
+
2
):
6
,
(
self
.
my_py_filename
,
firstlineno
+
3
):
5
,
(
self
.
my_py_filename
,
firstlineno
+
4
):
1
,
}
# When used through 'run', some other spurios counts are produced, like
# the settrace of threading, which we ignore, just making sure that the
# counts fo traced_func_loop were right.
#
for
k
in
expected
.
keys
():
self
.
assertEqual
(
self
.
tracer
.
results
()
.
counts
[
k
],
expected
[
k
])
class
TestFuncs
(
unittest
.
TestCase
):
"""White-box testing of funcs tracing"""
def
setUp
(
self
):
self
.
tracer
=
Trace
(
count
=
0
,
trace
=
0
,
countfuncs
=
1
)
self
.
filemod
=
my_file_and_modname
()
self
.
maxDiff
=
None
def
test_simple_caller
(
self
):
self
.
tracer
.
runfunc
(
traced_func_simple_caller
,
1
)
expected
=
{
self
.
filemod
+
(
'traced_func_simple_caller'
,):
1
,
self
.
filemod
+
(
'traced_func_linear'
,):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
calledfuncs
,
expected
)
def
test_loop_caller_importing
(
self
):
self
.
tracer
.
runfunc
(
traced_func_importing_caller
,
1
)
expected
=
{
self
.
filemod
+
(
'traced_func_simple_caller'
,):
1
,
self
.
filemod
+
(
'traced_func_linear'
,):
1
,
self
.
filemod
+
(
'traced_func_importing_caller'
,):
1
,
self
.
filemod
+
(
'traced_func_importing'
,):
1
,
(
fix_ext_py
(
testmod
.
__file__
),
'testmod'
,
'func'
):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
calledfuncs
,
expected
)
def
test_inst_method_calling
(
self
):
obj
=
TracedClass
(
20
)
self
.
tracer
.
runfunc
(
obj
.
inst_method_calling
,
1
)
expected
=
{
self
.
filemod
+
(
'TracedClass.inst_method_calling'
,):
1
,
self
.
filemod
+
(
'TracedClass.inst_method_linear'
,):
1
,
self
.
filemod
+
(
'traced_func_linear'
,):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
calledfuncs
,
expected
)
class
TestCallers
(
unittest
.
TestCase
):
"""White-box testing of callers tracing"""
def
setUp
(
self
):
self
.
tracer
=
Trace
(
count
=
0
,
trace
=
0
,
countcallers
=
1
)
self
.
filemod
=
my_file_and_modname
()
def
test_loop_caller_importing
(
self
):
self
.
tracer
.
runfunc
(
traced_func_importing_caller
,
1
)
expected
=
{
((
os
.
path
.
splitext
(
trace
.
__file__
)[
0
]
+
'.py'
,
'trace'
,
'Trace.runfunc'
),
(
self
.
filemod
+
(
'traced_func_importing_caller'
,))):
1
,
((
self
.
filemod
+
(
'traced_func_simple_caller'
,)),
(
self
.
filemod
+
(
'traced_func_linear'
,))):
1
,
((
self
.
filemod
+
(
'traced_func_importing_caller'
,)),
(
self
.
filemod
+
(
'traced_func_simple_caller'
,))):
1
,
((
self
.
filemod
+
(
'traced_func_importing_caller'
,)),
(
self
.
filemod
+
(
'traced_func_importing'
,))):
1
,
((
self
.
filemod
+
(
'traced_func_importing'
,)),
(
fix_ext_py
(
testmod
.
__file__
),
'testmod'
,
'func'
)):
1
,
}
self
.
assertEqual
(
self
.
tracer
.
results
()
.
callers
,
expected
)
# Created separately for issue #3821
class
TestCoverage
(
unittest
.
TestCase
):
def
tearDown
(
self
):
rmtree
(
TESTFN
)
unlink
(
TESTFN
)
def
_coverage
(
self
,
tracer
):
tracer
.
run
(
'from test import test_pprint; test_pprint.test_main()'
)
r
=
tracer
.
results
()
r
.
write_results
(
show_missing
=
True
,
summary
=
True
,
coverdir
=
TESTFN
)
def
test_coverage
(
self
):
tracer
=
trace
.
Trace
(
trace
=
0
,
count
=
1
)
with
captured_stdout
()
as
stdout
:
self
.
_coverage
(
tracer
)
stdout
=
stdout
.
getvalue
()
self
.
assertTrue
(
"pprint.py"
in
stdout
)
self
.
assertTrue
(
"case.py"
in
stdout
)
# from unittest
files
=
os
.
listdir
(
TESTFN
)
self
.
assertTrue
(
"pprint.cover"
in
files
)
self
.
assertTrue
(
"unittest.case.cover"
in
files
)
def
test_coverage_ignore
(
self
):
# Ignore all files, nothing should be traced nor printed
libpath
=
os
.
path
.
normpath
(
os
.
path
.
dirname
(
os
.
__file__
))
# sys.prefix does not work when running from a checkout
tracer
=
trace
.
Trace
(
ignoredirs
=
[
sys
.
prefix
,
sys
.
exec_prefix
,
libpath
],
trace
=
0
,
count
=
1
)
with
captured_stdout
()
as
stdout
:
self
.
_coverage
(
tracer
)
if
os
.
path
.
exists
(
TESTFN
):
files
=
os
.
listdir
(
TESTFN
)
self
.
assertEquals
(
files
,
[])
def
test_main
():
run_unittest
(
__name__
)
if
__name__
==
'__main__'
:
test_main
()
Lib/test/tracedmodules/__init__.py
0 → 100644
Dosyayı görüntüle @
9d17da33
"""This package contains modules that help testing the trace.py module. Note
that the exact location of functions in these modules is important, as trace.py
takes the real line numbers into account.
"""
Lib/test/tracedmodules/testmod.py
0 → 100644
Dosyayı görüntüle @
9d17da33
def
func
(
x
):
b
=
x
+
1
return
b
+
2
Lib/trace.py
Dosyayı görüntüle @
9d17da33
...
...
@@ -56,7 +56,7 @@ import threading
import
time
import
token
import
tokenize
import
types
import
inspect
import
gc
try
:
...
...
@@ -398,7 +398,7 @@ def find_lines(code, strs):
# and check the constants for references to other code objects
for
c
in
code
.
co_consts
:
if
i
sinstance
(
c
,
types
.
CodeType
):
if
i
nspect
.
iscode
(
c
):
# find another code object, so recurse into it
linenos
.
update
(
find_lines
(
c
,
strs
))
return
linenos
...
...
@@ -545,7 +545,7 @@ class Trace:
## use of gc.get_referrers() was suggested by Michael Hudson
# all functions which refer to this code object
funcs
=
[
f
for
f
in
gc
.
get_referrers
(
code
)
if
hasattr
(
f
,
"func_doc"
)]
if
inspect
.
isfunction
(
f
)]
# require len(func) == 1 to avoid ambiguity caused by calls to
# new.function(): "In the face of ambiguity, refuse the
# temptation to guess."
...
...
@@ -557,17 +557,13 @@ class Trace:
if
hasattr
(
c
,
"__bases__"
)]
if
len
(
classes
)
==
1
:
# ditto for new.classobj()
clsname
=
str
(
classes
[
0
])
clsname
=
classes
[
0
]
.
__name__
# cache the result - assumption is that new.* is
# not called later to disturb this relationship
# _caller_cache could be flushed if functions in
# the new module get called.
self
.
_caller_cache
[
code
]
=
clsname
if
clsname
is
not
None
:
# final hack - module name shows up in str(cls), but we've already
# computed module name, so remove it
clsname
=
clsname
.
split
(
"."
)[
1
:]
clsname
=
"."
.
join
(
clsname
)
funcname
=
"
%
s.
%
s"
%
(
clsname
,
funcname
)
return
filename
,
modulename
,
funcname
...
...
Misc/NEWS
Dosyayı görüntüle @
9d17da33
...
...
@@ -255,6 +255,9 @@ Library
- Issue #9164: Ensure sysconfig handles dupblice archs while building on OSX
- Issue #9315: Fix for the trace module to record correct class name
for tracing methods.
Extension Modules
-----------------
...
...
@@ -337,6 +340,8 @@ Build
Tests
-----
- Issue #9315: Added tests for the trace module. Patch by Eli Bendersky.
- Strengthen test_unicode with explicit type checking for assertEqual tests.
- Issue #8857: Provide a test case for socket.getaddrinfo.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment