Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b14930c

Browse files
committed
Only the parts which are relevant for 3.x branch.
Merged revisions 78757-78758,78769,78815 via svnmerge from svn+ssh://[email protected]/python/trunk ........ r78757 | florent.xicluna | 2010-03-07 13:14:25 +0100 (dim, 07 mar 2010) | 2 lines Fix some py3k warnings in the standard library. ........ r78758 | florent.xicluna | 2010-03-07 13:18:33 +0100 (dim, 07 mar 2010) | 4 lines Issue #7849: Now the utility ``check_warnings`` verifies if the warnings are effectively raised. A new utility ``check_py3k_warnings`` deals with py3k warnings. ........ r78769 | florent.xicluna | 2010-03-07 20:14:12 +0100 (dim, 07 mar 2010) | 2 lines Refresh the documentation for the test.test_support module. ........ r78815 | florent.xicluna | 2010-03-09 20:57:01 +0100 (mar, 09 mar 2010) | 2 lines #7772: Fix test_py3kwarn. Now the test suite could pass with "-3" flag. ........
1 parent 8142d8d commit b14930c

5 files changed

Lines changed: 122 additions & 34 deletions

File tree

Doc/library/test.rst

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@ guidelines to be followed:
130130
self.func(self.arg)
131131

132132
class AcceptLists(TestFuncAcceptsSequences):
133-
arg = [1,2,3]
133+
arg = [1, 2, 3]
134134

135135
class AcceptStrings(TestFuncAcceptsSequences):
136136
arg = 'abc'
137137

138138
class AcceptTuples(TestFuncAcceptsSequences):
139-
arg = (1,2,3)
139+
arg = (1, 2, 3)
140140

141141

142142
.. seealso::
@@ -198,16 +198,9 @@ This module defines the following exceptions:
198198
methods.
199199

200200

201-
.. exception:: TestSkipped
202-
203-
Subclass of :exc:`TestFailed`. Raised when a test is skipped. This occurs when a
204-
needed resource (such as a network connection) is not available at the time of
205-
testing.
206-
207-
208201
.. exception:: ResourceDenied
209202

