#10535: Enable silenced warnings in unittest by default
diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py
index 8473a33..bd5f2a4 100644
--- a/Lib/unittest/main.py
+++ b/Lib/unittest/main.py
@@ -67,12 +67,12 @@
     USAGE = USAGE_FROM_MODULE
 
     # defaults for testing
-    failfast = catchbreak = buffer = progName = None
+    failfast = catchbreak = buffer = progName = warnings = None
 
     def __init__(self, module='__main__', defaultTest=None, argv=None,
                     testRunner=None, testLoader=loader.defaultTestLoader,
                     exit=True, verbosity=1, failfast=None, catchbreak=None,
-                    buffer=None):
+                    buffer=None, warnings=None):
         if isinstance(module, str):
             self.module = __import__(module)
             for part in module.split('.')[1:]:
@@ -87,6 +87,18 @@
         self.catchbreak = catchbreak
         self.verbosity = verbosity
         self.buffer = buffer
+        if warnings is None and not sys.warnoptions:
+            # even if DreprecationWarnings are ignored by default
+            # print them anyway unless other warnings settings are
+            # specified by the warnings arg or the -W python flag
+            self.warnings = 'default'
+        else:
+            # here self.warnings is set either to the value passed
+            # to the warnings args or to None.
+            # If the user didn't pass a value self.warnings will
+            # be None. This means that the behavior is unchanged
+            # and depends on the values passed to -W.
+            self.warnings = warnings
         self.defaultTest = defaultTest
         self.testRunner = testRunner
         self.testLoader = testLoader
@@ -220,7 +232,8 @@
             try:
                 testRunner = self.testRunner(verbosity=self.verbosity,
                                              failfast=self.failfast,
-                                             buffer=self.buffer)
+                                             buffer=self.buffer,
+                                             warnings=self.warnings)
             except TypeError:
                 # didn't accept the verbosity, buffer or failfast arguments
                 testRunner = self.testRunner()
diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py
index cd9526d..c5e4258 100644
--- a/Lib/unittest/runner.py
+++ b/Lib/unittest/runner.py
@@ -2,6 +2,7 @@
 
 import sys
 import time
+import warnings
 
 from . import result
 from .signals import registerResult
@@ -125,12 +126,13 @@
     resultclass = TextTestResult
 
     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
-                 failfast=False, buffer=False, resultclass=None):
+                 failfast=False, buffer=False, resultclass=None, warnings=None):
         self.stream = _WritelnDecorator(stream)
         self.descriptions = descriptions
         self.verbosity = verbosity
         self.failfast = failfast
         self.buffer = buffer
+        self.warnings = warnings
         if resultclass is not None:
             self.resultclass = resultclass
 
@@ -143,17 +145,30 @@
         registerResult(result)
         result.failfast = self.failfast
         result.buffer = self.buffer
-        startTime = time.time()
-        startTestRun = getattr(result, 'startTestRun', None)
-        if startTestRun is not None:
-            startTestRun()
-        try:
-            test(result)
-        finally:
-            stopTestRun = getattr(result, 'stopTestRun', None)
-            if stopTestRun is not None:
-                stopTestRun()
-        stopTime = time.time()
+        with warnings.catch_warnings():
+            if self.warnings:
+                # if self.warnings is set, use it to filter all the warnings
+                warnings.simplefilter(self.warnings)
+                # if the filter is 'default' or 'always', special-case the
+                # warnings from the deprecated unittest methods to show them
+                # no more than once per module, because they can be fairly
+                # noisy.  The -Wd and -Wa flags can be used to bypass this
+                # only when self.warnings is None.
+                if self.warnings in ['default', 'always']:
+                    warnings.filterwarnings('module',
+                            category=DeprecationWarning,
+                            message='Please use assert\w+ instead.')
+            startTime = time.time()
+            startTestRun = getattr(result, 'startTestRun', None)
+            if startTestRun is not None:
+                startTestRun()
+            try:
+                test(result)
+            finally:
+                stopTestRun = getattr(result, 'stopTestRun', None)
+                if stopTestRun is not None:
+                    stopTestRun()
+            stopTime = time.time()
         timeTaken = stopTime - startTime
         result.printErrors()
         if hasattr(result, 'separator2'):
