Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
fcf5d639
Commit
fcf5d639
authored
Oct 16, 2008
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
forward port r66386
parent
d31fdc54
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
156 additions
and
59 deletions
+156
-59
Doc/library/test.rst
Doc/library/test.rst
+24
-16
Doc/library/warnings.rst
Doc/library/warnings.rst
+21
-13
Lib/test/support.py
Lib/test/support.py
+21
-11
Lib/test/test_import.py
Lib/test/test_import.py
+8
-5
Lib/test/test_structmembers.py
Lib/test/test_structmembers.py
+7
-7
Lib/test/test_sundry.py
Lib/test/test_sundry.py
+1
-1
Lib/test/test_threading.py
Lib/test/test_threading.py
+1
-1
Lib/test/test_warnings.py
Lib/test/test_warnings.py
+58
-5
Lib/warnings.py
Lib/warnings.py
+15
-0
No files found.
Doc/library/test.rst
View file @
fcf5d639
...
...
@@ -278,18 +278,26 @@ The :mod:`test.support` module defines the following functions:
This will run all tests defined in the named module.
.. function:: c
atch_warning(module=warnings, record=True
)
.. function:: c
heck_warnings(
)
Return a context manager that guards the warnings filter from being
permanently changed and optionally alters the :func:`showwarning`
function to record the details of any warnings that are issued in the
managed context. Attributes of the most recent warning are saved
directly on the context manager, while details of previous warnings
can be retrieved from the ``warnings`` list.
A convenience wrapper for ``warnings.catch_warnings()`` that makes
it easier to test that a warning was correctly raised with a single
assertion. It is approximately equivalent to calling
``warnings.catch_warnings(record=True)``.
The main difference is that on entry to the context manager, a
:class:`WarningRecorder` instance is returned instead of a simple list.
The underlying warnings list is available via the recorder object'
s
:
attr
:`
warnings
`
attribute
,
while
the
attributes
of
the
last
raised
warning
are
also
accessible
directly
on
the
object
.
If
no
warning
has
been
raised
,
then
the
latter
attributes
will
all
be
:
const
:`
None
`.
A
:
meth
:`
reset
`
method
is
also
provided
on
the
recorder
object
.
This
method
simply
clears
the
warning
list
.
The
context
manager
is
used
like
this
::
with c
atch_warning
() as w:
with
c
heck_warnings
()
as
w
:
warnings
.
simplefilter
(
"always"
)
warnings
.
warn
(
"foo"
)
assert
str
(
w
.
message
)
==
"foo"
...
...
@@ -297,15 +305,9 @@ The :mod:`test.support` module defines the following functions:
assert
str
(
w
.
message
)
==
"bar"
assert
str
(
w
.
warnings
[
0
].
message
)
==
"foo"
assert
str
(
w
.
warnings
[
1
].
message
)
==
"bar"
w
.
reset
()
assert
len
(
w
.
warnings
)
==
0
By default, the real :mod:`warnings` module is affected - the ability
to select a different module is provided for the benefit of the
:mod:`warnings` module'
s
own
unit
tests
.
The
``
record
``
argument
specifies
whether
or
not
the
:
func
:`
showwarning
`
function
is
replaced
.
Note
that
recording
the
warnings
in
this
fashion
also
prevents
them
from
being
written
to
sys
.
stderr
.
If
set
to
``
False
``,
the
standard
handling
of
warning
messages
is
left
in
place
(
however
,
the
original
handling
is
still
restored
at
the
end
of
the
block
).
..
function
::
captured_stdout
()
...
...
@@ -346,4 +348,10 @@ The :mod:`test.support` module defines the following classes:
Temporarily
unset
the
environment
variable
``
envvar
``.
..
class
::
WarningsRecorder
()
Class
used
to
record
warnings
for
unit
tests
.
See
documentation
of
:
func
:`
check_warnings
`
above
for
more
details
.
..
versionadded
::
2.6
Doc/library/warnings.rst
View file @
fcf5d639
...
...
@@ -165,9 +165,9 @@ ImportWarning can also be enabled explicitly in Python code using::
Temporarily Suppressing Warnings
--------------------------------
If you are using code that you know will raise a warning, such
some
deprecated
function, but do not want to see the warning, then
suppress the warning using
the :class:`catch_warnings` context manager::
If you are using code that you know will raise a warning, such
as a
deprecated
function, but do not want to see the warning, then
it is possible to suppress
the
warning using the
:class:`catch_warnings` context manager::
import warnings
...
...
@@ -218,7 +218,15 @@ the warning has been cleared.
Once the context manager exits, the warnings filter is restored to its state
when the context was entered. This prevents tests from changing the warnings
filter in unexpected ways between tests and leading to indeterminate test
results.
results. The :func:`showwarning` function in the module is also restored to
its original value.
When testing multiple operations that raise the same kind of warning, it
is important to test them in a manner that confirms each operation is raising
a new warning (e.g. set warnings to be raised as exceptions and check the
operations raise exceptions, check that the length of the warning list
continues to increase after each operation, or else delete the previous
entries from the warnings list before each new operation).
.. _warning-functions:
...
...
@@ -314,20 +322,20 @@ Available Context Managers
.. class:: catch_warnings([\*, record=False, module=None])
A context manager that copies and, upon exit, restores the warnings filter.
If the *record* argument is False (the default) the context manager returns
:class:`None`. If *record* is true, a list is returned that is populated
with objects as seen by a custom :func:`showwarning` function (which also
suppresses output to ``sys.stdout``). Each object has attributes with the
same names as the arguments to :func:`showwarning`.
A context manager that copies and, upon exit, restores the warnings filter
and the :func:`showwarning` function.
If the *record* argument is :const:`False` (the default) the context manager
returns :class:`None` on entry. If *record* is :const:`True`, a list is
returned that is progressively populated with objects as seen by a custom
:func:`showwarning` function (which also suppresses output to ``sys.stdout``).
Each object in the list has attributes with the same names as the arguments to
:func:`showwarning`.
The *module* argument takes a module that will be used instead of the
module returned when you import :mod:`warnings` whose filter will be
protected. This argument
s
exists primarily for testing the :mod:`warnings`
protected. This argument exists primarily for testing the :mod:`warnings`
module itself.
.. versionadded:: 2.6
.. versionchanged:: 3.0
Constructor arguments turned into keyword-only arguments.
...
...
Lib/test/support.py
View file @
fcf5d639
...
...
@@ -19,7 +19,7 @@ __all__ = ["Error", "TestFailed", "TestSkipped", "ResourceDenied", "import_modul
"is_resource_enabled"
,
"requires"
,
"find_unused_port"
,
"bind_port"
,
"fcmp"
,
"is_jython"
,
"TESTFN"
,
"HOST"
,
"FUZZ"
,
"findfile"
,
"verify"
,
"vereq"
,
"sortdict"
,
"check_syntax_error"
,
"open_urlresource"
,
"c
atch_warning
"
,
"CleanImport"
,
"EnvironmentVarGuard"
,
"c
heck_warnings
"
,
"CleanImport"
,
"EnvironmentVarGuard"
,
"TransientResource"
,
"captured_output"
,
"captured_stdout"
,
"TransientResource"
,
"transient_internet"
,
"run_with_locale"
,
"set_memlimit"
,
"bigmemtest"
,
"bigaddrspacetest"
,
"BasicTestRunner"
,
...
...
@@ -53,7 +53,7 @@ class ResourceDenied(TestSkipped):
def
import_module
(
name
,
deprecated
=
False
):
"""Import the module to be tested, raising TestSkipped if it is not
available."""
with
catch_warning
(
record
=
False
):
with
warnings
.
catch_warnings
(
):
if
deprecated
:
warnings
.
filterwarnings
(
"ignore"
,
".+ (module|package)"
,
DeprecationWarning
)
...
...
@@ -368,17 +368,27 @@ def open_urlresource(url, *args, **kw):
return
open
(
fn
,
*
args
,
**
kw
)
def
catch_warning
(
module
=
warnings
,
record
=
True
):
"""Guard the warnings filter from being permanently changed and
optionally record the details of any warnings that are issued.
class
WarningsRecorder
(
object
):
"""Convenience wrapper for the warnings list returned on
entry to the warnings.catch_warnings() context manager.
"""
def
__init__
(
self
,
warnings_list
):
self
.
warnings
=
warnings_list
Use like this:
def
__getattr__
(
self
,
attr
):
if
self
.
warnings
:
return
getattr
(
self
.
warnings
[
-
1
],
attr
)
elif
attr
in
warnings
.
WarningMessage
.
_WARNING_DETAILS
:
return
None
raise
AttributeError
(
"%r has no attribute %r"
%
(
self
,
attr
))
with catch_warning() as w:
warnings.warn("foo")
assert str(w.message) == "foo"
"""
return
warnings
.
catch_warnings
(
record
=
record
,
module
=
module
)
def
reset
(
self
):
del
self
.
warnings
[:]
@
contextlib
.
contextmanager
def
check_warnings
():
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
yield
WarningsRecorder
(
w
)
class
CleanImport
(
object
):
...
...
Lib/test/test_import.py
View file @
fcf5d639
...
...
@@ -266,21 +266,24 @@ class RelativeImport(unittest.TestCase):
self
.
assertTrue
(
hasattr
(
relimport
,
"RelativeImport"
))
def
test_issue3221
(
self
):
# Note for mergers: the 'absolute' tests from the 2.x branch
# are missing in Py3k because implicit relative imports are
# a thing of the past
def
check_relative
():
exec
(
"from . import relimport"
,
ns
)
# Check
both
OK with __package__ and __name__ correct
# Check
relative import
OK with __package__ and __name__ correct
ns
=
dict
(
__package__
=
'test'
,
__name__
=
'test.notarealmodule'
)
check_relative
()
# Check
both
OK with only __name__ wrong
# Check
relative import
OK with only __name__ wrong
ns
=
dict
(
__package__
=
'test'
,
__name__
=
'notarealpkg.notarealmodule'
)
check_relative
()
# Check relative fails with only __package__ wrong
# Check relative
import
fails with only __package__ wrong
ns
=
dict
(
__package__
=
'foo'
,
__name__
=
'test.notarealmodule'
)
self
.
assertRaises
(
SystemError
,
check_relative
)
# Check relative fails with __package__ and __name__ wrong
# Check relative
import
fails with __package__ and __name__ wrong
ns
=
dict
(
__package__
=
'foo'
,
__name__
=
'notarealpkg.notarealmodule'
)
self
.
assertRaises
(
SystemError
,
check_relative
)
# Check
both fail
with package set to a non-string
# Check
relative import fails
with package set to a non-string
ns
=
dict
(
__package__
=
object
())
self
.
assertRaises
(
ValueError
,
check_relative
)
...
...
Lib/test/test_structmembers.py
View file @
fcf5d639
...
...
@@ -66,35 +66,35 @@ class ReadWriteTests(unittest.TestCase):
class
TestWarnings
(
unittest
.
TestCase
):
def
has_warned
(
self
,
w
):
self
.
assertEqual
(
w
[
-
1
]
.
category
,
RuntimeWarning
)
self
.
assertEqual
(
w
.
category
,
RuntimeWarning
)
def
test_byte_max
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_BYTE
=
CHAR_MAX
+
1
self
.
has_warned
(
w
)
def
test_byte_min
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_BYTE
=
CHAR_MIN
-
1
self
.
has_warned
(
w
)
def
test_ubyte_max
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_UBYTE
=
UCHAR_MAX
+
1
self
.
has_warned
(
w
)
def
test_short_max
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_SHORT
=
SHRT_MAX
+
1
self
.
has_warned
(
w
)
def
test_short_min
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_SHORT
=
SHRT_MIN
-
1
self
.
has_warned
(
w
)
def
test_ushort_max
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
with
support
.
check_warnings
(
)
as
w
:
ts
.
T_USHORT
=
USHRT_MAX
+
1
self
.
has_warned
(
w
)
...
...
Lib/test/test_sundry.py
View file @
fcf5d639
...
...
@@ -7,7 +7,7 @@ import warnings
class
TestUntestedModules
(
unittest
.
TestCase
):
def
test_at_least_import_untested_modules
(
self
):
with
warnings
.
catch_warnings
(
record
=
True
):
with
warnings
.
catch_warnings
():
import
aifc
import
bdb
import
cgitb
...
...
Lib/test/test_threading.py
View file @
fcf5d639
# Very rudimentary test of threading module
import
test.support
from
test.support
import
verbose
,
catch_warning
from
test.support
import
verbose
import
random
import
re
import
sys
...
...
Lib/test/test_warnings.py
View file @
fcf5d639
...
...
@@ -214,7 +214,8 @@ class WarnTests(unittest.TestCase):
def
test_warn_nonstandard_types
(
self
):
# warn() should handle non-standard types without issue.
for
ob
in
(
Warning
,
None
,
42
):
with
support
.
catch_warning
(
self
.
module
)
as
w
:
with
original_warnings
.
catch_warnings
(
record
=
True
,
module
=
self
.
module
)
as
w
:
self
.
module
.
warn
(
ob
)
# Don't directly compare objects since
# ``Warning() != Warning()``.
...
...
@@ -526,19 +527,23 @@ class CatchWarningTests(BaseTest):
wmod
=
self
.
module
orig_filters
=
wmod
.
filters
orig_showwarning
=
wmod
.
showwarning
with
support
.
catch_warning
(
module
=
wmod
):
# Ensure both showwarning and filters are restored when recording
with
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
True
):
wmod
.
filters
=
wmod
.
showwarning
=
object
()
self
.
assert_
(
wmod
.
filters
is
orig_filters
)
self
.
assert_
(
wmod
.
showwarning
is
orig_showwarning
)
with
support
.
catch_warning
(
module
=
wmod
,
record
=
False
):
# Same test, but with recording disabled
with
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
False
):
wmod
.
filters
=
wmod
.
showwarning
=
object
()
self
.
assert_
(
wmod
.
filters
is
orig_filters
)
self
.
assert_
(
wmod
.
showwarning
is
orig_showwarning
)
def
test_catch_warnings_recording
(
self
):
wmod
=
self
.
module
with
support
.
catch_warning
(
module
=
wmod
)
as
w
:
# Ensure warnings are recorded when requested
with
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
True
)
as
w
:
self
.
assertEqual
(
w
,
[])
self
.
assert_
(
type
(
w
)
is
list
)
wmod
.
simplefilter
(
"always"
)
wmod
.
warn
(
"foo"
)
self
.
assertEqual
(
str
(
w
[
-
1
].
message
),
"foo"
)
...
...
@@ -548,11 +553,59 @@ class CatchWarningTests(BaseTest):
self
.
assertEqual
(
str
(
w
[
1
].
message
),
"bar"
)
del
w
[:]
self
.
assertEqual
(
w
,
[])
# Ensure warnings are not recorded when not requested
orig_showwarning
=
wmod
.
showwarning
with
support
.
catch_warning
(
module
=
wmod
,
record
=
False
)
as
w
:
with
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
False
)
as
w
:
self
.
assert_
(
w
is
None
)
self
.
assert_
(
wmod
.
showwarning
is
orig_showwarning
)
def
test_catch_warnings_reentry_guard
(
self
):
wmod
=
self
.
module
# Ensure catch_warnings is protected against incorrect usage
x
=
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
True
)
self
.
assertRaises
(
RuntimeError
,
x
.
__exit__
)
with
x
:
self
.
assertRaises
(
RuntimeError
,
x
.
__enter__
)
# Same test, but with recording disabled
x
=
wmod
.
catch_warnings
(
module
=
wmod
,
record
=
False
)
self
.
assertRaises
(
RuntimeError
,
x
.
__exit__
)
with
x
:
self
.
assertRaises
(
RuntimeError
,
x
.
__enter__
)
def
test_catch_warnings_defaults
(
self
):
wmod
=
self
.
module
orig_filters
=
wmod
.
filters
orig_showwarning
=
wmod
.
showwarning
# Ensure default behaviour is not to record warnings
with
wmod
.
catch_warnings
(
module
=
wmod
)
as
w
:
self
.
assert_
(
w
is
None
)
self
.
assert_
(
wmod
.
showwarning
is
orig_showwarning
)
self
.
assert_
(
wmod
.
filters
is
not
orig_filters
)
self
.
assert_
(
wmod
.
filters
is
orig_filters
)
if
wmod
is
sys
.
modules
[
'warnings'
]:
# Ensure the default module is this one
with
wmod
.
catch_warnings
()
as
w
:
self
.
assert_
(
w
is
None
)
self
.
assert_
(
wmod
.
showwarning
is
orig_showwarning
)
self
.
assert_
(
wmod
.
filters
is
not
orig_filters
)
self
.
assert_
(
wmod
.
filters
is
orig_filters
)
def
test_check_warnings
(
self
):
# Explicit tests for the test.support convenience wrapper
wmod
=
self
.
module
if
wmod
is
sys
.
modules
[
'warnings'
]:
with
support
.
check_warnings
()
as
w
:
self
.
assertEqual
(
w
.
warnings
,
[])
wmod
.
simplefilter
(
"always"
)
wmod
.
warn
(
"foo"
)
self
.
assertEqual
(
str
(
w
.
message
),
"foo"
)
wmod
.
warn
(
"bar"
)
self
.
assertEqual
(
str
(
w
.
message
),
"bar"
)
self
.
assertEqual
(
str
(
w
.
warnings
[
0
].
message
),
"foo"
)
self
.
assertEqual
(
str
(
w
.
warnings
[
1
].
message
),
"bar"
)
w
.
reset
()
self
.
assertEqual
(
w
.
warnings
,
[])
class
CCatchWarningTests
(
CatchWarningTests
):
module
=
c_warnings
...
...
Lib/warnings.py
View file @
fcf5d639
...
...
@@ -301,8 +301,21 @@ class catch_warnings(object):
"""
self
.
_record
=
record
self
.
_module
=
sys
.
modules
[
'warnings'
]
if
module
is
None
else
module
self
.
_entered
=
False
def
__repr__
(
self
):
args
=
[]
if
self
.
_record
:
args
.
append
(
"record=True"
)
if
self
.
_module
is
not
sys
.
modules
[
'warnings'
]:
args
.
append
(
"module=%r"
%
self
.
_module
)
name
=
type
(
self
).
__name__
return
"%s(%s)"
%
(
name
,
", "
.
join
(
args
))
def
__enter__
(
self
):
if
self
.
_entered
:
raise
RuntimeError
(
"Cannot enter %r twice"
%
self
)
self
.
_entered
=
True
self
.
_filters
=
self
.
_module
.
filters
self
.
_module
.
filters
=
self
.
_filters
[:]
self
.
_showwarning
=
self
.
_module
.
showwarning
...
...
@@ -316,6 +329,8 @@ class catch_warnings(object):
return
None
def
__exit__
(
self
,
*
exc_info
):
if
not
self
.
_entered
:
raise
RuntimeError
(
"Cannot exit %r without entering first"
%
self
)
self
.
_module
.
filters
=
self
.
_filters
self
.
_module
.
showwarning
=
self
.
_showwarning
...
...
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