210-
Subclass of :exc:`TestSkipped`. Raised when a resource (such as a network
203+
Subclass of :exc:`unittest.SkipTest`. Raised when a resource (such as a network
211204
connection) is not available. Raised by the :func:`requires` function.
212205

213206
The :mod:`test.support` module defines the following constants:
@@ -227,29 +220,29 @@ The :mod:`test.support` module defines the following constants:
227220

228221
.. data:: TESTFN
229222

230-
Set to the path that a temporary file may be created at. Any temporary that is
223+
Set to the name that a temporary file could use. Any temporary file that is
231224
created should be closed and unlinked (removed).
232225

233226
The :mod:`test.support` module defines the following functions:
234227

235228

236229
.. function:: forget(module_name)
237230

238-
Removes the module named *module_name* from ``sys.modules`` and deletes any
231+
Remove the module named *module_name* from ``sys.modules`` and deletes any
239232
byte-compiled files of the module.
240233

241234

242235
.. function:: is_resource_enabled(resource)
243236

244-
Returns :const:`True` if *resource* is enabled and available. The list of
237+
Return :const:`True` if *resource* is enabled and available. The list of
245238
available resources is only set when :mod:`test.regrtest` is executing the
246239
tests.
247240

248241

249242
.. function:: requires(resource, msg=None)
250243

251-
Raises :exc:`ResourceDenied` if *resource* is not available. *msg* is the
252-
argument to :exc:`ResourceDenied` if it is raised. Always returns true if called
244+
Raise :exc:`ResourceDenied` if *resource* is not available. *msg* is the
245+
argument to :exc:`ResourceDenied` if it is raised. Always returns True if called
253246
by a function whose ``__name__`` is ``'__main__'``. Used when tests are executed
254247
by :mod:`test.regrtest`.
255248

@@ -277,14 +270,24 @@ The :mod:`test.support` module defines the following functions:
277270
This will run all tests defined in the named module.
278271

279272

280-
.. function:: check_warnings()
273+
.. function:: check_warnings(*filters, quiet=False)
281274

282275
A convenience wrapper for ``warnings.catch_warnings()`` that makes
283276
it easier to test that a warning was correctly raised with a single
284277
assertion. It is approximately equivalent to calling
285278
``warnings.catch_warnings(record=True)``.
286279

287-
The main difference is that on entry to the context manager, a
280+
It accepts 2-tuples ``("message regexp", WarningCategory)`` as positional
281+
arguments. When the optional keyword argument ``quiet`` is True, it does
282+
not fail if a filter catches nothing. Without argument, it defaults to::
283+
284+
check_warnings(("", Warning), quiet=False)
285+
286+
The main difference is that it verifies the warnings raised. If some filter
287+
did not catch any warning, the test fails. If some warnings are not caught,
288+
the test fails, too. To disable these checks, use argument ``quiet=True``.
289+
290+
Another significant difference is that on entry to the context manager, a
288291
:class:`WarningRecorder` instance is returned instead of a simple list.
289292
The underlying warnings list is available via the recorder object's
290293
:attr:`warnings` attribute, while the attributes of the last raised
@@ -294,19 +297,34 @@ The :mod:`test.support` module defines the following functions:
294297
A :meth:`reset` method is also provided on the recorder object. This
295298
method simply clears the warning list.
296299

297-
The context manager is used like this::
300+
The context manager may be used like this::
301+
302+
import warnings
303+
304+
with check_warnings():
305+
exec('assert(False, "Hey!")')
306+
warnings.warn(UserWarning("Hide me!"))
298307

299-
with check_warnings() as w:
308+
with check_warnings(("assertion is always true", SyntaxWarning),
309+
("", UserWarning)):
310+
exec('assert(False, "Hey!")')
311+
warnings.warn(UserWarning("Hide me!"))
312+
313+
with check_warnings(quiet=True) as w:
300314
warnings.simplefilter("always")
301315
warnings.warn("foo")
302-
assert str(w.message) == "foo"
316+
assert str(w.args[0]) == "foo"
303317
warnings.warn("bar")
304-
assert str(w.message) == "bar"
305-
assert str(w.warnings[0].message) == "foo"
306-
assert str(w.warnings[1].message) == "bar"
318+
assert str(w.args[0]) == "bar"
319+
assert str(w.warnings[0].args[0]) == "foo"
320+
assert str(w.warnings[1].args[0]) == "bar"
307321
w.reset()
308322
assert len(w.warnings) == 0
309323

324+
.. versionchanged:: 2.7
325+
The test fails when the context manager do not catch any warning.
326+
New optional attributes ``*filters`` and ``quiet``.
327+
310328

311329
.. function:: captured_stdout()
312330

Lib/_pyio.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ def seek(self, pos, whence=0):
828828
if self.closed:
829829
raise ValueError("seek on closed file")
830830
try:
831-
pos = pos.__index__()
831+
pos.__index__
832832
except AttributeError as err:
833833
raise TypeError("an integer is required") from err
834834
if whence == 0:
@@ -853,8 +853,13 @@ def truncate(self, pos=None):
853853
raise ValueError("truncate on closed file")
854854
if pos is None:
855855
pos = self._pos
856-
elif pos < 0:
857-
raise ValueError("negative truncate position %r" % (pos,))
856+
else:
857+
try:
858+
pos.__index__
859+
except AttributeError as err:
860+
raise TypeError("an integer is required") from err
861+
if pos < 0:
862+
raise ValueError("negative truncate position %r" % (pos,))
858863
del self._buffer[pos:]
859864
return pos
860865

@@ -1803,6 +1808,10 @@ def read(self, n=None):
18031808
if n is None:
18041809
n = -1
18051810
decoder = self._decoder or self._get_decoder()
1811+
try:
1812+
n.__index__
1813+
except AttributeError as err:
1814+
raise TypeError("an integer is required") from err
18061815
if n < 0:
18071816
# Read everything.
18081817
result = (self._get_decoded_chars() +

Lib/test/support.py

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import unittest
1717
import importlib
1818
import collections
19+
import re
1920

2021
__all__ = ["Error", "TestFailed", "ResourceDenied", "import_module",
2122
"verbose", "use_resources", "max_memuse", "record_original_stdout",
@@ -464,22 +465,80 @@ class WarningsRecorder(object):
464465
entry to the warnings.catch_warnings() context manager.
465466
"""
466467
def __init__(self, warnings_list):
467-
self.warnings = warnings_list
468+
self._warnings = warnings_list
469+
self._last = 0
468470

469471
def __getattr__(self, attr):
470-
if self.warnings:
471-
return getattr(self.warnings[-1], attr)
472+
if len(self._warnings) > self._last:
473+
return getattr(self._warnings[-1], attr)
472474
elif attr in warnings.WarningMessage._WARNING_DETAILS:
473475
return None
474476
raise AttributeError("%r has no attribute %r" % (self, attr))
475477

478+
@property
479+
def warnings(self):
480+
return self._warnings[self._last:]
481+
476482
def reset(self):
477-
del self.warnings[:]
483+
self._last = len(self._warnings)
478484

479-
@contextlib.contextmanager
480-
def check_warnings():
485+
486+
def _filterwarnings(filters, quiet=False):
487+
"""Catch the warnings, then check if all the expected
488+
warnings have been raised and re-raise unexpected warnings.
489+
If 'quiet' is True, only re-raise the unexpected warnings.
490+
"""
491+
# Clear the warning registry of the calling module
492+
# in order to re-raise the warnings.
493+
frame = sys._getframe(2)
494+
registry = frame.f_globals.get('__warningregistry__')
495+
if registry:
496+
registry.clear()
481497
with warnings.catch_warnings(record=True) as w:
498+
# Set filter "always" to record all warnings. Because
499+
# test_warnings swap the module, we need to look up in
500+
# the sys.modules dictionary.
501+
sys.modules['warnings'].simplefilter("always")
482502
yield WarningsRecorder(w)
503+
# Filter the recorded warnings
504+
reraise = [warning.message for warning in w]
505+
missing = []
506+
for msg, cat in filters:
507+
seen = False
508+
for exc in reraise[:]:
509+
message = str(exc)
510+
# Filter out the matching messages
511+
if (re.match(msg, message, re.I) and
512+
issubclass(exc.__class__, cat)):
513+
seen = True
514+
reraise.remove(exc)
515+
if not seen and not quiet:
516+
# This filter caught nothing
517+
missing.append((msg, cat.__name__))
518+
if reraise:
519+
raise AssertionError("unhandled warning %r" % reraise[0])
520+
if missing:
521+
raise AssertionError("filter (%r, %s) did not catch any warning" %
522+
missing[0])
523+
524+
525+
@contextlib.contextmanager
526+
def check_warnings(*filters, **kwargs):
527+
"""Context manager to silence warnings.
528+
529+
Accept 2-tuples as positional arguments:
530+
("message regexp", WarningCategory)
531+
532+
Optional argument:
533+
- if 'quiet' is True, it does not fail if a filter catches nothing
534+
(default False)
535+
536+
Without argument, it defaults to:
537+
check_warnings(("", Warning), quiet=False)
538+
"""
539+
if not filters:
540+
filters = (("", Warning),)
541+
return _filterwarnings(filters, kwargs.get('quiet'))
483542

484543

485544
class CleanImport(object):
@@ -714,7 +773,6 @@ def inner(*args, **kwds):
714773
MAX_Py_ssize_t = sys.maxsize
715774

716775
def set_memlimit(limit):
717-
import re
718776
global max_memuse
719777
global real_max_memuse
720778
sizes = {

Lib/test/test_fileio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def testInvalidInit(self):
390390
self.assertRaises(TypeError, _FileIO, "1", 0, 0)
391391

392392
def testWarnings(self):
393-
with check_warnings() as w:
393+
with check_warnings(quiet=True) as w:
394394
self.assertEqual(w.warnings, [])
395395
self.assertRaises(TypeError, _FileIO, [])
396396
self.assertEqual(w.warnings, [])

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ Documentation
869869
Tests
870870
-----
871871

872+
- Issue #7849: Now the utility ``check_warnings`` verifies if the warnings are
873+
effectively raised.
874+
872875
- The four path modules (genericpath, macpath, ntpath, posixpath) share a
873876
common TestCase for some tests: test_genericpath.CommonTest.
874877

0 commit comments

Comments
 (0)