diff --git a/Lib/unittest/test/_test_warnings.py b/Lib/unittest/test/_test_warnings.py
new file mode 100644
index 0000000..d0be18d
--- /dev/null
+++ b/Lib/unittest/test/_test_warnings.py
@@ -0,0 +1,74 @@
+# helper module for test_runner.Test_TextTestRunner.test_warnings
+
+"""
+This module has a number of tests that raise different kinds of warnings.
+When the tests are run, the warnings are caught and their messages are printed
+to stdout.  This module also accepts an arg that is then passed to
+unittest.main to affect the behavior of warnings.
+Test_TextTestRunner.test_warnings executes this script with different
+combinations of warnings args and -W flags and check that the output is correct.
+See #10535.
+"""
+
+import io
+import sys
+import unittest
+import warnings
+
+def warnfun():
+    warnings.warn('rw', RuntimeWarning)
+
+class TestWarnings(unittest.TestCase):
+    # unittest warnings will be printed at most once per type (max one message
+    # for the fail* methods, and one for the assert* methods)
+    def test_assert(self):
+        self.assertEquals(2+2, 4)
+        self.assertEquals(2*2, 4)
+        self.assertEquals(2**2, 4)
+
+    def test_fail(self):
+        self.failUnless(1)
+        self.failUnless(True)
+
+    def test_other_unittest(self):
+        self.assertAlmostEqual(2+2, 4)
+        self.assertNotAlmostEqual(4+4, 2)
+
+    # these warnings are normally silenced, but they are printed in unittest
+    def test_deprecation(self):
+        warnings.warn('dw', DeprecationWarning)
+        warnings.warn('dw', DeprecationWarning)
+        warnings.warn('dw', DeprecationWarning)
+
+    def test_import(self):
+        warnings.warn('iw', ImportWarning)
+        warnings.warn('iw', ImportWarning)
+        warnings.warn('iw', ImportWarning)
+
+    # user warnings should always be printed
+    def test_warning(self):
+        warnings.warn('uw')
+        warnings.warn('uw')
+        warnings.warn('uw')
+
+    # these warnings come from the same place; they will be printed
+    # only once by default or three times if the 'always' filter is used
+    def test_function(self):
+
+        warnfun()
+        warnfun()
+        warnfun()
+
+
+
+if __name__ == '__main__':
+    with warnings.catch_warnings(record=True) as ws:
+        # if an arg is provided pass it to unittest.main as 'warnings'
+        if len(sys.argv) == 2:
+            unittest.main(exit=False, warnings=sys.argv.pop())
+        else:
+            unittest.main(exit=False)
+
+    # print all the warning messages collected
+    for w in ws:
+        print(w.message)
diff --git a/Lib/unittest/test/test_break.py b/Lib/unittest/test/test_break.py
index 0e09dfb..77ce201 100644
--- a/Lib/unittest/test/test_break.py
+++ b/Lib/unittest/test/test_break.py
@@ -209,7 +209,8 @@
 
         self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
                                                      'verbosity': verbosity,
-                                                     'failfast': failfast})])
+                                                     'failfast': failfast,
+                                                     'warnings': None})])
         self.assertEqual(FakeRunner.runArgs, [test])
         self.assertEqual(p.result, result)
 
@@ -222,7 +223,8 @@
 
         self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
                                                      'verbosity': verbosity,
-                                                     'failfast': failfast})])
+                                                     'failfast': failfast,
+                                                     'warnings': None})])
         self.assertEqual(FakeRunner.runArgs, [test])
         self.assertEqual(p.result, result)
 
diff --git a/Lib/unittest/test/test_program.py b/Lib/unittest/test/test_program.py
index f8e2804..2eb0be3 100644
--- a/Lib/unittest/test/test_program.py
+++ b/Lib/unittest/test/test_program.py
@@ -182,6 +182,27 @@
                 program.parseArgs([None, opt])
                 self.assertEqual(getattr(program, attr), not_none)
 
+    def testWarning(self):
+        """Test the warnings argument"""
+        # see #10535
+        class FakeTP(unittest.TestProgram):
+            def parseArgs(self, *args, **kw): pass
+            def runTests(self, *args, **kw): pass
+        warnoptions = sys.warnoptions
+        try:
+            sys.warnoptions[:] = []
+            # no warn options, no arg -> default
+            self.assertEqual(FakeTP().warnings, 'default')
+            # no warn options, w/ arg -> arg value
+            self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
+            sys.warnoptions[:] = ['somevalue']
+            # warn options, no arg -> None
+            # warn options, w/ arg -> arg value
+            self.assertEqual(FakeTP().warnings, None)
+            self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
+        finally:
+            sys.warnoptions[:] = warnoptions
+
     def testRunTestsRunnerClass(self):
         program = self.program
 
@@ -189,12 +210,14 @@
         program.verbosity = 'verbosity'
         program.failfast = 'failfast'
         program.buffer = 'buffer'
+        program.warnings = 'warnings'
 
         program.runTests()
 
         self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
                                                 'failfast': 'failfast',
-                                                'buffer': 'buffer'})
+                                                'buffer': 'buffer',
+                                                'warnings': 'warnings'})
         self.assertEqual(FakeRunner.test, 'test')
         self.assertIs(program.result, RESULT)
 
diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py
index 25f7541..efd4962 100644
--- a/Lib/unittest/test/test_runner.py
+++ b/Lib/unittest/test/test_runner.py
@@ -1,5 +1,8 @@
 import io
+import os
+import sys
 import pickle
+import subprocess
 
 import unittest
 
@@ -144,6 +147,7 @@
         self.assertFalse(runner.failfast)
         self.assertFalse(runner.buffer)
         self.assertEqual(runner.verbosity, 1)
+        self.assertEqual(runner.warnings, None)
         self.assertTrue(runner.descriptions)
         self.assertEqual(runner.resultclass, unittest.TextTestResult)
 
@@ -244,3 +248,57 @@
 
         expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY)
         self.assertEqual(runner._makeResult(), expectedresult)
+
+    def test_warnings(self):
+        """
+        Check that warnings argument of TextTestRunner correctly affects the
+        behavior of the warnings.
+        """
+        # see #10535 and the _test_warnings file for more information
+
+        def get_parse_out_err(p):
+            return [b.splitlines() for b in p.communicate()]
+        opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                    cwd=os.path.dirname(__file__))
+        ae_msg = b'Please use assertEqual instead.'
+        at_msg = b'Please use assertTrue instead.'
+
+        # no args -> all the warnings are printed, unittest warnings only once
+        p = subprocess.Popen([sys.executable, '_test_warnings.py'], **opts)
+        out, err = get_parse_out_err(p)
+        self.assertEqual(err[-1], b'OK')
+        # check that the total number of warnings in the output is correct
+        self.assertEqual(len(out), 12)
+        # check that the numbers of the different kind of warnings is correct
+        for msg in [b'dw', b'iw', b'uw']:
+            self.assertEqual(out.count(msg), 3)
+        for msg in [ae_msg, at_msg, b'rw']:
+            self.assertEqual(out.count(msg), 1)
+
+        args_list = (
+            # passing 'ignore' as warnings arg -> no warnings
+            [sys.executable, '_test_warnings.py', 'ignore'],
+            # -W doesn't affect the result if the arg is passed
+            [sys.executable, '-Wa', '_test_warnings.py', 'ignore'],
+            # -W affects the result if the arg is not passed
+            [sys.executable, '-Wi', '_test_warnings.py']
+        )
+        # in all these cases no warnings are printed
+        for args in args_list:
+            p = subprocess.Popen(args, **opts)
+            out, err = get_parse_out_err(p)
+            self.assertEqual(err[-1], b'OK')
+            self.assertEqual(len(out), 0)
+
+
+        # passing 'always' as warnings arg -> all the warnings printed,
+        #                                     unittest warnings only once
+        p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'],
+                             **opts)
+        out, err = get_parse_out_err(p)
+        self.assertEqual(err[-1], b'OK')
+        self.assertEqual(len(out), 14)
+        for msg in [b'dw', b'iw', b'uw', b'rw']:
+            self.assertEqual(out.count(msg), 3)
+        for msg in [ae_msg, at_msg]:
+            self.assertEqual(out.count(msg), 1)