From python-checkins at python.org Wed Dec 1 00:46:54 2010 From: python-checkins at python.org (brian.curtin) Date: Wed, 1 Dec 2010 00:46:54 +0100 (CET) Subject: [Python-checkins] r86906 - python/branches/py3k/Lib/test/test_os.py Message-ID: <20101130234654.8B06DEE9F9@mail.python.org> Author: brian.curtin Date: Wed Dec 1 00:46:54 2010 New Revision: 86906 Log: Fix #10591. Fix test_os for refleak runs. Split a common setUp/tearDown into the appropriate parts. Modified: python/branches/py3k/Lib/test/test_os.py Modified: python/branches/py3k/Lib/test/test_os.py ============================================================================== --- python/branches/py3k/Lib/test/test_os.py (original) +++ python/branches/py3k/Lib/test/test_os.py Wed Dec 1 00:46:54 2010 @@ -866,12 +866,11 @@ self.file1 = support.TESTFN self.file2 = os.path.join(support.TESTFN + "2") + def tearDown(self): for file in (self.file1, self.file2): if os.path.exists(file): os.unlink(file) - tearDown = setUp - def _test_link(self, file1, file2): with open(file1, "w") as f1: f1.write("test") From python-checkins at python.org Wed Dec 1 01:48:02 2010 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Dec 2010 01:48:02 +0100 (CET) Subject: [Python-checkins] r86907 - in python/branches/py3k: Doc/library/functools.rst Lib/functools.py Message-ID: <20101201004802.C9664EEA68@mail.python.org> Author: raymond.hettinger Date: Wed Dec 1 01:47:56 2010 New Revision: 86907 Log: Doc and docstring nits. Modified: python/branches/py3k/Doc/library/functools.rst python/branches/py3k/Lib/functools.py Modified: python/branches/py3k/Doc/library/functools.rst ============================================================================== --- python/branches/py3k/Doc/library/functools.rst (original) +++ python/branches/py3k/Doc/library/functools.rst Wed Dec 1 01:47:56 2010 @@ -91,6 +91,10 @@ .. versionadded:: 3.2 + .. seealso:: + + Recipe for a `plain cache without the LRU feature + `_. .. decorator:: total_ordering Modified: python/branches/py3k/Lib/functools.py ============================================================================== --- python/branches/py3k/Lib/functools.py (original) +++ python/branches/py3k/Lib/functools.py Wed Dec 1 01:47:56 2010 @@ -121,9 +121,9 @@ Arguments to the cached function must be hashable. - View the cache statistics named tuple (maxsize, size, hits, misses) with + View the cache statistics named tuple (hits, misses, maxsize, currsize) with f.cache_info(). Clear the cache and statistics with f.cache_clear(). - And access the underlying function with f.__wrapped__. + Access the underlying function with f.__wrapped__. See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used From python-checkins at python.org Wed Dec 1 01:56:10 2010 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Dec 2010 01:56:10 +0100 (CET) Subject: [Python-checkins] r86908 - in python/branches/py3k: Doc/library/unittest.rst Doc/library/warnings.rst Lib/unittest/main.py Lib/unittest/runner.py Lib/unittest/test/_test_warnings.py Lib/unittest/test/test_break.py Lib/unittest/test/test_program.py Lib/unittest/test/test_runner.py Message-ID: <20101201005610.E54D7EEA73@mail.python.org> Author: ezio.melotti Date: Wed Dec 1 01:56:10 2010 New Revision: 86908 Log: #10535: Enable silenced warnings in unittest by default Added: python/branches/py3k/Lib/unittest/test/_test_warnings.py Modified: python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/library/warnings.rst python/branches/py3k/Lib/unittest/main.py python/branches/py3k/Lib/unittest/runner.py python/branches/py3k/Lib/unittest/test/test_break.py python/branches/py3k/Lib/unittest/test/test_program.py python/branches/py3k/Lib/unittest/test/test_runner.py Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Wed Dec 1 01:56:10 2010 @@ -1845,12 +1845,21 @@ instead of repeatedly creating new instances. -.. class:: TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1, runnerclass=None) +.. class:: TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1, runnerclass=None, warnings=None) A basic test runner implementation which prints results on standard error. It has a few configurable parameters, but is essentially very simple. Graphical applications which run test suites should provide alternate implementations. + By default this runner shows :exc:`DeprecationWarning`, + :exc:`PendingDeprecationWarning`, and :exc:`ImportWarning` even if they are + :ref:`ignored by default `. Deprecation warnings caused by + :ref:`deprecated unittest methods ` are also + special-cased and, when the warning filters are ``'default'`` or ``'always'``, + they will appear only once per-module, in order to avoid too many warning + messages. This behavior can be overridden using the :option`-Wd` or + :option:`-Wa` options and leaving *warnings* to ``None``. + .. method:: _makeResult() This method returns the instance of ``TestResult`` used by :meth:`run`. @@ -1864,7 +1873,9 @@ stream, descriptions, verbosity -.. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None) + .. versionchanged:: 3.2 Added the ``warnings`` argument + +.. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None) A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. The simplest use for this function is to @@ -1893,12 +1904,17 @@ The ``failfast``, ``catchbreak`` and ``buffer`` parameters have the same effect as the same-name `command-line options`_. + The *warning* argument specifies the :ref:`warning filter ` + that should be used while running the tests. If it's not specified, it will + remain ``None`` if a :option:`-W` option is passed to :program:`python`, + otherwise it will be set to ``'default'``. + Calling ``main`` actually returns an instance of the ``TestProgram`` class. This stores the result of the tests run as the ``result`` attribute. .. versionchanged:: 3.2 - The ``exit``, ``verbosity``, ``failfast``, ``catchbreak`` and ``buffer`` - parameters were added. + The ``exit``, ``verbosity``, ``failfast``, ``catchbreak``, ``buffer``, + and ``warnings`` parameters were added. load_tests Protocol Modified: python/branches/py3k/Doc/library/warnings.rst ============================================================================== --- python/branches/py3k/Doc/library/warnings.rst (original) +++ python/branches/py3k/Doc/library/warnings.rst Wed Dec 1 01:56:10 2010 @@ -249,6 +249,8 @@ entries from the warnings list before each new operation). +.. _warning-ignored: + Updating Code For New Versions of Python ---------------------------------------- @@ -279,6 +281,9 @@ developer want to be notified that your code is using a deprecated module, to a user this information is essentially noise and provides no benefit to them. +The :mod:`unittest` module has been also updated to use the ``'default'`` +filter while running tests. + .. _warning-functions: Modified: python/branches/py3k/Lib/unittest/main.py ============================================================================== --- python/branches/py3k/Lib/unittest/main.py (original) +++ python/branches/py3k/Lib/unittest/main.py Wed Dec 1 01:56:10 2010 @@ -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() Modified: python/branches/py3k/Lib/unittest/runner.py ============================================================================== --- python/branches/py3k/Lib/unittest/runner.py (original) +++ python/branches/py3k/Lib/unittest/runner.py Wed Dec 1 01:56:10 2010 @@ -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'): Added: python/branches/py3k/Lib/unittest/test/_test_warnings.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/unittest/test/_test_warnings.py Wed Dec 1 01:56:10 2010 @@ -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) Modified: python/branches/py3k/Lib/unittest/test/test_break.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_break.py (original) +++ python/branches/py3k/Lib/unittest/test/test_break.py Wed Dec 1 01:56:10 2010 @@ -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) Modified: python/branches/py3k/Lib/unittest/test/test_program.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_program.py (original) +++ python/branches/py3k/Lib/unittest/test/test_program.py Wed Dec 1 01:56:10 2010 @@ -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) Modified: python/branches/py3k/Lib/unittest/test/test_runner.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_runner.py (original) +++ python/branches/py3k/Lib/unittest/test/test_runner.py Wed Dec 1 01:56:10 2010 @@ -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) From python-checkins at python.org Wed Dec 1 02:45:53 2010 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Dec 2010 02:45:53 +0100 (CET) Subject: [Python-checkins] r86909 - in python/branches/py3k: Lib/unittest/test/test_runner.py Misc/NEWS Message-ID: <20101201014553.E34E2EEB37@mail.python.org> Author: ezio.melotti Date: Wed Dec 1 02:45:53 2010 New Revision: 86909 Log: Fix test failure in debug builds and add NEWS entry for r86908 Modified: python/branches/py3k/Lib/unittest/test/test_runner.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/unittest/test/test_runner.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_runner.py (original) +++ python/branches/py3k/Lib/unittest/test/test_runner.py Wed Dec 1 02:45:53 2010 @@ -266,7 +266,7 @@ # 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') + self.assertIn(b'OK', err) # 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 @@ -287,7 +287,7 @@ for args in args_list: p = subprocess.Popen(args, **opts) out, err = get_parse_out_err(p) - self.assertEqual(err[-1], b'OK') + self.assertIn(b'OK', err) self.assertEqual(len(out), 0) @@ -296,7 +296,7 @@ p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'], **opts) out, err = get_parse_out_err(p) - self.assertEqual(err[-1], b'OK') + self.assertIn(b'OK', err) self.assertEqual(len(out), 14) for msg in [b'dw', b'iw', b'uw', b'rw']: self.assertEqual(out.count(msg), 3) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 1 02:45:53 2010 @@ -46,6 +46,8 @@ Library ------- +- Issue #10535: Enable silenced warnings in unittest by default. + - Issue #9873: The URL parsing functions in urllib.parse now accept ASCII byte sequences as input in addition to character strings. From python-checkins at python.org Wed Dec 1 03:32:33 2010 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Dec 2010 03:32:33 +0100 (CET) Subject: [Python-checkins] r86910 - in python/branches/py3k: Doc/library/unittest.rst Lib/test/test_abc.py Lib/test/test_asyncore.py Lib/test/test_concurrent_futures.py Lib/test/test_contextlib.py Lib/test/test_dis.py Lib/test/test_memoryview.py Lib/test/test_runpy.py Lib/test/test_smtplib.py Lib/test/test_ssl.py Lib/test/test_unicode.py Lib/test/test_urlparse.py Lib/test/test_xmlrpc.py Lib/test/test_zlib.py Lib/unittest/case.py Lib/unittest/test/test_assertions.py Lib/unittest/test/test_case.py Lib/unittest/test/test_discovery.py Lib/unittest/test/test_loader.py Lib/unittest/test/test_setups.py Misc/NEWS Message-ID: <20101201023233.2C46AEEA6D@mail.python.org> Author: ezio.melotti Date: Wed Dec 1 03:32:32 2010 New Revision: 86910 Log: #10273: Rename assertRegexpMatches and assertRaisesRegexp to assertRegex and assertRaisesRegex. Modified: python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Lib/test/test_abc.py python/branches/py3k/Lib/test/test_asyncore.py python/branches/py3k/Lib/test/test_concurrent_futures.py python/branches/py3k/Lib/test/test_contextlib.py python/branches/py3k/Lib/test/test_dis.py python/branches/py3k/Lib/test/test_memoryview.py python/branches/py3k/Lib/test/test_runpy.py python/branches/py3k/Lib/test/test_smtplib.py python/branches/py3k/Lib/test/test_ssl.py python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Lib/test/test_urlparse.py python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Lib/test/test_zlib.py python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/test/test_assertions.py python/branches/py3k/Lib/unittest/test/test_case.py python/branches/py3k/Lib/unittest/test/test_discovery.py python/branches/py3k/Lib/unittest/test/test_loader.py python/branches/py3k/Lib/unittest/test/test_setups.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Wed Dec 1 03:32:32 2010 @@ -835,7 +835,7 @@ +-----------------------------------------+-----------------------------+---------------+ All the assert methods (except :meth:`assertRaises`, - :meth:`assertRaisesRegexp`, :meth:`assertWarns`, :meth:`assertWarnsRegexp`) + :meth:`assertRaisesRegex`, :meth:`assertWarns`, :meth:`assertWarnsRegex`) accept a *msg* argument that, if specified, is used as the error message on failure (see also :data:`longMessage`). @@ -919,14 +919,14 @@ | :meth:`assertRaises(exc, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `exc` | | | ` | | | +---------------------------------------------------------+--------------------------------------+------------+ - | :meth:`assertRaisesRegexp(exc, re, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `exc` | 3.1 | - | ` | and the message matches `re` | | + | :meth:`assertRaisesRegex(exc, re, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `exc` | 3.1 | + | ` | and the message matches `re` | | +---------------------------------------------------------+--------------------------------------+------------+ | :meth:`assertWarns(warn, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `warn` | 3.2 | | ` | | | +---------------------------------------------------------+--------------------------------------+------------+ - | :meth:`assertWarnsRegexp(warn, re, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `warn` | 3.2 | - | ` | and the message matches `re` | | + | :meth:`assertWarnsRegex(warn, re, fun, *args, **kwds) | ``fun(*args, **kwds)`` raises `warn` | 3.2 | + | ` | and the message matches `re` | | +---------------------------------------------------------+--------------------------------------+------------+ .. method:: assertRaises(exception, callable, *args, **kwds) @@ -962,23 +962,25 @@ Added the :attr:`exception` attribute. - .. method:: assertRaisesRegexp(exception, regexp, callable, *args, **kwds) - assertRaisesRegexp(exception, regexp) + .. method:: assertRaisesRegex(exception, regex, callable, *args, **kwds) + assertRaisesRegex(exception, regex) - Like :meth:`assertRaises` but also tests that *regexp* matches - on the string representation of the raised exception. *regexp* may be + Like :meth:`assertRaises` but also tests that *regex* matches + on the string representation of the raised exception. *regex* may be a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. Examples:: - self.assertRaisesRegexp(ValueError, 'invalid literal for.*XYZ$', - int, 'XYZ') + self.assertRaisesRegex(ValueError, 'invalid literal for.*XYZ$', + int, 'XYZ') or:: - with self.assertRaisesRegexp(ValueError, 'literal'): + with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ') - .. versionadded:: 3.1 + .. versionadded:: 3.1 ``assertRaisesRegexp`` + .. versionchanged:: 3.2 + The method has been renamed to :meth:`assertRaisesRegex` .. method:: assertWarns(warning, callable, *args, **kwds) @@ -1015,21 +1017,21 @@ .. versionadded:: 3.2 - .. method:: assertWarnsRegexp(warning, regexp, callable, *args, **kwds) - assertWarnsRegexp(warning, regexp) + .. method:: assertWarnsRegex(warning, regex, callable, *args, **kwds) + assertWarnsRegex(warning, regex) - Like :meth:`assertWarns` but also tests that *regexp* matches on the - message of the triggered warning. *regexp* may be a regular expression + Like :meth:`assertWarns` but also tests that *regex* matches on the + message of the triggered warning. *regex* may be a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. Example:: - self.assertWarnsRegexp(DeprecationWarning, - r'legacy_function\(\) is deprecated', - legacy_function, 'XYZ') + self.assertWarnsRegex(DeprecationWarning, + r'legacy_function\(\) is deprecated', + legacy_function, 'XYZ') or:: - with self.assertWarnsRegexp(RuntimeWarning, 'unsafe frobnicating'): + with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'): frobnicate('/etc/passwd') .. versionadded:: 3.2 @@ -1059,11 +1061,11 @@ | :meth:`assertLessEqual(a, b) | ``a <= b`` | 3.1 | | ` | | | +---------------------------------------+--------------------------------+--------------+ - | :meth:`assertRegexpMatches(s, re) | ``regex.search(s)`` | 3.1 | - | ` | | | + | :meth:`assertRegex(s, re) | ``regex.search(s)`` | 3.1 | + | ` | | | +---------------------------------------+--------------------------------+--------------+ - | :meth:`assertNotRegexpMatches(s, re) | ``not regex.search(s)`` | 3.2 | - | ` | | | + | :meth:`assertNotRegex(s, re) | ``not regex.search(s)`` | 3.2 | + | ` | | | +---------------------------------------+--------------------------------+--------------+ | :meth:`assertDictContainsSubset(a, b) | all the key/value pairs | 3.1 | | ` | in `a` exist in `b` | | @@ -1108,17 +1110,19 @@ .. versionadded:: 3.1 - .. method:: assertRegexpMatches(text, regexp, msg=None) - assertNotRegexpMatches(text, regexp, msg=None) + .. method:: assertRegex(text, regex, msg=None) + assertNotRegex(text, regex, msg=None) - Test that a *regexp* search matches (or does not match) *text*. In case + Test that a *regex* search matches (or does not match) *text*. In case of failure, the error message will include the pattern and the *text* (or - the pattern and the part of *text* that unexpectedly matched). *regexp* + the pattern and the part of *text* that unexpectedly matched). *regex* may be a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. - .. versionadded:: 3.1 :meth:`~TestCase.assertRegexpMatches` - .. versionadded:: 3.2 :meth:`~TestCase.assertNotRegexpMatches` + .. versionadded:: 3.1 ``.assertRegexpMatches`` + .. versionchanged:: 3.2 + ``.assertRegexpMatches`` has been renamed to :meth:`.assertRegex` + .. versionadded:: 3.2 :meth:`.assertNotRegex` .. method:: assertDictContainsSubset(expected, actual, msg=None) @@ -1420,13 +1424,17 @@ :meth:`.assertRaises` failUnlessRaises :meth:`.assertAlmostEqual` failUnlessAlmostEqual assertAlmostEquals :meth:`.assertNotAlmostEqual` failIfAlmostEqual assertNotAlmostEquals + :meth:`.assertRegex` assertRegexpMatches + :meth:`.assertRaisesRegex` assertRaisesRegexp ============================== ====================== ====================== .. deprecated-removed:: 3.1 3.3 the fail* aliases listed in the second column. .. deprecated:: 3.2 the assert* aliases listed in the third column. - + .. deprecated:: 3.2 + ``assertRegexpMatches`` and ``assertRaisesRegexp`` have been renamed to + :meth:`.assertRegex` and :meth:`.assertRaisesRegex` .. _testsuite-objects: Modified: python/branches/py3k/Lib/test/test_abc.py ============================================================================== --- python/branches/py3k/Lib/test/test_abc.py (original) +++ python/branches/py3k/Lib/test/test_abc.py Wed Dec 1 03:32:32 2010 @@ -192,8 +192,8 @@ def test_register_non_class(self): class A(metaclass=abc.ABCMeta): pass - self.assertRaisesRegexp(TypeError, "Can only register classes", - A.register, 4) + self.assertRaisesRegex(TypeError, "Can only register classes", + A.register, 4) def test_registration_transitiveness(self): class A(metaclass=abc.ABCMeta): Modified: python/branches/py3k/Lib/test/test_asyncore.py ============================================================================== --- python/branches/py3k/Lib/test/test_asyncore.py (original) +++ python/branches/py3k/Lib/test/test_asyncore.py Wed Dec 1 03:32:32 2010 @@ -312,8 +312,8 @@ d = asyncore.dispatcher(socket.socket()) # make sure the error message no longer refers to the socket # object but the dispatcher instance instead - self.assertRaisesRegexp(AttributeError, 'dispatcher instance', - getattr, d, 'foo') + self.assertRaisesRegex(AttributeError, 'dispatcher instance', + getattr, d, 'foo') # cheap inheritance with the underlying socket is supposed # to still work but a DeprecationWarning is expected with warnings.catch_warnings(record=True) as w: Modified: python/branches/py3k/Lib/test/test_concurrent_futures.py ============================================================================== --- python/branches/py3k/Lib/test/test_concurrent_futures.py (original) +++ python/branches/py3k/Lib/test/test_concurrent_futures.py Wed Dec 1 03:32:32 2010 @@ -682,18 +682,18 @@ self.assertTrue(was_cancelled) def test_repr(self): - self.assertRegexpMatches(repr(PENDING_FUTURE), - '') - self.assertRegexpMatches(repr(RUNNING_FUTURE), - '') - self.assertRegexpMatches(repr(CANCELLED_FUTURE), - '') - self.assertRegexpMatches(repr(CANCELLED_AND_NOTIFIED_FUTURE), - '') - self.assertRegexpMatches( + self.assertRegex(repr(PENDING_FUTURE), + '') + self.assertRegex(repr(RUNNING_FUTURE), + '') + self.assertRegex(repr(CANCELLED_FUTURE), + '') + self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), + '') + self.assertRegex( repr(EXCEPTION_FUTURE), '') - self.assertRegexpMatches( + self.assertRegex( repr(SUCCESSFUL_FUTURE), '') Modified: python/branches/py3k/Lib/test/test_contextlib.py ============================================================================== --- python/branches/py3k/Lib/test/test_contextlib.py (original) +++ python/branches/py3k/Lib/test/test_contextlib.py Wed Dec 1 03:32:32 2010 @@ -231,7 +231,7 @@ def test_contextdecorator_with_exception(self): context = mycontext() - with self.assertRaisesRegexp(NameError, 'foo'): + with self.assertRaisesRegex(NameError, 'foo'): with context: raise NameError('foo') self.assertIsNotNone(context.exc) @@ -265,7 +265,7 @@ self.assertTrue(context.started) raise NameError('foo') - with self.assertRaisesRegexp(NameError, 'foo'): + with self.assertRaisesRegex(NameError, 'foo'): test() self.assertIsNotNone(context.exc) self.assertIs(context.exc[0], NameError) Modified: python/branches/py3k/Lib/test/test_dis.py ============================================================================== --- python/branches/py3k/Lib/test/test_dis.py (original) +++ python/branches/py3k/Lib/test/test_dis.py Wed Dec 1 03:32:32 2010 @@ -354,14 +354,14 @@ def test_code_info(self): self.maxDiff = 1000 for x, expected in self.test_pairs: - self.assertRegexpMatches(dis.code_info(x), expected) + self.assertRegex(dis.code_info(x), expected) def test_show_code(self): self.maxDiff = 1000 for x, expected in self.test_pairs: with captured_stdout() as output: dis.show_code(x) - self.assertRegexpMatches(output.getvalue(), expected+"\n") + self.assertRegex(output.getvalue(), expected+"\n") def test_main(): run_unittest(DisTests, CodeInfoTests) Modified: python/branches/py3k/Lib/test/test_memoryview.py ============================================================================== --- python/branches/py3k/Lib/test/test_memoryview.py (original) +++ python/branches/py3k/Lib/test/test_memoryview.py Wed Dec 1 03:32:32 2010 @@ -226,7 +226,7 @@ self.assertTrue(wr() is None, wr()) def _check_released(self, m, tp): - check = self.assertRaisesRegexp(ValueError, "released") + check = self.assertRaisesRegex(ValueError, "released") with check: bytes(m) with check: m.tobytes() with check: m.tolist() Modified: python/branches/py3k/Lib/test/test_runpy.py ============================================================================== --- python/branches/py3k/Lib/test/test_runpy.py (original) +++ python/branches/py3k/Lib/test/test_runpy.py Wed Dec 1 03:32:32 2010 @@ -329,7 +329,7 @@ def _check_import_error(self, script_name, msg): msg = re.escape(msg) - self.assertRaisesRegexp(ImportError, msg, run_path, script_name) + self.assertRaisesRegex(ImportError, msg, run_path, script_name) def test_basic_script(self): with temp_dir() as script_dir: @@ -403,7 +403,7 @@ script_name = self._make_test_script(script_dir, mod_name, source) zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) msg = "recursion depth exceeded" - self.assertRaisesRegexp(RuntimeError, msg, run_path, zip_name) + self.assertRaisesRegex(RuntimeError, msg, run_path, zip_name) Modified: python/branches/py3k/Lib/test/test_smtplib.py ============================================================================== --- python/branches/py3k/Lib/test/test_smtplib.py (original) +++ python/branches/py3k/Lib/test/test_smtplib.py Wed Dec 1 03:32:32 2010 @@ -319,12 +319,12 @@ self.assertEqual(self.output.getvalue(), mexpect) debugout = smtpd.DEBUGSTREAM.getvalue() sender = re.compile("^sender: foo at bar.com$", re.MULTILINE) - self.assertRegexpMatches(debugout, sender) + self.assertRegex(debugout, sender) for addr in ('John', 'Sally', 'Fred', 'root at localhost', 'warped at silly.walks.com'): to_addr = re.compile(r"^recips: .*'{}'.*$".format(addr), re.MULTILINE) - self.assertRegexpMatches(debugout, to_addr) + self.assertRegex(debugout, to_addr) def testSendMessageWithSomeAddresses(self): # Make sure nothing breaks if not all of the three 'to' headers exist @@ -347,11 +347,11 @@ self.assertEqual(self.output.getvalue(), mexpect) debugout = smtpd.DEBUGSTREAM.getvalue() sender = re.compile("^sender: foo at bar.com$", re.MULTILINE) - self.assertRegexpMatches(debugout, sender) + self.assertRegex(debugout, sender) for addr in ('John', 'Dinsdale'): to_addr = re.compile(r"^recips: .*'{}'.*$".format(addr), re.MULTILINE) - self.assertRegexpMatches(debugout, to_addr) + self.assertRegex(debugout, to_addr) class NonConnectingTests(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ssl.py (original) +++ python/branches/py3k/Lib/test/test_ssl.py Wed Dec 1 03:32:32 2010 @@ -185,17 +185,17 @@ def test_errors(self): sock = socket.socket() - self.assertRaisesRegexp(ValueError, + self.assertRaisesRegex(ValueError, "certfile must be specified", ssl.wrap_socket, sock, keyfile=CERTFILE) - self.assertRaisesRegexp(ValueError, + self.assertRaisesRegex(ValueError, "certfile must be specified for server-side operations", ssl.wrap_socket, sock, server_side=True) - self.assertRaisesRegexp(ValueError, + self.assertRaisesRegex(ValueError, "certfile must be specified for server-side operations", ssl.wrap_socket, sock, server_side=True, certfile="") s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) - self.assertRaisesRegexp(ValueError, "can't connect in server-side mode", + self.assertRaisesRegex(ValueError, "can't connect in server-side mode", s.connect, (HOST, 8080)) with self.assertRaises(IOError) as cm: with socket.socket() as sock: @@ -310,7 +310,7 @@ ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx.set_ciphers("ALL") ctx.set_ciphers("DEFAULT") - with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"): + with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): ctx.set_ciphers("^$:,;?*'dorothyx") @skip_if_broken_ubuntu_ssl @@ -358,24 +358,24 @@ with self.assertRaises(IOError) as cm: ctx.load_cert_chain(WRONGCERT) self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(BADCERT) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(EMPTYCERT) # Separate key and cert ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx.load_cert_chain(ONLYCERT, ONLYKEY) ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(ONLYCERT) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(ONLYKEY) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT) # Mismatching key and cert ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - with self.assertRaisesRegexp(ssl.SSLError, "key values mismatch"): + with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"): ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY) def test_load_verify_locations(self): @@ -389,7 +389,7 @@ with self.assertRaises(IOError) as cm: ctx.load_verify_locations(WRONGCERT) self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"): + with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_verify_locations(BADCERT) ctx.load_verify_locations(CERTFILE, CAPATH) ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH) @@ -434,8 +434,8 @@ # this should fail because we have no verification certs s = ssl.wrap_socket(socket.socket(socket.AF_INET), cert_reqs=ssl.CERT_REQUIRED) - self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed", - s.connect, ("svn.python.org", 443)) + self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", + s.connect, ("svn.python.org", 443)) s.close() # this should succeed because we specify the root cert @@ -469,7 +469,7 @@ # This should fail because we have no verification certs ctx.verify_mode = ssl.CERT_REQUIRED s = ctx.wrap_socket(socket.socket(socket.AF_INET)) - self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed", + self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", s.connect, ("svn.python.org", 443)) s.close() # This should succeed because we specify the root cert @@ -587,7 +587,7 @@ cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") s.connect(remote) # Error checking can happen at instantiation or when connecting - with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"): + with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): with socket.socket(socket.AF_INET) as sock: s = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx") @@ -1499,8 +1499,8 @@ c.settimeout(0.2) c.connect((host, port)) # Will attempt handshake and time out - self.assertRaisesRegexp(ssl.SSLError, "timed out", - ssl.wrap_socket, c) + self.assertRaisesRegex(ssl.SSLError, "timed out", + ssl.wrap_socket, c) finally: c.close() try: @@ -1508,8 +1508,8 @@ c = ssl.wrap_socket(c) c.settimeout(0.2) # Will attempt handshake and time out - self.assertRaisesRegexp(ssl.SSLError, "timed out", - c.connect, (host, port)) + self.assertRaisesRegex(ssl.SSLError, "timed out", + c.connect, (host, port)) finally: c.close() finally: Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Wed Dec 1 03:32:32 2010 @@ -1427,7 +1427,7 @@ # non-ascii format, ascii argument: ensure that PyUnicode_FromFormat() # raises an error for a non-ascii format string. - self.assertRaisesRegexp(ValueError, + self.assertRaisesRegex(ValueError, '^PyUnicode_FromFormatV\(\) expects an ASCII-encoded format ' 'string, got a non-ASCII byte: 0xe9$', format_unicode, b'unicode\xe9=%s', 'ascii') Modified: python/branches/py3k/Lib/test/test_urlparse.py ============================================================================== --- python/branches/py3k/Lib/test/test_urlparse.py (original) +++ python/branches/py3k/Lib/test/test_urlparse.py Wed Dec 1 03:32:32 2010 @@ -629,25 +629,25 @@ def test_mixed_types_rejected(self): # Several functions that process either strings or ASCII encoded bytes # accept multiple arguments. Check they reject mixed type input - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlparse("www.python.org", b"http") - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlparse(b"www.python.org", "http") - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlsplit("www.python.org", b"http") - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlsplit(b"www.python.org", "http") - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlunparse(( b"http", "www.python.org","","","","")) - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlunparse(("http", b"www.python.org","","","","")) - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlunsplit((b"http", "www.python.org","","","")) - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urlunsplit(("http", b"www.python.org","","","")) - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urljoin("http://python.org", b"http://python.org") - with self.assertRaisesRegexp(TypeError, "Cannot mix str"): + with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urljoin(b"http://python.org", "http://python.org") def _check_result_type(self, str_type): Modified: python/branches/py3k/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc.py Wed Dec 1 03:32:32 2010 @@ -715,8 +715,8 @@ t.encode_threshold = None t.fake_gzip = True p = xmlrpclib.ServerProxy(URL, transport=t) - cm = self.assertRaisesRegexp(xmlrpclib.ProtocolError, - re.compile(r"\b400\b")) + cm = self.assertRaisesRegex(xmlrpclib.ProtocolError, + re.compile(r"\b400\b")) with cm: p.pow(6, 8) Modified: python/branches/py3k/Lib/test/test_zlib.py ============================================================================== --- python/branches/py3k/Lib/test/test_zlib.py (original) +++ python/branches/py3k/Lib/test/test_zlib.py Wed Dec 1 03:32:32 2010 @@ -143,7 +143,7 @@ def test_incomplete_stream(self): # An useful error message is given x = zlib.compress(HAMLET_SCENE) - self.assertRaisesRegexp(zlib.error, + self.assertRaisesRegex(zlib.error, "Error -5 while decompressing data: incomplete or truncated stream", zlib.decompress, x[:-1]) Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Wed Dec 1 03:32:32 2010 @@ -94,7 +94,7 @@ class _AssertRaisesBaseContext(object): def __init__(self, expected, test_case, callable_obj=None, - expected_regexp=None): + expected_regex=None): self.expected = expected self.failureException = test_case.failureException if callable_obj is not None: @@ -104,9 +104,9 @@ self.obj_name = str(callable_obj) else: self.obj_name = None - if isinstance(expected_regexp, (bytes, str)): - expected_regexp = re.compile(expected_regexp) - self.expected_regexp = expected_regexp + if isinstance(expected_regex, (bytes, str)): + expected_regex = re.compile(expected_regex) + self.expected_regex = expected_regex class _AssertRaisesContext(_AssertRaisesBaseContext): @@ -132,13 +132,13 @@ return False # store exception, without traceback, for later retrieval self.exception = exc_value.with_traceback(None) - if self.expected_regexp is None: + if self.expected_regex is None: return True - expected_regexp = self.expected_regexp - if not expected_regexp.search(str(exc_value)): + expected_regex = self.expected_regex + if not expected_regex.search(str(exc_value)): raise self.failureException('"%s" does not match "%s"' % - (expected_regexp.pattern, str(exc_value))) + (expected_regex.pattern, str(exc_value))) return True @@ -172,8 +172,8 @@ continue if first_matching is None: first_matching = w - if (self.expected_regexp is not None and - not self.expected_regexp.search(str(w))): + if (self.expected_regex is not None and + not self.expected_regex.search(str(w))): continue # store warning for later retrieval self.warning = w @@ -183,7 +183,7 @@ # Now we simply try to choose a helpful failure message if first_matching is not None: raise self.failureException('"%s" does not match "%s"' % - (self.expected_regexp.pattern, str(first_matching))) + (self.expected_regex.pattern, str(first_matching))) if self.obj_name: raise self.failureException("{0} not triggered by {1}" .format(exc_name, self.obj_name)) @@ -689,24 +689,6 @@ raise self.failureException(msg) - def _deprecate(original_func): - def deprecated_func(*args, **kwargs): - warnings.warn( - 'Please use {0} instead.'.format(original_func.__name__), - DeprecationWarning, 2) - return original_func(*args, **kwargs) - return deprecated_func - - # The fail* methods can be removed in 3.3, the 5 assert* methods will - # have to stay around for a few more versions. See #9424. - failUnlessEqual = assertEquals = _deprecate(assertEqual) - failIfEqual = assertNotEquals = _deprecate(assertNotEqual) - failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual) - failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual) - failUnless = assert_ = _deprecate(assertTrue) - failUnlessRaises = _deprecate(assertRaises) - failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): """An equality assertion for ordered sequences (like lists and tuples). @@ -1095,27 +1077,27 @@ standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) self.fail(self._formatMessage(msg, standardMsg)) - def assertRaisesRegexp(self, expected_exception, expected_regexp, - callable_obj=None, *args, **kwargs): - """Asserts that the message in a raised exception matches a regexp. + def assertRaisesRegex(self, expected_exception, expected_regex, + callable_obj=None, *args, **kwargs): + """Asserts that the message in a raised exception matches a regex. Args: expected_exception: Exception class expected to be raised. - expected_regexp: Regexp (re pattern object or string) expected + expected_regex: Regex (re pattern object or string) expected to be found in error message. callable_obj: Function to be called. args: Extra args. kwargs: Extra kwargs. """ context = _AssertRaisesContext(expected_exception, self, callable_obj, - expected_regexp) + expected_regex) if callable_obj is None: return context with context: callable_obj(*args, **kwargs) - def assertWarnsRegexp(self, expected_warning, expected_regexp, - callable_obj=None, *args, **kwargs): + def assertWarnsRegex(self, expected_warning, expected_regex, + callable_obj=None, *args, **kwargs): """Asserts that the message in a triggered warning matches a regexp. Basic functioning is similar to assertWarns() with the addition that only warnings whose messages also match the regular expression @@ -1123,42 +1105,64 @@ Args: expected_warning: Warning class expected to be triggered. - expected_regexp: Regexp (re pattern object or string) expected + expected_regex: Regex (re pattern object or string) expected to be found in error message. callable_obj: Function to be called. args: Extra args. kwargs: Extra kwargs. """ context = _AssertWarnsContext(expected_warning, self, callable_obj, - expected_regexp) + expected_regex) if callable_obj is None: return context with context: callable_obj(*args, **kwargs) - def assertRegexpMatches(self, text, expected_regexp, msg=None): + def assertRegex(self, text, expected_regex, msg=None): """Fail the test unless the text matches the regular expression.""" - if isinstance(expected_regexp, (str, bytes)): - expected_regexp = re.compile(expected_regexp) - if not expected_regexp.search(text): - msg = msg or "Regexp didn't match" - msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text) + if isinstance(expected_regex, (str, bytes)): + expected_regex = re.compile(expected_regex) + if not expected_regex.search(text): + msg = msg or "Regex didn't match" + msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text) raise self.failureException(msg) - def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None): + def assertNotRegexMatches(self, text, unexpected_regex, msg=None): """Fail the test if the text matches the regular expression.""" - if isinstance(unexpected_regexp, (str, bytes)): - unexpected_regexp = re.compile(unexpected_regexp) - match = unexpected_regexp.search(text) + if isinstance(unexpected_regex, (str, bytes)): + unexpected_regex = re.compile(unexpected_regex) + match = unexpected_regex.search(text) if match: - msg = msg or "Regexp matched" + msg = msg or "Regex matched" msg = '%s: %r matches %r in %r' % (msg, text[match.start():match.end()], - unexpected_regexp.pattern, + unexpected_regex.pattern, text) raise self.failureException(msg) + def _deprecate(original_func): + def deprecated_func(*args, **kwargs): + warnings.warn( + 'Please use {0} instead.'.format(original_func.__name__), + DeprecationWarning, 2) + return original_func(*args, **kwargs) + return deprecated_func + + # The fail* methods can be removed in 3.3, the 5 assert* methods will + # have to stay around for a few more versions. See #9424. + failUnlessEqual = assertEquals = _deprecate(assertEqual) + failIfEqual = assertNotEquals = _deprecate(assertNotEqual) + failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual) + failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual) + failUnless = assert_ = _deprecate(assertTrue) + failUnlessRaises = _deprecate(assertRaises) + failIf = _deprecate(assertFalse) + assertRaisesRegexp = _deprecate(assertRaisesRegex) + assertRegexpMatches = _deprecate(assertRegex) + + + class FunctionTestCase(TestCase): """A test case that wraps a test function. Modified: python/branches/py3k/Lib/unittest/test/test_assertions.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_assertions.py (original) +++ python/branches/py3k/Lib/unittest/test/test_assertions.py Wed Dec 1 03:32:32 2010 @@ -92,15 +92,15 @@ else: self.fail("assertRaises() didn't let exception pass through") - def testAssertNotRegexpMatches(self): - self.assertNotRegexpMatches('Ala ma kota', r'r+') + def testAssertNotRegexMatches(self): + self.assertNotRegexMatches('Ala ma kota', r'r+') try: - self.assertNotRegexpMatches('Ala ma kota', r'k.t', 'Message') + self.assertNotRegexMatches('Ala ma kota', r'k.t', 'Message') except self.failureException as e: self.assertIn("'kot'", e.args[0]) self.assertIn('Message', e.args[0]) else: - self.fail('assertNotRegexpMatches should have failed.') + self.fail('assertNotRegexMatches should have failed.') class TestLongMessage(unittest.TestCase): @@ -153,15 +153,15 @@ test = self.testableTrue return getattr(test, methodName) - for i, expected_regexp in enumerate(errors): + for i, expected_regex in enumerate(errors): testMethod = getMethod(i) kwargs = {} withMsg = i % 2 if withMsg: kwargs = {"msg": "oops"} - with self.assertRaisesRegexp(self.failureException, - expected_regexp=expected_regexp): + with self.assertRaisesRegex(self.failureException, + expected_regex=expected_regex): testMethod(*args, **kwargs) def testAssertTrue(self): Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Wed Dec 1 03:32:32 2010 @@ -872,44 +872,44 @@ self.assertIsNotNone('DjZoPloGears on Rails') self.assertRaises(self.failureException, self.assertIsNotNone, None) - def testAssertRegexpMatches(self): - self.assertRegexpMatches('asdfabasdf', r'ab+') - self.assertRaises(self.failureException, self.assertRegexpMatches, + def testAssertRegex(self): + self.assertRegex('asdfabasdf', r'ab+') + self.assertRaises(self.failureException, self.assertRegex, 'saaas', r'aaaa') - def testAssertRaisesRegexp(self): + def testAssertRaisesRegex(self): class ExceptionMock(Exception): pass def Stub(): raise ExceptionMock('We expect') - self.assertRaisesRegexp(ExceptionMock, re.compile('expect$'), Stub) - self.assertRaisesRegexp(ExceptionMock, 'expect$', Stub) + self.assertRaisesRegex(ExceptionMock, re.compile('expect$'), Stub) + self.assertRaisesRegex(ExceptionMock, 'expect$', Stub) - def testAssertNotRaisesRegexp(self): - self.assertRaisesRegexp( + def testAssertNotRaisesRegex(self): + self.assertRaisesRegex( self.failureException, '^Exception not raised by $', - self.assertRaisesRegexp, Exception, re.compile('x'), + self.assertRaisesRegex, Exception, re.compile('x'), lambda: None) - self.assertRaisesRegexp( + self.assertRaisesRegex( self.failureException, '^Exception not raised by $', - self.assertRaisesRegexp, Exception, 'x', + self.assertRaisesRegex, Exception, 'x', lambda: None) - def testAssertRaisesRegexpMismatch(self): + def testAssertRaisesRegexMismatch(self): def Stub(): raise Exception('Unexpected') - self.assertRaisesRegexp( + self.assertRaisesRegex( self.failureException, r'"\^Expected\$" does not match "Unexpected"', - self.assertRaisesRegexp, Exception, '^Expected$', + self.assertRaisesRegex, Exception, '^Expected$', Stub) - self.assertRaisesRegexp( + self.assertRaisesRegex( self.failureException, r'"\^Expected\$" does not match "Unexpected"', - self.assertRaisesRegexp, Exception, + self.assertRaisesRegex, Exception, re.compile('^Expected$'), Stub) def testAssertRaisesExcValue(self): @@ -993,26 +993,26 @@ with self.assertWarns(DeprecationWarning): _runtime_warn() - def testAssertWarnsRegexpCallable(self): + def testAssertWarnsRegexCallable(self): def _runtime_warn(msg): warnings.warn(msg, RuntimeWarning) - self.assertWarnsRegexp(RuntimeWarning, "o+", - _runtime_warn, "foox") + self.assertWarnsRegex(RuntimeWarning, "o+", + _runtime_warn, "foox") # Failure when no warning is triggered with self.assertRaises(self.failureException): - self.assertWarnsRegexp(RuntimeWarning, "o+", - lambda: 0) + self.assertWarnsRegex(RuntimeWarning, "o+", + lambda: 0) # Failure when another warning is triggered with warnings.catch_warnings(): # Force default filter (in case tests are run with -We) warnings.simplefilter("default", RuntimeWarning) with self.assertRaises(self.failureException): - self.assertWarnsRegexp(DeprecationWarning, "o+", - _runtime_warn, "foox") + self.assertWarnsRegex(DeprecationWarning, "o+", + _runtime_warn, "foox") # Failure when message doesn't match with self.assertRaises(self.failureException): - self.assertWarnsRegexp(RuntimeWarning, "o+", - _runtime_warn, "barz") + self.assertWarnsRegex(RuntimeWarning, "o+", + _runtime_warn, "barz") # A little trickier: we ask RuntimeWarnings to be raised, and then # check for some of them. It is implementation-defined whether # non-matching RuntimeWarnings are simply re-raised, or produce a @@ -1020,15 +1020,15 @@ with warnings.catch_warnings(): warnings.simplefilter("error", RuntimeWarning) with self.assertRaises((RuntimeWarning, self.failureException)): - self.assertWarnsRegexp(RuntimeWarning, "o+", - _runtime_warn, "barz") + self.assertWarnsRegex(RuntimeWarning, "o+", + _runtime_warn, "barz") - def testAssertWarnsRegexpContext(self): - # Same as above, but with assertWarnsRegexp as a context manager + def testAssertWarnsRegexContext(self): + # Same as above, but with assertWarnsRegex as a context manager def _runtime_warn(msg): warnings.warn(msg, RuntimeWarning) _runtime_warn_lineno = inspect.getsourcelines(_runtime_warn)[1] - with self.assertWarnsRegexp(RuntimeWarning, "o+") as cm: + with self.assertWarnsRegex(RuntimeWarning, "o+") as cm: _runtime_warn("foox") self.assertIsInstance(cm.warning, RuntimeWarning) self.assertEqual(cm.warning.args[0], "foox") @@ -1036,18 +1036,18 @@ self.assertEqual(cm.lineno, _runtime_warn_lineno + 1) # Failure when no warning is triggered with self.assertRaises(self.failureException): - with self.assertWarnsRegexp(RuntimeWarning, "o+"): + with self.assertWarnsRegex(RuntimeWarning, "o+"): pass # Failure when another warning is triggered with warnings.catch_warnings(): # Force default filter (in case tests are run with -We) warnings.simplefilter("default", RuntimeWarning) with self.assertRaises(self.failureException): - with self.assertWarnsRegexp(DeprecationWarning, "o+"): + with self.assertWarnsRegex(DeprecationWarning, "o+"): _runtime_warn("foox") # Failure when message doesn't match with self.assertRaises(self.failureException): - with self.assertWarnsRegexp(RuntimeWarning, "o+"): + with self.assertWarnsRegex(RuntimeWarning, "o+"): _runtime_warn("barz") # A little trickier: we ask RuntimeWarnings to be raised, and then # check for some of them. It is implementation-defined whether @@ -1056,7 +1056,7 @@ with warnings.catch_warnings(): warnings.simplefilter("error", RuntimeWarning) with self.assertRaises((RuntimeWarning, self.failureException)): - with self.assertWarnsRegexp(RuntimeWarning, "o+"): + with self.assertWarnsRegex(RuntimeWarning, "o+"): _runtime_warn("barz") def testDeprecatedMethodNames(self): @@ -1078,7 +1078,9 @@ (self.assert_, (True,)), (self.failUnlessRaises, (TypeError, lambda _: 3.14 + 'spam')), (self.failIf, (False,)), - (self.assertSameElements, ([1, 1, 2, 3], [1, 2, 3])) + (self.assertSameElements, ([1, 1, 2, 3], [1, 2, 3])), + (self.assertRaisesRegexp, (KeyError, 'foo', lambda: {}['foo'])), + (self.assertRegexpMatches, ('bar', 'bar')), ) for meth, args in old: with self.assertWarns(DeprecationWarning): Modified: python/branches/py3k/Lib/unittest/test/test_discovery.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_discovery.py (original) +++ python/branches/py3k/Lib/unittest/test/test_discovery.py Wed Dec 1 03:32:32 2010 @@ -354,7 +354,7 @@ expected_dir = os.path.abspath('foo') msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. " "Is this module globally installed?" % (mod_dir, expected_dir)) - self.assertRaisesRegexp( + self.assertRaisesRegex( ImportError, '^%s$' % msg, loader.discover, start_dir='foo', pattern='foo.py' ) Modified: python/branches/py3k/Lib/unittest/test/test_loader.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_loader.py (original) +++ python/branches/py3k/Lib/unittest/test/test_loader.py Wed Dec 1 03:32:32 2010 @@ -186,7 +186,7 @@ self.assertEqual(suite.countTestCases(), 1) test = list(suite)[0] - self.assertRaisesRegexp(TypeError, "some failure", test.m) + self.assertRaisesRegex(TypeError, "some failure", test.m) ################################################################ ### /Tests for TestLoader.loadTestsFromModule() Modified: python/branches/py3k/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k/Lib/unittest/test/test_setups.py Wed Dec 1 03:32:32 2010 @@ -500,7 +500,7 @@ messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') for phase, msg in enumerate(messages): - with self.assertRaisesRegexp(Exception, msg): + with self.assertRaisesRegex(Exception, msg): suite.debug() if __name__ == '__main__': Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 1 03:32:32 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #10273: Rename `assertRegexpMatches` and `assertRaisesRegexp` to + `assertRegex` and `assertRaisesRegex`. + - Issue #10535: Enable silenced warnings in unittest by default. - Issue #9873: The URL parsing functions in urllib.parse now accept From python-checkins at python.org Wed Dec 1 04:45:41 2010 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Dec 2010 04:45:41 +0100 (CET) Subject: [Python-checkins] r86911 - in python/branches/py3k: Doc/library/functools.rst Lib/functools.py Lib/test/test_functools.py Message-ID: <20101201034541.46C66EEA2B@mail.python.org> Author: raymond.hettinger Date: Wed Dec 1 04:45:41 2010 New Revision: 86911 Log: Issue 10593: Adopt Nick's suggestion for an lru_cache with maxsize=None. Modified: python/branches/py3k/Doc/library/functools.rst python/branches/py3k/Lib/functools.py python/branches/py3k/Lib/test/test_functools.py Modified: python/branches/py3k/Doc/library/functools.rst ============================================================================== --- python/branches/py3k/Doc/library/functools.rst (original) +++ python/branches/py3k/Doc/library/functools.rst Wed Dec 1 04:45:41 2010 @@ -32,7 +32,7 @@ A compare function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one - argument and returns another value that indicates the position in the desired + argument and returns another value indicating the position in the desired collation sequence. Example:: @@ -51,10 +51,14 @@ Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable. + If *maxsize* is set to None, the LRU feature is disabled and the cache + can grow without bound. + To help measure the effectiveness of the cache and tune the *maxsize* parameter, the wrapped function is instrumented with a :func:`cache_info` function that returns a :term:`named tuple` showing *hits*, *misses*, - *maxsize* and *currsize*. + *maxsize* and *currsize*. In a multi-threaded environment, the hits + and misses are approximate. The decorator also provides a :func:`cache_clear` function for clearing or invalidating the cache. @@ -89,12 +93,25 @@ >>> print(get_pep.cache_info()) CacheInfo(hits=3, misses=8, maxsize=20, currsize=8) - .. versionadded:: 3.2 + Example of efficiently computing + `Fibonacci numbers `_ + using a cache to implement a + `dynamic programming `_ + technique:: + + @lru_cache(maxsize=None) + def fib(n): + if n < 2: + return n + return fib(n-1) + fib(n-2) - .. seealso:: + >>> print([fib(n) for n in range(16)]) + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] - Recipe for a `plain cache without the LRU feature - `_. + >>> print(fib.cache_info()) + CacheInfo(hits=28, misses=16, maxsize=None, currsize=16) + + .. versionadded:: 3.2 .. decorator:: total_ordering Modified: python/branches/py3k/Lib/functools.py ============================================================================== --- python/branches/py3k/Lib/functools.py (original) +++ python/branches/py3k/Lib/functools.py Wed Dec 1 04:45:41 2010 @@ -119,6 +119,9 @@ def lru_cache(maxsize=100): """Least-recently-used cache decorator. + If *maxsize* is set to None, the LRU features are disabled and the cache + can grow without bound. + Arguments to the cached function must be hashable. View the cache statistics named tuple (hits, misses, maxsize, currsize) with @@ -136,32 +139,51 @@ def decorating_function(user_function, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): - cache = OrderedDict() # ordered least recent to most recent - cache_popitem = cache.popitem - cache_renew = cache.move_to_end hits = misses = 0 kwd_mark = object() # separates positional and keyword args lock = Lock() - @wraps(user_function) - def wrapper(*args, **kwds): - nonlocal hits, misses - key = args - if kwds: - key += (kwd_mark,) + tuple(sorted(kwds.items())) - try: - with lock: + if maxsize is None: + cache = dict() # simple cache without ordering or size limit + + @wraps(user_function) + def wrapper(*args, **kwds): + nonlocal hits, misses + key = args + if kwds: + key += (kwd_mark,) + tuple(sorted(kwds.items())) + try: result = cache[key] - cache_renew(key) # record recent use of this key hits += 1 - except KeyError: - result = user_function(*args, **kwds) - with lock: - cache[key] = result # record recent use of this key + except KeyError: + result = user_function(*args, **kwds) + cache[key] = result misses += 1 - if len(cache) > maxsize: - cache_popitem(0) # purge least recently used cache entry - return result + return result + else: + cache = OrderedDict() # ordered least recent to most recent + cache_popitem = cache.popitem + cache_renew = cache.move_to_end + + @wraps(user_function) + def wrapper(*args, **kwds): + nonlocal hits, misses + key = args + if kwds: + key += (kwd_mark,) + tuple(sorted(kwds.items())) + try: + with lock: + result = cache[key] + cache_renew(key) # record recent use of this key + hits += 1 + except KeyError: + result = user_function(*args, **kwds) + with lock: + cache[key] = result # record recent use of this key + misses += 1 + if len(cache) > maxsize: + cache_popitem(0) # purge least recently used cache entry + return result def cache_info(): """Report cache statistics""" Modified: python/branches/py3k/Lib/test/test_functools.py ============================================================================== --- python/branches/py3k/Lib/test/test_functools.py (original) +++ python/branches/py3k/Lib/test/test_functools.py Wed Dec 1 04:45:41 2010 @@ -586,6 +586,20 @@ self.assertEqual(misses, 4) self.assertEqual(currsize, 2) + def test_lru_with_maxsize_none(self): + @functools.lru_cache(maxsize=None) + def fib(n): + if n < 2: + return n + return fib(n-1) + fib(n-2) + self.assertEqual([fib(n) for n in range(16)], + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]) + self.assertEqual(fib.cache_info(), + functools._CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)) + fib.cache_clear() + self.assertEqual(fib.cache_info(), + functools._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)) + def test_main(verbose=None): test_classes = ( TestPartial, From solipsis at pitrou.net Wed Dec 1 04:50:58 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 01 Dec 2010 04:50:58 +0100 Subject: [Python-checkins] Daily py3k reference leaks (r86909): sum=0 Message-ID: py3k results for svn r86909 (hg cset 502eca1dc051) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogT8QCJk', '-x'] From python-checkins at python.org Wed Dec 1 11:49:19 2010 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Dec 2010 11:49:19 +0100 (CET) Subject: [Python-checkins] r86912 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20101201104919.99309EE99C@mail.python.org> Author: raymond.hettinger Date: Wed Dec 1 11:49:19 2010 New Revision: 86912 Log: Add recipe to itertools doc. Modified: python/branches/py3k/Doc/library/itertools.rst Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Wed Dec 1 11:49:19 2010 @@ -653,6 +653,14 @@ pending -= 1 nexts = cycle(islice(nexts, pending)) + def accumulate(iterable): + 'Emit a running total' + # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 + total = 0 + for element in iterable: + total += element + yield total + def partition(pred, iterable): 'Use a predicate to partition entries into false entries and true entries' # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 From python-checkins at python.org Wed Dec 1 16:32:44 2010 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Dec 2010 16:32:44 +0100 (CET) Subject: [Python-checkins] r86913 - python/branches/py3k/Doc/reference/expressions.rst Message-ID: <20101201153244.298D7EE9A5@mail.python.org> Author: georg.brandl Date: Wed Dec 1 16:32:43 2010 New Revision: 86913 Log: Add missing word, and add a better reference to the actual function. Modified: python/branches/py3k/Doc/reference/expressions.rst Modified: python/branches/py3k/Doc/reference/expressions.rst ============================================================================== --- python/branches/py3k/Doc/reference/expressions.rst (original) +++ python/branches/py3k/Doc/reference/expressions.rst Wed Dec 1 16:32:43 2010 @@ -1322,8 +1322,8 @@ true numerically due to roundoff. For example, and assuming a platform on which a Python float is an IEEE 754 double-precision number, in order that ``-1e-100 % 1e100`` have the same sign as ``1e100``, the computed result is ``-1e-100 + - 1e100``, which is numerically exactly equal to ``1e100``. Function :func:`fmod` - in the :mod:`math` module returns a result whose sign matches the sign of the + 1e100``, which is numerically exactly equal to ``1e100``. The function + :func:`math.fmod` returns a result whose sign matches the sign of the first argument instead, and so returns ``-1e-100`` in this case. Which approach is more appropriate depends on the application. @@ -1344,7 +1344,8 @@ the :keyword:`is` operator, like those involving comparisons between instance methods, or constants. Check their documentation for more info. -.. [#] The ``%`` is also used for string formatting; the same precedence applies. +.. [#] The ``%`` operator is also used for string formatting; the same + precedence applies. .. [#] The power operator ``**`` binds less tightly than an arithmetic or bitwise unary operator on its right, that is, ``2**-1`` is ``0.5``. From python-checkins at python.org Wed Dec 1 16:36:33 2010 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Dec 2010 16:36:33 +0100 (CET) Subject: [Python-checkins] r86914 - python/branches/py3k/Doc/c-api/list.rst Message-ID: <20101201153633.8B748F5C5@mail.python.org> Author: georg.brandl Date: Wed Dec 1 16:36:33 2010 New Revision: 86914 Log: #10594: fix parameter names in PyList API docs. Modified: python/branches/py3k/Doc/c-api/list.rst Modified: python/branches/py3k/Doc/c-api/list.rst ============================================================================== --- python/branches/py3k/Doc/c-api/list.rst (original) +++ python/branches/py3k/Doc/c-api/list.rst Wed Dec 1 16:36:33 2010 @@ -37,7 +37,7 @@ .. note:: - If *length* is greater than zero, the returned list object's items are + If *len* is greater than zero, the returned list object's items are set to ``NULL``. Thus you cannot use abstract API functions such as :c:func:`PySequence_SetItem` or expose the object to Python code before setting all items to a real object with :c:func:`PyList_SetItem`. @@ -58,9 +58,9 @@ .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - Return the object at position *pos* in the list pointed to by *p*. The + Return the object at position *index* in the list pointed to by *list*. The position must be positive, indexing from the end of the list is not - supported. If *pos* is out of bounds, return *NULL* and set an + supported. If *index* is out of bounds, return *NULL* and set an :exc:`IndexError` exception. From python-checkins at python.org Wed Dec 1 16:44:25 2010 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Dec 2010 16:44:25 +0100 (CET) Subject: [Python-checkins] r86915 - python/branches/py3k/Doc/library/unittest.rst Message-ID: <20101201154425.CD388EE9A8@mail.python.org> Author: georg.brandl Date: Wed Dec 1 16:44:25 2010 New Revision: 86915 Log: Fix some markup and style in the unittest docs. Modified: python/branches/py3k/Doc/library/unittest.rst Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Wed Dec 1 16:44:25 2010 @@ -978,9 +978,10 @@ with self.assertRaisesRegex(ValueError, 'literal'): int('XYZ') - .. versionadded:: 3.1 ``assertRaisesRegexp`` + .. versionadded:: 3.1 + under the name ``assertRaisesRegexp``. .. versionchanged:: 3.2 - The method has been renamed to :meth:`assertRaisesRegex` + Renamed to :meth:`assertRaisesRegex`. .. method:: assertWarns(warning, callable, *args, **kwds) @@ -1091,9 +1092,9 @@ Supplying both *delta* and *places* raises a ``TypeError``. .. versionchanged:: 3.2 - assertAlmostEqual automatically considers almost equal objects that compare equal. - assertNotAlmostEqual automatically fails if the objects compare equal. - Added the ``delta`` keyword argument. + :meth:`assertAlmostEqual` automatically considers almost equal objects + that compare equal. :meth:`assertNotAlmostEqual` automatically fails + if the objects compare equal. Added the *delta* keyword argument. .. method:: assertGreater(first, second, msg=None) @@ -1119,10 +1120,13 @@ may be a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. - .. versionadded:: 3.1 ``.assertRegexpMatches`` + .. versionadded:: 3.1 + under the name ``assertRegexpMatches``. .. versionchanged:: 3.2 - ``.assertRegexpMatches`` has been renamed to :meth:`.assertRegex` - .. versionadded:: 3.2 :meth:`.assertNotRegex` + The method ``assertRegexpMatches()`` has been renamed to + :meth:`.assertRegex`. + .. versionadded:: 3.2 + :meth:`.assertNotRegex`. .. method:: assertDictContainsSubset(expected, actual, msg=None) @@ -1359,11 +1363,11 @@ returns the first line of the test method's docstring, if available, or ``None``. - .. versionchanged:: 3.1,3.2 + .. versionchanged:: 3.1 In 3.1 this was changed to add the test name to the short description - even in the presence of a docstring. This caused compatibility issues + even in the presence of a docstring. This caused compatibility issues with unittest extensions and adding the test name was moved to the - :class:`TextTestResult`. + :class:`TextTestResult` in Python 3.2. .. method:: addCleanup(function, *args, **kwargs) @@ -1715,7 +1719,6 @@ The total number of tests run so far. - .. attribute:: buffer If set to true, ``sys.stdout`` and ``sys.stderr`` will be buffered in between :meth:`startTest` and :meth:`stopTest` being called. Collected output will @@ -1881,9 +1884,12 @@ stream, descriptions, verbosity - .. versionchanged:: 3.2 Added the ``warnings`` argument + .. versionchanged:: 3.2 + Added the ``warnings`` argument. -.. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None) +.. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, \ + testLoader=unittest.loader.defaultTestLoader, exit=True, verbosity=1, \ + failfast=None, catchbreak=None, buffer=None, warnings=None) A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. The simplest use for this function is to @@ -1928,10 +1934,8 @@ load_tests Protocol ################### - .. versionadded:: 3.2 - Modules or packages can customize how tests are loaded from them during normal test runs or test discovery by implementing a function called ``load_tests``. @@ -2078,6 +2082,8 @@ Signal Handling --------------- +.. versionadded:: 3.2 + The :option:`-c/--catch ` command-line option to unittest, along with the ``catchbreak`` parameter to :func:`unittest.main()`, provide more friendly handling of control-C during a test run. With catch break @@ -2103,7 +2109,6 @@ (usually in response to the user pressing control-c) all registered results have :meth:`~TestResult.stop` called. - .. versionadded:: 3.2 .. function:: registerResult(result) @@ -2115,7 +2120,6 @@ handling is not enabled, so test frameworks can unconditionally register all results they create independently of whether or not handling is enabled. - .. versionadded:: 3.2 .. function:: removeResult(result) @@ -2123,7 +2127,6 @@ :meth:`~TestResult.stop` will no longer be called on that result object in response to a control-c. - .. versionadded:: 3.2 .. function:: removeHandler(function=None) @@ -2134,6 +2137,3 @@ @unittest.removeHandler def test_signal_handling(self): ... - - .. versionadded:: 3.2 - From python-checkins at python.org Wed Dec 1 21:05:49 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Wed, 1 Dec 2010 21:05:49 +0100 (CET) Subject: [Python-checkins] r86916 - in python/branches/py3k: Lib/test/test_functools.py Lib/test/test_inspect.py Misc/NEWS Modules/_functoolsmodule.c Message-ID: <20101201200549.BD863EE981@mail.python.org> Author: alexander.belopolsky Date: Wed Dec 1 21:05:49 2010 New Revision: 86916 Log: Issue #4113: Added custom __repr__ method to functools.partial. Modified: python/branches/py3k/Lib/test/test_functools.py python/branches/py3k/Lib/test/test_inspect.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_functoolsmodule.c Modified: python/branches/py3k/Lib/test/test_functools.py ============================================================================== --- python/branches/py3k/Lib/test/test_functools.py (original) +++ python/branches/py3k/Lib/test/test_functools.py Wed Dec 1 21:05:49 2010 @@ -146,6 +146,32 @@ join = self.thetype(''.join) self.assertEqual(join(data), '0123456789') + def test_repr(self): + args = (object(), object()) + args_repr = ', '.join(repr(a) for a in args) + kwargs = {'a': object(), 'b': object()} + kwargs_repr = ', '.join("%s=%r" % (k, v) for k, v in kwargs.items()) + if self.thetype is functools.partial: + name = 'functools.partial' + else: + name = self.thetype.__name__ + + f = self.thetype(capture) + self.assertEqual('{}({!r})'.format(name, capture), + repr(f)) + + f = self.thetype(capture, *args) + self.assertEqual('{}({!r}, {})'.format(name, capture, args_repr), + repr(f)) + + f = self.thetype(capture, **kwargs) + self.assertEqual('{}({!r}, {})'.format(name, capture, kwargs_repr), + repr(f)) + + f = self.thetype(capture, *args, **kwargs) + self.assertEqual('{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr), + repr(f)) + def test_pickle(self): f = self.thetype(signature, 'asdf', bar=True) f.add_something_to__dict__ = True @@ -163,6 +189,9 @@ thetype = PythonPartial + # the python version hasn't a nice repr + def test_repr(self): pass + # the python version isn't picklable def test_pickle(self): pass Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Wed Dec 1 21:05:49 2010 @@ -12,6 +12,7 @@ from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 +from test import inspect_fodder3 as mod3 # C module for test_findsource_binary import unicodedata @@ -388,6 +389,12 @@ self.assertEqual(inspect.findsource(co), (lines,0)) self.assertEqual(inspect.getsource(co), lines[0]) +class TestNoEOF(GetSourceBase): + fodderFile = mod3 + + def test_class(self): + self.assertSourceEqual(mod3.X, 1, 2) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 1 21:05:49 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #4113: Added custom ``__repr__`` method to ``functools.partial``. + Original patch by Daniel Urban. + - Issue #10273: Rename `assertRegexpMatches` and `assertRaisesRegexp` to `assertRegex` and `assertRaisesRegex`. Modified: python/branches/py3k/Modules/_functoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/_functoolsmodule.c (original) +++ python/branches/py3k/Modules/_functoolsmodule.c Wed Dec 1 21:05:49 2010 @@ -196,6 +196,48 @@ {NULL} /* Sentinel */ }; +static PyObject * +partial_repr(partialobject *pto) +{ + PyObject *result; + PyObject *arglist; + PyObject *tmp; + Py_ssize_t i, n; + + arglist = PyUnicode_FromString(""); + if (arglist == NULL) { + return NULL; + } + /* Pack positional arguments */ + assert (PyTuple_Check(pto->args)); + n = PyTuple_GET_SIZE(pto->args); + for (i = 0; i < n; i++) { + tmp = PyUnicode_FromFormat("%U, %R", arglist, + PyTuple_GET_ITEM(pto->args, i)); + Py_DECREF(arglist); + if (tmp == NULL) + return NULL; + arglist = tmp; + } + /* Pack keyword arguments */ + assert (pto->kw == Py_None || PyDict_Check(pto->kw)); + if (pto->kw != Py_None) { + PyObject *key, *value; + for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { + tmp = PyUnicode_FromFormat("%U, %U=%R", arglist, + key, value); + Py_DECREF(arglist); + if (tmp == NULL) + return NULL; + arglist = tmp; + } + } + result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name, + pto->fn, arglist); + Py_DECREF(arglist); + return result; +} + /* Pickle strategy: __reduce__ by itself doesn't support getting kwargs in the unpickle operation so we define a __setstate__ that replaces all the information @@ -254,7 +296,7 @@ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc)partial_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ From python-checkins at python.org Wed Dec 1 22:55:40 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Wed, 1 Dec 2010 22:55:40 +0100 (CET) Subject: [Python-checkins] r86917 - python/branches/py3k/Lib/test/test_inspect.py Message-ID: <20101201215540.52D68EE991@mail.python.org> Author: alexander.belopolsky Date: Wed Dec 1 22:55:40 2010 New Revision: 86917 Log: Reverted unintended change from r86916 Modified: python/branches/py3k/Lib/test/test_inspect.py Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Wed Dec 1 22:55:40 2010 @@ -12,7 +12,6 @@ from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 -from test import inspect_fodder3 as mod3 # C module for test_findsource_binary import unicodedata @@ -389,12 +388,6 @@ self.assertEqual(inspect.findsource(co), (lines,0)) self.assertEqual(inspect.getsource(co), lines[0]) -class TestNoEOF(GetSourceBase): - fodderFile = mod3 - - def test_class(self): - self.assertSourceEqual(mod3.X, 1, 2) - # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] From python-checkins at python.org Wed Dec 1 23:48:01 2010 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Dec 2010 23:48:01 +0100 (CET) Subject: [Python-checkins] r86918 - in python/branches/py3k: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: <20101201224801.0500BEE992@mail.python.org> Author: raymond.hettinger Date: Wed Dec 1 23:48:00 2010 New Revision: 86918 Log: Add itertools.accumulate(). Modified: python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Wed Dec 1 23:48:00 2010 @@ -56,6 +56,23 @@ return prod(range(1, n+1)) class TestBasicOps(unittest.TestCase): + + def test_accumulate(self): + self.assertEqual(list(accumulate(range(10))), # one positional arg + [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) + self.assertEqual(list(accumulate(range(10), 100)), # two positional args + [100, 101, 103, 106, 110, 115, 121, 128, 136, 145]) + self.assertEqual(list(accumulate(iterable=range(10), start=100)), # kw args + [100, 101, 103, 106, 110, 115, 121, 128, 136, 145]) + for typ in int, complex, Decimal, Fraction: # multiple types + self.assertEqual(list(accumulate(range(10), typ(0))), + list(map(typ, [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]))) + self.assertEqual(list(accumulate([])), []) # empty iterable + self.assertRaises(TypeError, accumulate, range(10), 0, 5) # too many args + self.assertRaises(TypeError, accumulate) # too few args + self.assertRaises(TypeError, accumulate, range(10), x=7) # unexpected kwd args + self.assertRaises(TypeError, list, accumulate([1, []])) # args that don't add + def test_chain(self): def chain2(*iterables): @@ -932,6 +949,9 @@ class TestExamples(unittest.TestCase): + def test_accumlate(self): + self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15]) + def test_chain(self): self.assertEqual(''.join(chain('ABC', 'DEF')), 'ABCDEF') @@ -1019,6 +1039,10 @@ next(iterator) del container, iterator + def test_accumulate(self): + a = [] + self.makecycle(accumulate([1,2,a,3]), a) + def test_chain(self): a = [] self.makecycle(chain(a), a) @@ -1188,6 +1212,17 @@ class TestVariousIteratorArgs(unittest.TestCase): + def test_accumulate(self): + s = [1,2,3,4,5] + r = [1,3,6,10,15] + n = len(s) + for g in (G, I, Ig, L, R): + self.assertEqual(list(accumulate(g(s))), r) + self.assertEqual(list(accumulate(S(s))), []) + self.assertRaises(TypeError, accumulate, X(s)) + self.assertRaises(TypeError, accumulate, N(s)) + self.assertRaises(ZeroDivisionError, list, accumulate(E(s))) + def test_chain(self): for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): for g in (G, I, Ig, S, L, R): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 1 23:48:00 2010 @@ -46,6 +46,8 @@ Library ------- +- Added itertools.accumulate(). + - Issue #4113: Added custom ``__repr__`` method to ``functools.partial``. Original patch by Daniel Urban. Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Wed Dec 1 23:48:00 2010 @@ -2584,6 +2584,146 @@ PyObject_GC_Del, /* tp_free */ }; +/* accumulate object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *total; + PyObject *it; +} accumulateobject; + +static PyTypeObject accumulate_type; + +static PyObject * +accumulate_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static char *kwargs[] = {"iterable", "start", NULL}; + PyObject *iterable; + PyObject *it; + PyObject *start = NULL; + accumulateobject *lz; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:accumulate", + kwargs, &iterable, &start)) + return NULL; + + /* Get iterator. */ + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + /* Default start value */ + if (start == NULL) { + start = PyLong_FromLong(0); + if (start == NULL) { + Py_DECREF(it); + return NULL; + } + } else { + Py_INCREF(start); + } + + /* create accumulateobject structure */ + lz = (accumulateobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + Py_DECREF(start); + return NULL; + } + + lz->total = start; + lz->it = it; + return (PyObject *)lz; +} + +static void +accumulate_dealloc(accumulateobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->total); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->total); + return 0; +} + +static PyObject * +accumulate_next(accumulateobject *lz) +{ + PyObject *val, *oldtotal, *newtotal; + + val = PyIter_Next(lz->it); + if (val == NULL) + return NULL; + + newtotal = PyNumber_Add(lz->total, val); + Py_DECREF(val); + if (newtotal == NULL) + return NULL; + + oldtotal = lz->total; + lz->total = newtotal; + Py_DECREF(oldtotal); + + Py_INCREF(newtotal); + return newtotal; +} + +PyDoc_STRVAR(accumulate_doc, +"accumulate(iterable, start=0) --> accumulate object\n\ +\n\ +Return series of accumulated sums."); + +static PyTypeObject accumulate_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.accumulate", /* tp_name */ + sizeof(accumulateobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)accumulate_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + accumulate_doc, /* tp_doc */ + (traverseproc)accumulate_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)accumulate_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + accumulate_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + /* compress object ************************************************************/ @@ -3496,6 +3636,7 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ \n\ Iterators terminating on the shortest input sequence:\n\ +accumulate(p, start=0) --> p0, p0+p1, p0+p1+p2\n\ chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\ compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ @@ -3541,6 +3682,7 @@ PyObject *m; char *name; PyTypeObject *typelist[] = { + &accumulate_type, &combinations_type, &cwr_type, &cycle_type, From python-checkins at python.org Wed Dec 1 23:50:36 2010 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Dec 2010 23:50:36 +0100 (CET) Subject: [Python-checkins] r86919 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20101201225036.46F93EE99C@mail.python.org> Author: raymond.hettinger Date: Wed Dec 1 23:50:36 2010 New Revision: 86919 Log: Add itertools.accumulate(). Modified: python/branches/py3k/Doc/library/itertools.rst Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Wed Dec 1 23:50:36 2010 @@ -2,14 +2,14 @@ ======================================================================= .. module:: itertools - :synopsis: Functions creating iterators for efficient looping. + :synopsis: Functions creating iterators for efficient looping. .. moduleauthor:: Raymond Hettinger .. sectionauthor:: Raymond Hettinger .. testsetup:: - from itertools import * + from itertools import * This module implements a number of :term:`iterator` building blocks inspired @@ -46,6 +46,7 @@ ==================== ============================ ================================================= ============================================================= Iterator Arguments Results Example ==================== ============================ ================================================= ============================================================= +:func:`accumulate` p[, start=0] p0, p0+p1, p0+p1+p2 ... ` ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` @@ -83,47 +84,62 @@ streams of infinite length, so they should only be accessed by functions or loops that truncate the stream. +.. function:: accumulate(iterable, start=0) + + Make an iterator that returns accumulated sums plus the value of the *start* + parameter (which defaults to :const:`0`). Elements may be any addable type + including :class:`Decimal` or :class:`Fraction`. Equivalent to:: + + def accumulate(iterable, start=0): + 'Return running totals' + # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 + total = start + for element in iterable: + total += element + yield total + + .. versionadded:: 3.2 .. function:: chain(*iterables) - Make an iterator that returns elements from the first iterable until it is - exhausted, then proceeds to the next iterable, until all of the iterables are - exhausted. Used for treating consecutive sequences as a single sequence. - Equivalent to:: - - def chain(*iterables): - # chain('ABC', 'DEF') --> A B C D E F - for it in iterables: - for element in it: - yield element + Make an iterator that returns elements from the first iterable until it is + exhausted, then proceeds to the next iterable, until all of the iterables are + exhausted. Used for treating consecutive sequences as a single sequence. + Equivalent to:: + + def chain(*iterables): + # chain('ABC', 'DEF') --> A B C D E F + for it in iterables: + for element in it: + yield element .. classmethod:: chain.from_iterable(iterable) - Alternate constructor for :func:`chain`. Gets chained inputs from a - single iterable argument that is evaluated lazily. Equivalent to:: + Alternate constructor for :func:`chain`. Gets chained inputs from a + single iterable argument that is evaluated lazily. Equivalent to:: - @classmethod - def from_iterable(iterables): - # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F - for it in iterables: - for element in it: - yield element + @classmethod + def from_iterable(iterables): + # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F + for it in iterables: + for element in it: + yield element .. function:: combinations(iterable, r) - Return *r* length subsequences of elements from the input *iterable*. + Return *r* length subsequences of elements from the input *iterable*. - Combinations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the combination tuples will be produced - in sorted order. + Combinations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the combination tuples will be produced + in sorted order. - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat - values in each combination. + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, there will be no repeat + values in each combination. - Equivalent to:: + Equivalent to:: def combinations(iterable, r): # combinations('ABCD', 2) --> AB AC AD BC BD CD @@ -145,9 +161,9 @@ indices[j] = indices[j-1] + 1 yield tuple(pool[i] for i in indices) - The code for :func:`combinations` can be also expressed as a subsequence - of :func:`permutations` after filtering entries where the elements are not - in sorted order (according to their position in the input pool):: + The code for :func:`combinations` can be also expressed as a subsequence + of :func:`permutations` after filtering entries where the elements are not + in sorted order (according to their position in the input pool):: def combinations(iterable, r): pool = tuple(iterable) @@ -156,23 +172,23 @@ if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) - The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n`` - or zero when ``r > n``. + The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n`` + or zero when ``r > n``. .. function:: combinations_with_replacement(iterable, r) - Return *r* length subsequences of elements from the input *iterable* - allowing individual elements to be repeated more than once. + Return *r* length subsequences of elements from the input *iterable* + allowing individual elements to be repeated more than once. - Combinations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the combination tuples will be produced - in sorted order. - - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, the generated combinations - will also be unique. + Combinations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the combination tuples will be produced + in sorted order. + + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, the generated combinations + will also be unique. - Equivalent to:: + Equivalent to:: def combinations_with_replacement(iterable, r): # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC @@ -191,9 +207,9 @@ indices[i:] = [indices[i] + 1] * (r - i) yield tuple(pool[i] for i in indices) - The code for :func:`combinations_with_replacement` can be also expressed as - a subsequence of :func:`product` after filtering entries where the elements - are not in sorted order (according to their position in the input pool):: + The code for :func:`combinations_with_replacement` can be also expressed as + a subsequence of :func:`product` after filtering entries where the elements + are not in sorted order (according to their position in the input pool):: def combinations_with_replacement(iterable, r): pool = tuple(iterable) @@ -202,196 +218,196 @@ if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) - The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``. + The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``. - .. versionadded:: 3.1 + .. versionadded:: 3.1 .. function:: compress(data, selectors) - Make an iterator that filters elements from *data* returning only those that - have a corresponding element in *selectors* that evaluates to ``True``. - Stops when either the *data* or *selectors* iterables has been exhausted. - Equivalent to:: - - def compress(data, selectors): - # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F - return (d for d, s in zip(data, selectors) if s) + Make an iterator that filters elements from *data* returning only those that + have a corresponding element in *selectors* that evaluates to ``True``. + Stops when either the *data* or *selectors* iterables has been exhausted. + Equivalent to:: + + def compress(data, selectors): + # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F + return (d for d, s in zip(data, selectors) if s) - .. versionadded:: 3.1 + .. versionadded:: 3.1 .. function:: count(start=0, step=1) - Make an iterator that returns evenly spaced values starting with *n*. Often - used as an argument to :func:`map` to generate consecutive data points. - Also, used with :func:`zip` to add sequence numbers. Equivalent to:: - - def count(start=0, step=1): - # count(10) --> 10 11 12 13 14 ... - # count(2.5, 0.5) -> 3.5 3.0 4.5 ... - n = start - while True: - yield n - n += step - - When counting with floating point numbers, better accuracy can sometimes be - achieved by substituting multiplicative code such as: ``(start + step * i - for i in count())``. + Make an iterator that returns evenly spaced values starting with *n*. Often + used as an argument to :func:`map` to generate consecutive data points. + Also, used with :func:`zip` to add sequence numbers. Equivalent to:: + + def count(start=0, step=1): + # count(10) --> 10 11 12 13 14 ... + # count(2.5, 0.5) -> 3.5 3.0 4.5 ... + n = start + while True: + yield n + n += step + + When counting with floating point numbers, better accuracy can sometimes be + achieved by substituting multiplicative code such as: ``(start + step * i + for i in count())``. - .. versionchanged:: 3.1 - Added *step* argument and allowed non-integer arguments. + .. versionchanged:: 3.1 + Added *step* argument and allowed non-integer arguments. .. function:: cycle(iterable) - Make an iterator returning elements from the iterable and saving a copy of each. - When the iterable is exhausted, return elements from the saved copy. Repeats - indefinitely. Equivalent to:: - - def cycle(iterable): - # cycle('ABCD') --> A B C D A B C D A B C D ... - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: + Make an iterator returning elements from the iterable and saving a copy of each. + When the iterable is exhausted, return elements from the saved copy. Repeats + indefinitely. Equivalent to:: + + def cycle(iterable): + # cycle('ABCD') --> A B C D A B C D A B C D ... + saved = [] + for element in iterable: + yield element + saved.append(element) + while saved: + for element in saved: yield element - Note, this member of the toolkit may require significant auxiliary storage - (depending on the length of the iterable). + Note, this member of the toolkit may require significant auxiliary storage + (depending on the length of the iterable). .. function:: dropwhile(predicate, iterable) - Make an iterator that drops elements from the iterable as long as the predicate - is true; afterwards, returns every element. Note, the iterator does not produce - *any* output until the predicate first becomes false, so it may have a lengthy - start-up time. Equivalent to:: - - def dropwhile(predicate, iterable): - # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x + Make an iterator that drops elements from the iterable as long as the predicate + is true; afterwards, returns every element. Note, the iterator does not produce + *any* output until the predicate first becomes false, so it may have a lengthy + start-up time. Equivalent to:: + + def dropwhile(predicate, iterable): + # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 + iterable = iter(iterable) + for x in iterable: + if not predicate(x): + yield x + break + for x in iterable: + yield x .. function:: filterfalse(predicate, iterable) - Make an iterator that filters elements from iterable returning only those for - which the predicate is ``False``. If *predicate* is ``None``, return the items - that are false. Equivalent to:: - - def filterfalse(predicate, iterable): - # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x + Make an iterator that filters elements from iterable returning only those for + which the predicate is ``False``. If *predicate* is ``None``, return the items + that are false. Equivalent to:: + + def filterfalse(predicate, iterable): + # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 + if predicate is None: + predicate = bool + for x in iterable: + if not predicate(x): + yield x .. function:: groupby(iterable, key=None) - Make an iterator that returns consecutive keys and groups from the *iterable*. - The *key* is a function computing a key value for each element. If not - specified or is ``None``, *key* defaults to an identity function and returns - the element unchanged. Generally, the iterable needs to already be sorted on - the same key function. - - The operation of :func:`groupby` is similar to the ``uniq`` filter in Unix. It - generates a break or new group every time the value of the key function changes - (which is why it is usually necessary to have sorted the data using the same key - function). That behavior differs from SQL's GROUP BY which aggregates common - elements regardless of their input order. - - The returned group is itself an iterator that shares the underlying iterable - with :func:`groupby`. Because the source is shared, when the :func:`groupby` - object is advanced, the previous group is no longer visible. So, if that data - is needed later, it should be stored as a list:: - - groups = [] - uniquekeys = [] - data = sorted(data, key=keyfunc) - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - - :func:`groupby` is equivalent to:: - - class groupby: - # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B - # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = object() - def __iter__(self): - return self - def __next__(self): - while self.currkey == self.tgtkey: - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) + Make an iterator that returns consecutive keys and groups from the *iterable*. + The *key* is a function computing a key value for each element. If not + specified or is ``None``, *key* defaults to an identity function and returns + the element unchanged. Generally, the iterable needs to already be sorted on + the same key function. + + The operation of :func:`groupby` is similar to the ``uniq`` filter in Unix. It + generates a break or new group every time the value of the key function changes + (which is why it is usually necessary to have sorted the data using the same key + function). That behavior differs from SQL's GROUP BY which aggregates common + elements regardless of their input order. + + The returned group is itself an iterator that shares the underlying iterable + with :func:`groupby`. Because the source is shared, when the :func:`groupby` + object is advanced, the previous group is no longer visible. So, if that data + is needed later, it should be stored as a list:: + + groups = [] + uniquekeys = [] + data = sorted(data, key=keyfunc) + for k, g in groupby(data, keyfunc): + groups.append(list(g)) # Store group iterator as a list + uniquekeys.append(k) + + :func:`groupby` is equivalent to:: + + class groupby: + # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B + # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D + def __init__(self, iterable, key=None): + if key is None: + key = lambda x: x + self.keyfunc = key + self.it = iter(iterable) + self.tgtkey = self.currkey = self.currvalue = object() + def __iter__(self): + return self + def __next__(self): + while self.currkey == self.tgtkey: + self.currvalue = next(self.it) # Exit on StopIteration + self.currkey = self.keyfunc(self.currvalue) + self.tgtkey = self.currkey + return (self.currkey, self._grouper(self.tgtkey)) + def _grouper(self, tgtkey): + while self.currkey == tgtkey: + yield self.currvalue + self.currvalue = next(self.it) # Exit on StopIteration + self.currkey = self.keyfunc(self.currvalue) .. function:: islice(iterable, [start,] stop [, step]) - Make an iterator that returns selected elements from the iterable. If *start* is - non-zero, then elements from the iterable are skipped until start is reached. - Afterward, elements are returned consecutively unless *step* is set higher than - one which results in items being skipped. If *stop* is ``None``, then iteration - continues until the iterator is exhausted, if at all; otherwise, it stops at the - specified position. Unlike regular slicing, :func:`islice` does not support - negative values for *start*, *stop*, or *step*. Can be used to extract related - fields from data where the internal structure has been flattened (for example, a - multi-line report may list a name field on every third line). Equivalent to:: - - def islice(iterable, *args): - # islice('ABCDEFG', 2) --> A B - # islice('ABCDEFG', 2, 4) --> C D - # islice('ABCDEFG', 2, None) --> C D E F G - # islice('ABCDEFG', 0, None, 2) --> A C E G - s = slice(*args) - it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) - nexti = next(it) - for i, element in enumerate(iterable): - if i == nexti: - yield element - nexti = next(it) + Make an iterator that returns selected elements from the iterable. If *start* is + non-zero, then elements from the iterable are skipped until start is reached. + Afterward, elements are returned consecutively unless *step* is set higher than + one which results in items being skipped. If *stop* is ``None``, then iteration + continues until the iterator is exhausted, if at all; otherwise, it stops at the + specified position. Unlike regular slicing, :func:`islice` does not support + negative values for *start*, *stop*, or *step*. Can be used to extract related + fields from data where the internal structure has been flattened (for example, a + multi-line report may list a name field on every third line). Equivalent to:: + + def islice(iterable, *args): + # islice('ABCDEFG', 2) --> A B + # islice('ABCDEFG', 2, 4) --> C D + # islice('ABCDEFG', 2, None) --> C D E F G + # islice('ABCDEFG', 0, None, 2) --> A C E G + s = slice(*args) + it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) + nexti = next(it) + for i, element in enumerate(iterable): + if i == nexti: + yield element + nexti = next(it) - If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, - then the step defaults to one. + If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, + then the step defaults to one. .. function:: permutations(iterable, r=None) - Return successive *r* length permutations of elements in the *iterable*. + Return successive *r* length permutations of elements in the *iterable*. - If *r* is not specified or is ``None``, then *r* defaults to the length - of the *iterable* and all possible full-length permutations - are generated. + If *r* is not specified or is ``None``, then *r* defaults to the length + of the *iterable* and all possible full-length permutations + are generated. - Permutations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the permutation tuples will be produced - in sorted order. + Permutations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the permutation tuples will be produced + in sorted order. - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat - values in each permutation. + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, there will be no repeat + values in each permutation. - Equivalent to:: + Equivalent to:: def permutations(iterable, r=None): # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC @@ -418,9 +434,9 @@ else: return - The code for :func:`permutations` can be also expressed as a subsequence of - :func:`product`, filtered to exclude entries with repeated elements (those - from the same position in the input pool):: + The code for :func:`permutations` can be also expressed as a subsequence of + :func:`product`, filtered to exclude entries with repeated elements (those + from the same position in the input pool):: def permutations(iterable, r=None): pool = tuple(iterable) @@ -430,87 +446,87 @@ if len(set(indices)) == r: yield tuple(pool[i] for i in indices) - The number of items returned is ``n! / (n-r)!`` when ``0 <= r <= n`` - or zero when ``r > n``. + The number of items returned is ``n! / (n-r)!`` when ``0 <= r <= n`` + or zero when ``r > n``. .. function:: product(*iterables, repeat=1) - Cartesian product of input iterables. + Cartesian product of input iterables. - Equivalent to nested for-loops in a generator expression. For example, - ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. + Equivalent to nested for-loops in a generator expression. For example, + ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. - The nested loops cycle like an odometer with the rightmost element advancing - on every iteration. This pattern creates a lexicographic ordering so that if - the input's iterables are sorted, the product tuples are emitted in sorted - order. - - To compute the product of an iterable with itself, specify the number of - repetitions with the optional *repeat* keyword argument. For example, - ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. - - This function is equivalent to the following code, except that the - actual implementation does not build up intermediate results in memory:: - - def product(*args, repeat=1): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = [tuple(pool) for pool in args] * repeat - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) + The nested loops cycle like an odometer with the rightmost element advancing + on every iteration. This pattern creates a lexicographic ordering so that if + the input's iterables are sorted, the product tuples are emitted in sorted + order. + + To compute the product of an iterable with itself, specify the number of + repetitions with the optional *repeat* keyword argument. For example, + ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. + + This function is equivalent to the following code, except that the + actual implementation does not build up intermediate results in memory:: + + def product(*args, repeat=1): + # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + pools = [tuple(pool) for pool in args] * repeat + result = [[]] + for pool in pools: + result = [x+[y] for x in result for y in pool] + for prod in result: + yield tuple(prod) .. function:: repeat(object[, times]) - Make an iterator that returns *object* over and over again. Runs indefinitely - unless the *times* argument is specified. Used as argument to :func:`map` for - invariant parameters to the called function. Also used with :func:`zip` to - create an invariant part of a tuple record. Equivalent to:: - - def repeat(object, times=None): - # repeat(10, 3) --> 10 10 10 - if times is None: - while True: - yield object - else: - for i in range(times): - yield object + Make an iterator that returns *object* over and over again. Runs indefinitely + unless the *times* argument is specified. Used as argument to :func:`map` for + invariant parameters to the called function. Also used with :func:`zip` to + create an invariant part of a tuple record. Equivalent to:: + + def repeat(object, times=None): + # repeat(10, 3) --> 10 10 10 + if times is None: + while True: + yield object + else: + for i in range(times): + yield object .. function:: starmap(function, iterable) - Make an iterator that computes the function using arguments obtained from - the iterable. Used instead of :func:`map` when argument parameters are already - grouped in tuples from a single iterable (the data has been "pre-zipped"). The - difference between :func:`map` and :func:`starmap` parallels the distinction - between ``function(a,b)`` and ``function(*c)``. Equivalent to:: - - def starmap(function, iterable): - # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 - for args in iterable: - yield function(*args) + Make an iterator that computes the function using arguments obtained from + the iterable. Used instead of :func:`map` when argument parameters are already + grouped in tuples from a single iterable (the data has been "pre-zipped"). The + difference between :func:`map` and :func:`starmap` parallels the distinction + between ``function(a,b)`` and ``function(*c)``. Equivalent to:: + + def starmap(function, iterable): + # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 + for args in iterable: + yield function(*args) .. function:: takewhile(predicate, iterable) - Make an iterator that returns elements from the iterable as long as the - predicate is true. Equivalent to:: + Make an iterator that returns elements from the iterable as long as the + predicate is true. Equivalent to:: - def takewhile(predicate, iterable): - # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 - for x in iterable: - if predicate(x): - yield x - else: - break + def takewhile(predicate, iterable): + # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 + for x in iterable: + if predicate(x): + yield x + else: + break .. function:: tee(iterable, n=2) - Return *n* independent iterators from a single iterable. Equivalent to:: + Return *n* independent iterators from a single iterable. Equivalent to:: def tee(iterable, n=2): it = iter(iterable) @@ -524,38 +540,38 @@ yield mydeque.popleft() return tuple(gen(d) for d in deques) - Once :func:`tee` has made a split, the original *iterable* should not be - used anywhere else; otherwise, the *iterable* could get advanced without - the tee objects being informed. - - This itertool may require significant auxiliary storage (depending on how - much temporary data needs to be stored). In general, if one iterator uses - most or all of the data before another iterator starts, it is faster to use - :func:`list` instead of :func:`tee`. + Once :func:`tee` has made a split, the original *iterable* should not be + used anywhere else; otherwise, the *iterable* could get advanced without + the tee objects being informed. + + This itertool may require significant auxiliary storage (depending on how + much temporary data needs to be stored). In general, if one iterator uses + most or all of the data before another iterator starts, it is faster to use + :func:`list` instead of :func:`tee`. .. function:: zip_longest(*iterables, fillvalue=None) - Make an iterator that aggregates elements from each of the iterables. If the - iterables are of uneven length, missing values are filled-in with *fillvalue*. - Iteration continues until the longest iterable is exhausted. Equivalent to:: - - def zip_longest(*args, fillvalue=None): - # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- - def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): - yield counter() # yields the fillvalue, or raises IndexError - fillers = repeat(fillvalue) - iters = [chain(it, sentinel(), fillers) for it in args] - try: - for tup in zip(*iters): - yield tup - except IndexError: - pass - - If one of the iterables is potentially infinite, then the :func:`zip_longest` - function should be wrapped with something that limits the number of calls - (for example :func:`islice` or :func:`takewhile`). If not specified, - *fillvalue* defaults to ``None``. + Make an iterator that aggregates elements from each of the iterables. If the + iterables are of uneven length, missing values are filled-in with *fillvalue*. + Iteration continues until the longest iterable is exhausted. Equivalent to:: + + def zip_longest(*args, fillvalue=None): + # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- + def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): + yield counter() # yields the fillvalue, or raises IndexError + fillers = repeat(fillvalue) + iters = [chain(it, sentinel(), fillers) for it in args] + try: + for tup in zip(*iters): + yield tup + except IndexError: + pass + + If one of the iterables is potentially infinite, then the :func:`zip_longest` + function should be wrapped with something that limits the number of calls + (for example :func:`islice` or :func:`takewhile`). If not specified, + *fillvalue* defaults to ``None``. .. _itertools-recipes: @@ -576,176 +592,168 @@ .. testcode:: - def take(n, iterable): - "Return first n items of the iterable as a list" - return list(islice(iterable, n)) - - def tabulate(function, start=0): - "Return function(0), function(1), ..." - return map(function, count(start)) - - def consume(iterator, n): - "Advance the iterator n-steps ahead. If n is none, consume entirely." - # Use functions that consume iterators at C speed. - if n is None: - # feed the entire iterator into a zero-length deque - collections.deque(iterator, maxlen=0) - else: - # advance to the empty slice starting at position n - next(islice(iterator, n, n), None) - - def nth(iterable, n, default=None): - "Returns the nth item or a default value" - return next(islice(iterable, n, None), default) - - def quantify(iterable, pred=bool): - "Count how many times the predicate is true" - return sum(map(pred, iterable)) - - def padnone(iterable): - """Returns the sequence elements and then returns None indefinitely. - - Useful for emulating the behavior of the built-in map() function. - """ - return chain(iterable, repeat(None)) - - def ncycles(iterable, n): - "Returns the sequence elements n times" - return chain.from_iterable(repeat(tuple(iterable), n)) - - def dotproduct(vec1, vec2): - return sum(map(operator.mul, vec1, vec2)) - - def flatten(listOfLists): - "Flatten one level of nesting" - return chain.from_iterable(listOfLists) - - def repeatfunc(func, times=None, *args): - """Repeat calls to func with specified arguments. - - Example: repeatfunc(random.random) - """ - if times is None: - return starmap(func, repeat(args)) - return starmap(func, repeat(args, times)) - - def pairwise(iterable): - "s -> (s0,s1), (s1,s2), (s2, s3), ..." - a, b = tee(iterable) - next(b, None) - return zip(a, b) - - def grouper(n, iterable, fillvalue=None): - "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" - args = [iter(iterable)] * n - return zip_longest(*args, fillvalue=fillvalue) - - def roundrobin(*iterables): - "roundrobin('ABC', 'D', 'EF') --> A D E B F C" - # Recipe credited to George Sakkis - pending = len(iterables) - nexts = cycle(iter(it).__next__ for it in iterables) - while pending: - try: - for next in nexts: - yield next() - except StopIteration: - pending -= 1 - nexts = cycle(islice(nexts, pending)) - - def accumulate(iterable): - 'Emit a running total' - # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 - total = 0 - for element in iterable: - total += element - yield total - - def partition(pred, iterable): - 'Use a predicate to partition entries into false entries and true entries' - # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 - t1, t2 = tee(iterable) - return filterfalse(pred, t1), filter(pred, t2) - - def powerset(iterable): - "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" - s = list(iterable) - return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - - def unique_everseen(iterable, key=None): - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() - seen_add = seen.add - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element - else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element - - def unique_justseen(iterable, key=None): - "List unique elements, preserving order. Remember only the element just seen." - # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B - # unique_justseen('ABBCcAD', str.lower) --> A B C A D - return map(next, map(itemgetter(1), groupby(iterable, key))) - - def iter_except(func, exception, first=None): - """ Call a function repeatedly until an exception is raised. - - Converts a call-until-exception interface to an iterator interface. - Like __builtin__.iter(func, sentinel) but uses an exception instead - of a sentinel to end the loop. - - Examples: - iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator - iter_except(d.popitem, KeyError) # non-blocking dict iterator - iter_except(d.popleft, IndexError) # non-blocking deque iterator - iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue - iter_except(s.pop, KeyError) # non-blocking set iterator - - """ - try: - if first is not None: - yield first() # For database APIs needing an initial cast to db.first() - while 1: - yield func() - except exception: - pass - - def random_product(*args, repeat=1): - "Random selection from itertools.product(*args, **kwds)" - pools = [tuple(pool) for pool in args] * repeat - return tuple(random.choice(pool) for pool in pools) - - def random_permutation(iterable, r=None): - "Random selection from itertools.permutations(iterable, r)" - pool = tuple(iterable) - r = len(pool) if r is None else r - return tuple(random.sample(pool, r)) - - def random_combination(iterable, r): - "Random selection from itertools.combinations(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.sample(range(n), r)) - return tuple(pool[i] for i in indices) - - def random_combination_with_replacement(iterable, r): - "Random selection from itertools.combinations_with_replacement(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.randrange(n) for i in range(r)) - return tuple(pool[i] for i in indices) + def take(n, iterable): + "Return first n items of the iterable as a list" + return list(islice(iterable, n)) + + def tabulate(function, start=0): + "Return function(0), function(1), ..." + return map(function, count(start)) + + def consume(iterator, n): + "Advance the iterator n-steps ahead. If n is none, consume entirely." + # Use functions that consume iterators at C speed. + if n is None: + # feed the entire iterator into a zero-length deque + collections.deque(iterator, maxlen=0) + else: + # advance to the empty slice starting at position n + next(islice(iterator, n, n), None) + + def nth(iterable, n, default=None): + "Returns the nth item or a default value" + return next(islice(iterable, n, None), default) + + def quantify(iterable, pred=bool): + "Count how many times the predicate is true" + return sum(map(pred, iterable)) + + def padnone(iterable): + """Returns the sequence elements and then returns None indefinitely. + + Useful for emulating the behavior of the built-in map() function. + """ + return chain(iterable, repeat(None)) + + def ncycles(iterable, n): + "Returns the sequence elements n times" + return chain.from_iterable(repeat(tuple(iterable), n)) + + def dotproduct(vec1, vec2): + return sum(map(operator.mul, vec1, vec2)) + + def flatten(listOfLists): + "Flatten one level of nesting" + return chain.from_iterable(listOfLists) + + def repeatfunc(func, times=None, *args): + """Repeat calls to func with specified arguments. + + Example: repeatfunc(random.random) + """ + if times is None: + return starmap(func, repeat(args)) + return starmap(func, repeat(args, times)) + + def pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = tee(iterable) + next(b, None) + return zip(a, b) + + def grouper(n, iterable, fillvalue=None): + "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" + args = [iter(iterable)] * n + return zip_longest(*args, fillvalue=fillvalue) + + def roundrobin(*iterables): + "roundrobin('ABC', 'D', 'EF') --> A D E B F C" + # Recipe credited to George Sakkis + pending = len(iterables) + nexts = cycle(iter(it).__next__ for it in iterables) + while pending: + try: + for next in nexts: + yield next() + except StopIteration: + pending -= 1 + nexts = cycle(islice(nexts, pending)) + + def partition(pred, iterable): + 'Use a predicate to partition entries into false entries and true entries' + # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + t1, t2 = tee(iterable) + return filterfalse(pred, t1), filter(pred, t2) + + def powerset(iterable): + "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) + + def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + def unique_justseen(iterable, key=None): + "List unique elements, preserving order. Remember only the element just seen." + # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B + # unique_justseen('ABBCcAD', str.lower) --> A B C A D + return map(next, map(itemgetter(1), groupby(iterable, key))) + + def iter_except(func, exception, first=None): + """ Call a function repeatedly until an exception is raised. + + Converts a call-until-exception interface to an iterator interface. + Like __builtin__.iter(func, sentinel) but uses an exception instead + of a sentinel to end the loop. + + Examples: + iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator + iter_except(d.popitem, KeyError) # non-blocking dict iterator + iter_except(d.popleft, IndexError) # non-blocking deque iterator + iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue + iter_except(s.pop, KeyError) # non-blocking set iterator + + """ + try: + if first is not None: + yield first() # For database APIs needing an initial cast to db.first() + while 1: + yield func() + except exception: + pass + + def random_product(*args, repeat=1): + "Random selection from itertools.product(*args, **kwds)" + pools = [tuple(pool) for pool in args] * repeat + return tuple(random.choice(pool) for pool in pools) + + def random_permutation(iterable, r=None): + "Random selection from itertools.permutations(iterable, r)" + pool = tuple(iterable) + r = len(pool) if r is None else r + return tuple(random.sample(pool, r)) + + def random_combination(iterable, r): + "Random selection from itertools.combinations(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.sample(range(n), r)) + return tuple(pool[i] for i in indices) + + def random_combination_with_replacement(iterable, r): + "Random selection from itertools.combinations_with_replacement(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.randrange(n) for i in range(r)) + return tuple(pool[i] for i in indices) Note, many of the above recipes can be optimized by replacing global lookups with local variables defined as default values. For example, the *dotproduct* recipe can be written as:: - def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul): - return sum(map(mul, vec1, vec2)) + def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul): + return sum(map(mul, vec1, vec2)) From python-checkins at python.org Thu Dec 2 00:45:20 2010 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 2 Dec 2010 00:45:20 +0100 (CET) Subject: [Python-checkins] r86920 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20101201234520.8E79AEE983@mail.python.org> Author: raymond.hettinger Date: Thu Dec 2 00:45:20 2010 New Revision: 86920 Log: Clean-up last update (missing comma, unnecessary spacing change, spurious backtick). Modified: python/branches/py3k/Doc/library/itertools.rst Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Thu Dec 2 00:45:20 2010 @@ -2,14 +2,14 @@ ======================================================================= .. module:: itertools - :synopsis: Functions creating iterators for efficient looping. + :synopsis: Functions creating iterators for efficient looping. .. moduleauthor:: Raymond Hettinger .. sectionauthor:: Raymond Hettinger .. testsetup:: - from itertools import * + from itertools import * This module implements a number of :term:`iterator` building blocks inspired @@ -46,7 +46,7 @@ ==================== ============================ ================================================= ============================================================= Iterator Arguments Results Example ==================== ============================ ================================================= ============================================================= -:func:`accumulate` p[, start=0] p0, p0+p1, p0+p1+p2 ... ` ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`accumulate` p[, start=0] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` @@ -102,44 +102,44 @@ .. function:: chain(*iterables) - Make an iterator that returns elements from the first iterable until it is - exhausted, then proceeds to the next iterable, until all of the iterables are - exhausted. Used for treating consecutive sequences as a single sequence. - Equivalent to:: - - def chain(*iterables): - # chain('ABC', 'DEF') --> A B C D E F - for it in iterables: - for element in it: - yield element + Make an iterator that returns elements from the first iterable until it is + exhausted, then proceeds to the next iterable, until all of the iterables are + exhausted. Used for treating consecutive sequences as a single sequence. + Equivalent to:: + + def chain(*iterables): + # chain('ABC', 'DEF') --> A B C D E F + for it in iterables: + for element in it: + yield element .. classmethod:: chain.from_iterable(iterable) - Alternate constructor for :func:`chain`. Gets chained inputs from a - single iterable argument that is evaluated lazily. Equivalent to:: + Alternate constructor for :func:`chain`. Gets chained inputs from a + single iterable argument that is evaluated lazily. Equivalent to:: - @classmethod - def from_iterable(iterables): - # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F - for it in iterables: - for element in it: - yield element + @classmethod + def from_iterable(iterables): + # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F + for it in iterables: + for element in it: + yield element .. function:: combinations(iterable, r) - Return *r* length subsequences of elements from the input *iterable*. + Return *r* length subsequences of elements from the input *iterable*. - Combinations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the combination tuples will be produced - in sorted order. + Combinations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the combination tuples will be produced + in sorted order. - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat - values in each combination. + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, there will be no repeat + values in each combination. - Equivalent to:: + Equivalent to:: def combinations(iterable, r): # combinations('ABCD', 2) --> AB AC AD BC BD CD @@ -161,9 +161,9 @@ indices[j] = indices[j-1] + 1 yield tuple(pool[i] for i in indices) - The code for :func:`combinations` can be also expressed as a subsequence - of :func:`permutations` after filtering entries where the elements are not - in sorted order (according to their position in the input pool):: + The code for :func:`combinations` can be also expressed as a subsequence + of :func:`permutations` after filtering entries where the elements are not + in sorted order (according to their position in the input pool):: def combinations(iterable, r): pool = tuple(iterable) @@ -172,23 +172,23 @@ if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) - The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n`` - or zero when ``r > n``. + The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n`` + or zero when ``r > n``. .. function:: combinations_with_replacement(iterable, r) - Return *r* length subsequences of elements from the input *iterable* - allowing individual elements to be repeated more than once. + Return *r* length subsequences of elements from the input *iterable* + allowing individual elements to be repeated more than once. - Combinations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the combination tuples will be produced - in sorted order. - - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, the generated combinations - will also be unique. + Combinations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the combination tuples will be produced + in sorted order. + + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, the generated combinations + will also be unique. - Equivalent to:: + Equivalent to:: def combinations_with_replacement(iterable, r): # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC @@ -207,9 +207,9 @@ indices[i:] = [indices[i] + 1] * (r - i) yield tuple(pool[i] for i in indices) - The code for :func:`combinations_with_replacement` can be also expressed as - a subsequence of :func:`product` after filtering entries where the elements - are not in sorted order (according to their position in the input pool):: + The code for :func:`combinations_with_replacement` can be also expressed as + a subsequence of :func:`product` after filtering entries where the elements + are not in sorted order (according to their position in the input pool):: def combinations_with_replacement(iterable, r): pool = tuple(iterable) @@ -218,196 +218,196 @@ if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) - The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``. + The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``. - .. versionadded:: 3.1 + .. versionadded:: 3.1 .. function:: compress(data, selectors) - Make an iterator that filters elements from *data* returning only those that - have a corresponding element in *selectors* that evaluates to ``True``. - Stops when either the *data* or *selectors* iterables has been exhausted. - Equivalent to:: - - def compress(data, selectors): - # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F - return (d for d, s in zip(data, selectors) if s) + Make an iterator that filters elements from *data* returning only those that + have a corresponding element in *selectors* that evaluates to ``True``. + Stops when either the *data* or *selectors* iterables has been exhausted. + Equivalent to:: + + def compress(data, selectors): + # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F + return (d for d, s in zip(data, selectors) if s) - .. versionadded:: 3.1 + .. versionadded:: 3.1 .. function:: count(start=0, step=1) - Make an iterator that returns evenly spaced values starting with *n*. Often - used as an argument to :func:`map` to generate consecutive data points. - Also, used with :func:`zip` to add sequence numbers. Equivalent to:: - - def count(start=0, step=1): - # count(10) --> 10 11 12 13 14 ... - # count(2.5, 0.5) -> 3.5 3.0 4.5 ... - n = start - while True: - yield n - n += step + Make an iterator that returns evenly spaced values starting with *n*. Often + used as an argument to :func:`map` to generate consecutive data points. + Also, used with :func:`zip` to add sequence numbers. Equivalent to:: + + def count(start=0, step=1): + # count(10) --> 10 11 12 13 14 ... + # count(2.5, 0.5) -> 3.5 3.0 4.5 ... + n = start + while True: + yield n + n += step + + When counting with floating point numbers, better accuracy can sometimes be + achieved by substituting multiplicative code such as: ``(start + step * i + for i in count())``. - When counting with floating point numbers, better accuracy can sometimes be - achieved by substituting multiplicative code such as: ``(start + step * i - for i in count())``. - - .. versionchanged:: 3.1 - Added *step* argument and allowed non-integer arguments. + .. versionchanged:: 3.1 + Added *step* argument and allowed non-integer arguments. .. function:: cycle(iterable) - Make an iterator returning elements from the iterable and saving a copy of each. - When the iterable is exhausted, return elements from the saved copy. Repeats - indefinitely. Equivalent to:: - - def cycle(iterable): - # cycle('ABCD') --> A B C D A B C D A B C D ... - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: + Make an iterator returning elements from the iterable and saving a copy of each. + When the iterable is exhausted, return elements from the saved copy. Repeats + indefinitely. Equivalent to:: + + def cycle(iterable): + # cycle('ABCD') --> A B C D A B C D A B C D ... + saved = [] + for element in iterable: + yield element + saved.append(element) + while saved: + for element in saved: yield element - Note, this member of the toolkit may require significant auxiliary storage - (depending on the length of the iterable). + Note, this member of the toolkit may require significant auxiliary storage + (depending on the length of the iterable). .. function:: dropwhile(predicate, iterable) - Make an iterator that drops elements from the iterable as long as the predicate - is true; afterwards, returns every element. Note, the iterator does not produce - *any* output until the predicate first becomes false, so it may have a lengthy - start-up time. Equivalent to:: - - def dropwhile(predicate, iterable): - # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x + Make an iterator that drops elements from the iterable as long as the predicate + is true; afterwards, returns every element. Note, the iterator does not produce + *any* output until the predicate first becomes false, so it may have a lengthy + start-up time. Equivalent to:: + + def dropwhile(predicate, iterable): + # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 + iterable = iter(iterable) + for x in iterable: + if not predicate(x): + yield x + break + for x in iterable: + yield x .. function:: filterfalse(predicate, iterable) - Make an iterator that filters elements from iterable returning only those for - which the predicate is ``False``. If *predicate* is ``None``, return the items - that are false. Equivalent to:: - - def filterfalse(predicate, iterable): - # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x + Make an iterator that filters elements from iterable returning only those for + which the predicate is ``False``. If *predicate* is ``None``, return the items + that are false. Equivalent to:: + + def filterfalse(predicate, iterable): + # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 + if predicate is None: + predicate = bool + for x in iterable: + if not predicate(x): + yield x .. function:: groupby(iterable, key=None) - Make an iterator that returns consecutive keys and groups from the *iterable*. - The *key* is a function computing a key value for each element. If not - specified or is ``None``, *key* defaults to an identity function and returns - the element unchanged. Generally, the iterable needs to already be sorted on - the same key function. - - The operation of :func:`groupby` is similar to the ``uniq`` filter in Unix. It - generates a break or new group every time the value of the key function changes - (which is why it is usually necessary to have sorted the data using the same key - function). That behavior differs from SQL's GROUP BY which aggregates common - elements regardless of their input order. - - The returned group is itself an iterator that shares the underlying iterable - with :func:`groupby`. Because the source is shared, when the :func:`groupby` - object is advanced, the previous group is no longer visible. So, if that data - is needed later, it should be stored as a list:: - - groups = [] - uniquekeys = [] - data = sorted(data, key=keyfunc) - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - - :func:`groupby` is equivalent to:: - - class groupby: - # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B - # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = object() - def __iter__(self): - return self - def __next__(self): - while self.currkey == self.tgtkey: - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = next(self.it) # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) + Make an iterator that returns consecutive keys and groups from the *iterable*. + The *key* is a function computing a key value for each element. If not + specified or is ``None``, *key* defaults to an identity function and returns + the element unchanged. Generally, the iterable needs to already be sorted on + the same key function. + + The operation of :func:`groupby` is similar to the ``uniq`` filter in Unix. It + generates a break or new group every time the value of the key function changes + (which is why it is usually necessary to have sorted the data using the same key + function). That behavior differs from SQL's GROUP BY which aggregates common + elements regardless of their input order. + + The returned group is itself an iterator that shares the underlying iterable + with :func:`groupby`. Because the source is shared, when the :func:`groupby` + object is advanced, the previous group is no longer visible. So, if that data + is needed later, it should be stored as a list:: + + groups = [] + uniquekeys = [] + data = sorted(data, key=keyfunc) + for k, g in groupby(data, keyfunc): + groups.append(list(g)) # Store group iterator as a list + uniquekeys.append(k) + + :func:`groupby` is equivalent to:: + + class groupby: + # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B + # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D + def __init__(self, iterable, key=None): + if key is None: + key = lambda x: x + self.keyfunc = key + self.it = iter(iterable) + self.tgtkey = self.currkey = self.currvalue = object() + def __iter__(self): + return self + def __next__(self): + while self.currkey == self.tgtkey: + self.currvalue = next(self.it) # Exit on StopIteration + self.currkey = self.keyfunc(self.currvalue) + self.tgtkey = self.currkey + return (self.currkey, self._grouper(self.tgtkey)) + def _grouper(self, tgtkey): + while self.currkey == tgtkey: + yield self.currvalue + self.currvalue = next(self.it) # Exit on StopIteration + self.currkey = self.keyfunc(self.currvalue) .. function:: islice(iterable, [start,] stop [, step]) - Make an iterator that returns selected elements from the iterable. If *start* is - non-zero, then elements from the iterable are skipped until start is reached. - Afterward, elements are returned consecutively unless *step* is set higher than - one which results in items being skipped. If *stop* is ``None``, then iteration - continues until the iterator is exhausted, if at all; otherwise, it stops at the - specified position. Unlike regular slicing, :func:`islice` does not support - negative values for *start*, *stop*, or *step*. Can be used to extract related - fields from data where the internal structure has been flattened (for example, a - multi-line report may list a name field on every third line). Equivalent to:: - - def islice(iterable, *args): - # islice('ABCDEFG', 2) --> A B - # islice('ABCDEFG', 2, 4) --> C D - # islice('ABCDEFG', 2, None) --> C D E F G - # islice('ABCDEFG', 0, None, 2) --> A C E G - s = slice(*args) - it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) - nexti = next(it) - for i, element in enumerate(iterable): - if i == nexti: - yield element - nexti = next(it) + Make an iterator that returns selected elements from the iterable. If *start* is + non-zero, then elements from the iterable are skipped until start is reached. + Afterward, elements are returned consecutively unless *step* is set higher than + one which results in items being skipped. If *stop* is ``None``, then iteration + continues until the iterator is exhausted, if at all; otherwise, it stops at the + specified position. Unlike regular slicing, :func:`islice` does not support + negative values for *start*, *stop*, or *step*. Can be used to extract related + fields from data where the internal structure has been flattened (for example, a + multi-line report may list a name field on every third line). Equivalent to:: + + def islice(iterable, *args): + # islice('ABCDEFG', 2) --> A B + # islice('ABCDEFG', 2, 4) --> C D + # islice('ABCDEFG', 2, None) --> C D E F G + # islice('ABCDEFG', 0, None, 2) --> A C E G + s = slice(*args) + it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) + nexti = next(it) + for i, element in enumerate(iterable): + if i == nexti: + yield element + nexti = next(it) - If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, - then the step defaults to one. + If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, + then the step defaults to one. .. function:: permutations(iterable, r=None) - Return successive *r* length permutations of elements in the *iterable*. + Return successive *r* length permutations of elements in the *iterable*. - If *r* is not specified or is ``None``, then *r* defaults to the length - of the *iterable* and all possible full-length permutations - are generated. + If *r* is not specified or is ``None``, then *r* defaults to the length + of the *iterable* and all possible full-length permutations + are generated. - Permutations are emitted in lexicographic sort order. So, if the - input *iterable* is sorted, the permutation tuples will be produced - in sorted order. + Permutations are emitted in lexicographic sort order. So, if the + input *iterable* is sorted, the permutation tuples will be produced + in sorted order. - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat - values in each permutation. + Elements are treated as unique based on their position, not on their + value. So if the input elements are unique, there will be no repeat + values in each permutation. - Equivalent to:: + Equivalent to:: def permutations(iterable, r=None): # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC @@ -434,9 +434,9 @@ else: return - The code for :func:`permutations` can be also expressed as a subsequence of - :func:`product`, filtered to exclude entries with repeated elements (those - from the same position in the input pool):: + The code for :func:`permutations` can be also expressed as a subsequence of + :func:`product`, filtered to exclude entries with repeated elements (those + from the same position in the input pool):: def permutations(iterable, r=None): pool = tuple(iterable) @@ -446,87 +446,87 @@ if len(set(indices)) == r: yield tuple(pool[i] for i in indices) - The number of items returned is ``n! / (n-r)!`` when ``0 <= r <= n`` - or zero when ``r > n``. + The number of items returned is ``n! / (n-r)!`` when ``0 <= r <= n`` + or zero when ``r > n``. .. function:: product(*iterables, repeat=1) - Cartesian product of input iterables. + Cartesian product of input iterables. - Equivalent to nested for-loops in a generator expression. For example, - ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. + Equivalent to nested for-loops in a generator expression. For example, + ``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``. - The nested loops cycle like an odometer with the rightmost element advancing - on every iteration. This pattern creates a lexicographic ordering so that if - the input's iterables are sorted, the product tuples are emitted in sorted - order. - - To compute the product of an iterable with itself, specify the number of - repetitions with the optional *repeat* keyword argument. For example, - ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. - - This function is equivalent to the following code, except that the - actual implementation does not build up intermediate results in memory:: - - def product(*args, repeat=1): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = [tuple(pool) for pool in args] * repeat - result = [[]] - for pool in pools: - result = [x+[y] for x in result for y in pool] - for prod in result: - yield tuple(prod) + The nested loops cycle like an odometer with the rightmost element advancing + on every iteration. This pattern creates a lexicographic ordering so that if + the input's iterables are sorted, the product tuples are emitted in sorted + order. + + To compute the product of an iterable with itself, specify the number of + repetitions with the optional *repeat* keyword argument. For example, + ``product(A, repeat=4)`` means the same as ``product(A, A, A, A)``. + + This function is equivalent to the following code, except that the + actual implementation does not build up intermediate results in memory:: + + def product(*args, repeat=1): + # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + pools = [tuple(pool) for pool in args] * repeat + result = [[]] + for pool in pools: + result = [x+[y] for x in result for y in pool] + for prod in result: + yield tuple(prod) .. function:: repeat(object[, times]) - Make an iterator that returns *object* over and over again. Runs indefinitely - unless the *times* argument is specified. Used as argument to :func:`map` for - invariant parameters to the called function. Also used with :func:`zip` to - create an invariant part of a tuple record. Equivalent to:: - - def repeat(object, times=None): - # repeat(10, 3) --> 10 10 10 - if times is None: - while True: - yield object - else: - for i in range(times): - yield object + Make an iterator that returns *object* over and over again. Runs indefinitely + unless the *times* argument is specified. Used as argument to :func:`map` for + invariant parameters to the called function. Also used with :func:`zip` to + create an invariant part of a tuple record. Equivalent to:: + + def repeat(object, times=None): + # repeat(10, 3) --> 10 10 10 + if times is None: + while True: + yield object + else: + for i in range(times): + yield object .. function:: starmap(function, iterable) - Make an iterator that computes the function using arguments obtained from - the iterable. Used instead of :func:`map` when argument parameters are already - grouped in tuples from a single iterable (the data has been "pre-zipped"). The - difference between :func:`map` and :func:`starmap` parallels the distinction - between ``function(a,b)`` and ``function(*c)``. Equivalent to:: - - def starmap(function, iterable): - # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 - for args in iterable: - yield function(*args) + Make an iterator that computes the function using arguments obtained from + the iterable. Used instead of :func:`map` when argument parameters are already + grouped in tuples from a single iterable (the data has been "pre-zipped"). The + difference between :func:`map` and :func:`starmap` parallels the distinction + between ``function(a,b)`` and ``function(*c)``. Equivalent to:: + + def starmap(function, iterable): + # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 + for args in iterable: + yield function(*args) .. function:: takewhile(predicate, iterable) - Make an iterator that returns elements from the iterable as long as the - predicate is true. Equivalent to:: + Make an iterator that returns elements from the iterable as long as the + predicate is true. Equivalent to:: - def takewhile(predicate, iterable): - # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 - for x in iterable: - if predicate(x): - yield x - else: - break + def takewhile(predicate, iterable): + # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 + for x in iterable: + if predicate(x): + yield x + else: + break .. function:: tee(iterable, n=2) - Return *n* independent iterators from a single iterable. Equivalent to:: + Return *n* independent iterators from a single iterable. Equivalent to:: def tee(iterable, n=2): it = iter(iterable) @@ -540,38 +540,38 @@ yield mydeque.popleft() return tuple(gen(d) for d in deques) - Once :func:`tee` has made a split, the original *iterable* should not be - used anywhere else; otherwise, the *iterable* could get advanced without - the tee objects being informed. - - This itertool may require significant auxiliary storage (depending on how - much temporary data needs to be stored). In general, if one iterator uses - most or all of the data before another iterator starts, it is faster to use - :func:`list` instead of :func:`tee`. + Once :func:`tee` has made a split, the original *iterable* should not be + used anywhere else; otherwise, the *iterable* could get advanced without + the tee objects being informed. + + This itertool may require significant auxiliary storage (depending on how + much temporary data needs to be stored). In general, if one iterator uses + most or all of the data before another iterator starts, it is faster to use + :func:`list` instead of :func:`tee`. .. function:: zip_longest(*iterables, fillvalue=None) - Make an iterator that aggregates elements from each of the iterables. If the - iterables are of uneven length, missing values are filled-in with *fillvalue*. - Iteration continues until the longest iterable is exhausted. Equivalent to:: - - def zip_longest(*args, fillvalue=None): - # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- - def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): - yield counter() # yields the fillvalue, or raises IndexError - fillers = repeat(fillvalue) - iters = [chain(it, sentinel(), fillers) for it in args] - try: - for tup in zip(*iters): - yield tup - except IndexError: - pass - - If one of the iterables is potentially infinite, then the :func:`zip_longest` - function should be wrapped with something that limits the number of calls - (for example :func:`islice` or :func:`takewhile`). If not specified, - *fillvalue* defaults to ``None``. + Make an iterator that aggregates elements from each of the iterables. If the + iterables are of uneven length, missing values are filled-in with *fillvalue*. + Iteration continues until the longest iterable is exhausted. Equivalent to:: + + def zip_longest(*args, fillvalue=None): + # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- + def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): + yield counter() # yields the fillvalue, or raises IndexError + fillers = repeat(fillvalue) + iters = [chain(it, sentinel(), fillers) for it in args] + try: + for tup in zip(*iters): + yield tup + except IndexError: + pass + + If one of the iterables is potentially infinite, then the :func:`zip_longest` + function should be wrapped with something that limits the number of calls + (for example :func:`islice` or :func:`takewhile`). If not specified, + *fillvalue* defaults to ``None``. .. _itertools-recipes: @@ -592,168 +592,168 @@ .. testcode:: - def take(n, iterable): - "Return first n items of the iterable as a list" - return list(islice(iterable, n)) - - def tabulate(function, start=0): - "Return function(0), function(1), ..." - return map(function, count(start)) - - def consume(iterator, n): - "Advance the iterator n-steps ahead. If n is none, consume entirely." - # Use functions that consume iterators at C speed. - if n is None: - # feed the entire iterator into a zero-length deque - collections.deque(iterator, maxlen=0) - else: - # advance to the empty slice starting at position n - next(islice(iterator, n, n), None) - - def nth(iterable, n, default=None): - "Returns the nth item or a default value" - return next(islice(iterable, n, None), default) - - def quantify(iterable, pred=bool): - "Count how many times the predicate is true" - return sum(map(pred, iterable)) - - def padnone(iterable): - """Returns the sequence elements and then returns None indefinitely. - - Useful for emulating the behavior of the built-in map() function. - """ - return chain(iterable, repeat(None)) - - def ncycles(iterable, n): - "Returns the sequence elements n times" - return chain.from_iterable(repeat(tuple(iterable), n)) - - def dotproduct(vec1, vec2): - return sum(map(operator.mul, vec1, vec2)) - - def flatten(listOfLists): - "Flatten one level of nesting" - return chain.from_iterable(listOfLists) - - def repeatfunc(func, times=None, *args): - """Repeat calls to func with specified arguments. - - Example: repeatfunc(random.random) - """ - if times is None: - return starmap(func, repeat(args)) - return starmap(func, repeat(args, times)) - - def pairwise(iterable): - "s -> (s0,s1), (s1,s2), (s2, s3), ..." - a, b = tee(iterable) - next(b, None) - return zip(a, b) - - def grouper(n, iterable, fillvalue=None): - "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" - args = [iter(iterable)] * n - return zip_longest(*args, fillvalue=fillvalue) - - def roundrobin(*iterables): - "roundrobin('ABC', 'D', 'EF') --> A D E B F C" - # Recipe credited to George Sakkis - pending = len(iterables) - nexts = cycle(iter(it).__next__ for it in iterables) - while pending: - try: - for next in nexts: - yield next() - except StopIteration: - pending -= 1 - nexts = cycle(islice(nexts, pending)) - - def partition(pred, iterable): - 'Use a predicate to partition entries into false entries and true entries' - # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 - t1, t2 = tee(iterable) - return filterfalse(pred, t1), filter(pred, t2) - - def powerset(iterable): - "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" - s = list(iterable) - return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - - def unique_everseen(iterable, key=None): - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() - seen_add = seen.add - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element - else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element - - def unique_justseen(iterable, key=None): - "List unique elements, preserving order. Remember only the element just seen." - # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B - # unique_justseen('ABBCcAD', str.lower) --> A B C A D - return map(next, map(itemgetter(1), groupby(iterable, key))) - - def iter_except(func, exception, first=None): - """ Call a function repeatedly until an exception is raised. - - Converts a call-until-exception interface to an iterator interface. - Like __builtin__.iter(func, sentinel) but uses an exception instead - of a sentinel to end the loop. - - Examples: - iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator - iter_except(d.popitem, KeyError) # non-blocking dict iterator - iter_except(d.popleft, IndexError) # non-blocking deque iterator - iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue - iter_except(s.pop, KeyError) # non-blocking set iterator - - """ - try: - if first is not None: - yield first() # For database APIs needing an initial cast to db.first() - while 1: - yield func() - except exception: - pass - - def random_product(*args, repeat=1): - "Random selection from itertools.product(*args, **kwds)" - pools = [tuple(pool) for pool in args] * repeat - return tuple(random.choice(pool) for pool in pools) - - def random_permutation(iterable, r=None): - "Random selection from itertools.permutations(iterable, r)" - pool = tuple(iterable) - r = len(pool) if r is None else r - return tuple(random.sample(pool, r)) - - def random_combination(iterable, r): - "Random selection from itertools.combinations(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.sample(range(n), r)) - return tuple(pool[i] for i in indices) - - def random_combination_with_replacement(iterable, r): - "Random selection from itertools.combinations_with_replacement(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.randrange(n) for i in range(r)) - return tuple(pool[i] for i in indices) + def take(n, iterable): + "Return first n items of the iterable as a list" + return list(islice(iterable, n)) + + def tabulate(function, start=0): + "Return function(0), function(1), ..." + return map(function, count(start)) + + def consume(iterator, n): + "Advance the iterator n-steps ahead. If n is none, consume entirely." + # Use functions that consume iterators at C speed. + if n is None: + # feed the entire iterator into a zero-length deque + collections.deque(iterator, maxlen=0) + else: + # advance to the empty slice starting at position n + next(islice(iterator, n, n), None) + + def nth(iterable, n, default=None): + "Returns the nth item or a default value" + return next(islice(iterable, n, None), default) + + def quantify(iterable, pred=bool): + "Count how many times the predicate is true" + return sum(map(pred, iterable)) + + def padnone(iterable): + """Returns the sequence elements and then returns None indefinitely. + + Useful for emulating the behavior of the built-in map() function. + """ + return chain(iterable, repeat(None)) + + def ncycles(iterable, n): + "Returns the sequence elements n times" + return chain.from_iterable(repeat(tuple(iterable), n)) + + def dotproduct(vec1, vec2): + return sum(map(operator.mul, vec1, vec2)) + + def flatten(listOfLists): + "Flatten one level of nesting" + return chain.from_iterable(listOfLists) + + def repeatfunc(func, times=None, *args): + """Repeat calls to func with specified arguments. + + Example: repeatfunc(random.random) + """ + if times is None: + return starmap(func, repeat(args)) + return starmap(func, repeat(args, times)) + + def pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = tee(iterable) + next(b, None) + return zip(a, b) + + def grouper(n, iterable, fillvalue=None): + "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" + args = [iter(iterable)] * n + return zip_longest(*args, fillvalue=fillvalue) + + def roundrobin(*iterables): + "roundrobin('ABC', 'D', 'EF') --> A D E B F C" + # Recipe credited to George Sakkis + pending = len(iterables) + nexts = cycle(iter(it).__next__ for it in iterables) + while pending: + try: + for next in nexts: + yield next() + except StopIteration: + pending -= 1 + nexts = cycle(islice(nexts, pending)) + + def partition(pred, iterable): + 'Use a predicate to partition entries into false entries and true entries' + # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + t1, t2 = tee(iterable) + return filterfalse(pred, t1), filter(pred, t2) + + def powerset(iterable): + "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) + + def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + def unique_justseen(iterable, key=None): + "List unique elements, preserving order. Remember only the element just seen." + # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B + # unique_justseen('ABBCcAD', str.lower) --> A B C A D + return map(next, map(itemgetter(1), groupby(iterable, key))) + + def iter_except(func, exception, first=None): + """ Call a function repeatedly until an exception is raised. + + Converts a call-until-exception interface to an iterator interface. + Like __builtin__.iter(func, sentinel) but uses an exception instead + of a sentinel to end the loop. + + Examples: + iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator + iter_except(d.popitem, KeyError) # non-blocking dict iterator + iter_except(d.popleft, IndexError) # non-blocking deque iterator + iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue + iter_except(s.pop, KeyError) # non-blocking set iterator + + """ + try: + if first is not None: + yield first() # For database APIs needing an initial cast to db.first() + while 1: + yield func() + except exception: + pass + + def random_product(*args, repeat=1): + "Random selection from itertools.product(*args, **kwds)" + pools = [tuple(pool) for pool in args] * repeat + return tuple(random.choice(pool) for pool in pools) + + def random_permutation(iterable, r=None): + "Random selection from itertools.permutations(iterable, r)" + pool = tuple(iterable) + r = len(pool) if r is None else r + return tuple(random.sample(pool, r)) + + def random_combination(iterable, r): + "Random selection from itertools.combinations(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.sample(range(n), r)) + return tuple(pool[i] for i in indices) + + def random_combination_with_replacement(iterable, r): + "Random selection from itertools.combinations_with_replacement(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.randrange(n) for i in range(r)) + return tuple(pool[i] for i in indices) Note, many of the above recipes can be optimized by replacing global lookups with local variables defined as default values. For example, the *dotproduct* recipe can be written as:: - def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul): - return sum(map(mul, vec1, vec2)) + def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul): + return sum(map(mul, vec1, vec2)) From python-checkins at python.org Thu Dec 2 01:05:58 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 2 Dec 2010 01:05:58 +0100 (CET) Subject: [Python-checkins] r86921 - python/branches/py3k/Doc/whatsnew/3.2.rst Message-ID: <20101202000558.1E046EE985@mail.python.org> Author: alexander.belopolsky Date: Thu Dec 2 01:05:57 2010 New Revision: 86921 Log: With Raymond's approval added a paragraph describing Unicode 6.0.0 changes. Not reST formatted. Modified: python/branches/py3k/Doc/whatsnew/3.2.rst Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Thu Dec 2 01:05:57 2010 @@ -661,6 +661,23 @@ Unicode ======= +Python has been updated to Unicode 6.0.0. The new features of the +Unicode Standard that will affect Python users include: + +* adds 2,088 characters, including over 1,000 additional symbols?chief +among them the additional emoji symbols, which are especially +important for mobile phones; + +* corrects character properties for existing characters including + - a general category change to two Kannada characters (U+0CF1, +U+0CF2), which has the effect of making them newly eligible for +inclusion in identifiers; + + - a general category change to one New Tai Lue numeric character +(U+19DA), which would have the effect of disqualifying it from +inclusion in identifiers unless grandfathering measures are in place +for the defining identifier syntax. + The :mod:`os` module has two new functions: :func:`~os.fsencode` and :func:`~os.fsdecode`. Add :data:`os.environb`: bytes version of :data:`os.environ`, :func:`os.getenvb` function and From python-checkins at python.org Thu Dec 2 01:10:12 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 2 Dec 2010 01:10:12 +0100 (CET) Subject: [Python-checkins] r86922 - python/branches/py3k/Lib/test/test_inspect.py Message-ID: <20101202001012.0236DEE997@mail.python.org> Author: alexander.belopolsky Date: Thu Dec 2 01:10:11 2010 New Revision: 86922 Log: Issue4335: Added a test for inspect.getsourcelines with a module without EOL at EOF. Modified: python/branches/py3k/Lib/test/test_inspect.py Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Thu Dec 2 01:10:11 2010 @@ -6,9 +6,11 @@ import linecache import datetime import collections +import os +import shutil from os.path import normcase -from test.support import run_unittest +from test.support import run_unittest, TESTFN, DirsOnSysPath from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 @@ -194,12 +196,12 @@ class GetSourceBase(unittest.TestCase): # Subclasses must override. - fodderFile = None + fodderModule = None def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - with open(inspect.getsourcefile(self.fodderFile)) as fp: + with open(inspect.getsourcefile(self.fodderModule)) as fp: self.source = fp.read() def sourcerange(self, top, bottom): @@ -211,7 +213,7 @@ self.sourcerange(top, bottom)) class TestRetrievingSourceCode(GetSourceBase): - fodderFile = mod + fodderModule = mod def test_getclasses(self): classes = inspect.getmembers(mod, inspect.isclass) @@ -297,7 +299,7 @@ inspect.getmodule(compile('a=10','','single')) class TestDecorators(GetSourceBase): - fodderFile = mod2 + fodderModule = mod2 def test_wrapped_decorator(self): self.assertSourceEqual(mod2.wrapped, 14, 17) @@ -306,7 +308,7 @@ self.assertSourceEqual(mod2.gone, 9, 10) class TestOneliners(GetSourceBase): - fodderFile = mod2 + fodderModule = mod2 def test_oneline_lambda(self): # Test inspect.getsource with a one-line lambda function. self.assertSourceEqual(mod2.oll, 25, 25) @@ -348,7 +350,7 @@ self.assertSourceEqual(mod2.anonymous, 55, 55) class TestBuggyCases(GetSourceBase): - fodderFile = mod2 + fodderModule = mod2 def test_with_comment(self): self.assertSourceEqual(mod2.with_comment, 58, 59) @@ -388,6 +390,24 @@ self.assertEqual(inspect.findsource(co), (lines,0)) self.assertEqual(inspect.getsource(co), lines[0]) +class TestNoEOL(GetSourceBase): + def __init__(self, *args, **kwargs): + self.tempdir = TESTFN + '_dir' + os.mkdir(self.tempdir) + with open(os.path.join(self.tempdir, + 'inspect_fodder3%spy' % os.extsep), 'w') as f: + f.write("class X:\n pass # No EOL") + with DirsOnSysPath(self.tempdir): + import inspect_fodder3 as mod3 + self.fodderModule = mod3 + GetSourceBase.__init__(self, *args, **kwargs) + + def tearDown(self): + shutil.rmtree(self.tempdir) + + def test_class(self): + self.assertSourceEqual(self.fodderModule.X, 1, 2) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] @@ -945,7 +965,8 @@ TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases, TestInterpreterStack, TestClassesAndFunctions, TestPredicates, TestGetcallargsFunctions, TestGetcallargsMethods, - TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState + TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState, + TestNoEOL ) if __name__ == "__main__": From python-checkins at python.org Thu Dec 2 02:38:31 2010 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 2 Dec 2010 02:38:31 +0100 (CET) Subject: [Python-checkins] r86923 - python/branches/py3k/Doc/whatsnew/3.2.rst Message-ID: <20101202013831.19C2AC839@mail.python.org> Author: raymond.hettinger Date: Thu Dec 2 02:38:25 2010 New Revision: 86923 Log: Fix markup Modified: python/branches/py3k/Doc/whatsnew/3.2.rst Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Thu Dec 2 02:38:25 2010 @@ -665,18 +665,19 @@ Unicode Standard that will affect Python users include: * adds 2,088 characters, including over 1,000 additional symbols?chief -among them the additional emoji symbols, which are especially -important for mobile phones; + among them the additional emoji symbols, which are especially + important for mobile phones; * corrects character properties for existing characters including - - a general category change to two Kannada characters (U+0CF1, -U+0CF2), which has the effect of making them newly eligible for -inclusion in identifiers; - - - a general category change to one New Tai Lue numeric character -(U+19DA), which would have the effect of disqualifying it from -inclusion in identifiers unless grandfathering measures are in place -for the defining identifier syntax. + + - a general category change to two Kannada characters (U+0CF1, + U+0CF2), which has the effect of making them newly eligible for + inclusion in identifiers; + + - a general category change to one New Tai Lue numeric character + (U+19DA), which would have the effect of disqualifying it from + inclusion in identifiers unless grandfathering measures are in place + for the defining identifier syntax. The :mod:`os` module has two new functions: :func:`~os.fsencode` and :func:`~os.fsdecode`. Add :data:`os.environb`: bytes version of From python-checkins at python.org Thu Dec 2 03:41:33 2010 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 2 Dec 2010 03:41:33 +0100 (CET) Subject: [Python-checkins] r86924 - python/branches/py3k/Doc/library/random.rst Message-ID: <20101202024133.CCAF1EE985@mail.python.org> Author: raymond.hettinger Date: Thu Dec 2 03:41:33 2010 New Revision: 86924 Log: Add an example to the random docs. Modified: python/branches/py3k/Doc/library/random.rst Modified: python/branches/py3k/Doc/library/random.rst ============================================================================== --- python/branches/py3k/Doc/library/random.rst (original) +++ python/branches/py3k/Doc/library/random.rst Thu Dec 2 03:41:33 2010 @@ -295,3 +295,29 @@ * The generator's :meth:`random` method will continue to produce the same sequence when the compatible seeder is given the same seed. + + +.. _random-examples: + +Examples and Recipes +==================== + +A common task is to make a :func:`random.choice` with weighted probababilites. + +If the weights are small integer ratios, a simple technique is to build a sample +population with repeats:: + + >>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)] + >>> population = [val for val, cnt in weighted_choices for i in range(cnt)] + >>> random.choice(population) + 'Green' + +A more general approach is to arrange the weights in a cumulative probability +distribution with :func:`itertools.accumulate`, and then locate the random value +with :func:`bisect.bisect`:: + + >>> choices, weights = zip(*weighted_choices) + >>> cumdist = list(itertools.accumulate(weights)) + >>> x = random.random() * cumdist[-1] + >>> choices[bisect.bisect(cumdist, x)] + 'Blue' From python-checkins at python.org Thu Dec 2 03:58:07 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 03:58:07 +0100 (CET) Subject: [Python-checkins] r86925 - in python/branches/py3k: Lib/netrc.py Lib/test/test_netrc.py Misc/ACKS Misc/NEWS Message-ID: <20101202025807.6133EF9A0@mail.python.org> Author: r.david.murray Date: Thu Dec 2 03:58:07 2010 New Revision: 86925 Log: #10464: fix netrc handling of lines with embedded '#" characters. Patch by Xuanji Li. Modified: python/branches/py3k/Lib/netrc.py python/branches/py3k/Lib/test/test_netrc.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/netrc.py ============================================================================== --- python/branches/py3k/Lib/netrc.py (original) +++ python/branches/py3k/Lib/netrc.py Thu Dec 2 03:58:07 2010 @@ -34,11 +34,15 @@ def _parse(self, file, fp): lexer = shlex.shlex(fp) lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" + lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword toplevel = tt = lexer.get_token() if not tt: break + elif tt[0] == '#': + fp.readline(); + continue; elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': Modified: python/branches/py3k/Lib/test/test_netrc.py ============================================================================== --- python/branches/py3k/Lib/test/test_netrc.py (original) +++ python/branches/py3k/Lib/test/test_netrc.py Thu Dec 2 03:58:07 2010 @@ -3,7 +3,13 @@ from test import support TEST_NETRC = """ + + #this is a comment +#this is a comment +# this is a comment + machine foo login log1 password pass1 account acct1 +machine bar login log1 password pass# account acct1 macdef macro1 line1 @@ -28,17 +34,21 @@ fp = open(temp_filename, mode) fp.write(TEST_NETRC) fp.close() + self.nrc = netrc.netrc(temp_filename) def tearDown(self): os.unlink(temp_filename) def test_case_1(self): - nrc = netrc.netrc(temp_filename) - self.assertTrue(nrc.macros == {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']} - ) - self.assertTrue(nrc.hosts['foo'] == ('log1', 'acct1', 'pass1')) - self.assertTrue(nrc.hosts['default'] == ('log2', None, 'pass2')) + self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) + self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + + def test_macros(self): + self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], + 'macro2':['line3\n', 'line4\n']}) + + def test_parses_passwords_with_hash_character(self): + self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) def test_main(): support.run_unittest(NetrcTestCase) Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Thu Dec 2 03:58:07 2010 @@ -501,6 +501,7 @@ Christopher Tur Lesniewski-Laas Mark Levinson William Lewis +Xuanji Li Robert van Liere Ross Light Shawn Ligocki Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 03:58:07 2010 @@ -46,6 +46,8 @@ Library ------- +- Issue #10464: netrc now correctly handles lines with embedded '#' characters. + - Added itertools.accumulate(). - Issue #4113: Added custom ``__repr__`` method to ``functools.partial``. From python-checkins at python.org Thu Dec 2 04:10:44 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 04:10:44 +0100 (CET) Subject: [Python-checkins] r86926 - in python/branches/release31-maint: Lib/netrc.py Lib/test/test_netrc.py Misc/ACKS Misc/NEWS Message-ID: <20101202031044.26BFFEE9E7@mail.python.org> Author: r.david.murray Date: Thu Dec 2 04:10:43 2010 New Revision: 86926 Log: Merged revisions 86925 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86925 | r.david.murray | 2010-12-01 21:58:07 -0500 (Wed, 01 Dec 2010) | 4 lines #10464: fix netrc handling of lines with embedded '#" characters. Patch by Xuanji Li. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/netrc.py python/branches/release31-maint/Lib/test/test_netrc.py python/branches/release31-maint/Misc/ACKS python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/netrc.py ============================================================================== --- python/branches/release31-maint/Lib/netrc.py (original) +++ python/branches/release31-maint/Lib/netrc.py Thu Dec 2 04:10:43 2010 @@ -34,11 +34,15 @@ def _parse(self, file, fp): lexer = shlex.shlex(fp) lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" + lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword toplevel = tt = lexer.get_token() if not tt: break + elif tt[0] == '#': + fp.readline(); + continue; elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': Modified: python/branches/release31-maint/Lib/test/test_netrc.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_netrc.py (original) +++ python/branches/release31-maint/Lib/test/test_netrc.py Thu Dec 2 04:10:43 2010 @@ -3,7 +3,13 @@ from test import support TEST_NETRC = """ + + #this is a comment +#this is a comment +# this is a comment + machine foo login log1 password pass1 account acct1 +machine bar login log1 password pass# account acct1 macdef macro1 line1 @@ -28,17 +34,21 @@ fp = open(temp_filename, mode) fp.write(TEST_NETRC) fp.close() + self.nrc = netrc.netrc(temp_filename) def tearDown(self): os.unlink(temp_filename) def test_case_1(self): - nrc = netrc.netrc(temp_filename) - self.assertTrue(nrc.macros == {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']} - ) - self.assertTrue(nrc.hosts['foo'] == ('log1', 'acct1', 'pass1')) - self.assertTrue(nrc.hosts['default'] == ('log2', None, 'pass2')) + self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) + self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + + def test_macros(self): + self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], + 'macro2':['line3\n', 'line4\n']}) + + def test_parses_passwords_with_hash_character(self): + self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) def test_main(): support.run_unittest(NetrcTestCase) Modified: python/branches/release31-maint/Misc/ACKS ============================================================================== --- python/branches/release31-maint/Misc/ACKS (original) +++ python/branches/release31-maint/Misc/ACKS Thu Dec 2 04:10:43 2010 @@ -468,6 +468,7 @@ Christopher Tur Lesniewski-Laas Mark Levinson William Lewis +Xuanji Li Robert van Liere Ross Light Shawn Ligocki Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Dec 2 04:10:43 2010 @@ -13,6 +13,8 @@ Library ------- +- Issue #10464: netrc now correctly handles lines with embedded '#' characters. + What's New in Python 3.1.3? =========================== From ncoghlan at gmail.com Thu Dec 2 04:14:12 2010 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 2 Dec 2010 13:14:12 +1000 Subject: [Python-checkins] r86924 - python/branches/py3k/Doc/library/random.rst In-Reply-To: <20101202024133.CCAF1EE985@mail.python.org> References: <20101202024133.CCAF1EE985@mail.python.org> Message-ID: On Thu, Dec 2, 2010 at 12:41 PM, raymond.hettinger wrote: > +A more general approach is to arrange the weights in a cumulative probability > +distribution with :func:`itertools.accumulate`, and then locate the random value > +with :func:`bisect.bisect`:: > + > + ? ?>>> choices, weights = zip(*weighted_choices) > + ? ?>>> cumdist = list(itertools.accumulate(weights)) > + ? ?>>> x = random.random() * cumdist[-1] > + ? ?>>> choices[bisect.bisect(cumdist, x)] > + ? ?'Blue' Neat example, although it would be easier to follow if you broke that last line into two pieces: .>>> random_index = bisect.bisect(cumdist, x) .>>> choices[random_index] 'Blue' It took me a moment to remember how bisect.bisect worked, but it would have been instant if the return value was assigned to an appropriately named variable. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Thu Dec 2 04:16:23 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 04:16:23 +0100 (CET) Subject: [Python-checkins] r86927 - in python/branches/release27-maint: Lib/netrc.py Lib/test/test_netrc.py Misc/ACKS Misc/NEWS Message-ID: <20101202031623.44F41EE9BF@mail.python.org> Author: r.david.murray Date: Thu Dec 2 04:16:23 2010 New Revision: 86927 Log: Merged revisions 86925 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86925 | r.david.murray | 2010-12-01 21:58:07 -0500 (Wed, 01 Dec 2010) | 4 lines #10464: fix netrc handling of lines with embedded '#" characters. Patch by Xuanji Li. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/netrc.py python/branches/release27-maint/Lib/test/test_netrc.py python/branches/release27-maint/Misc/ACKS python/branches/release27-maint/Misc/NEWS Modified: python/branches/release27-maint/Lib/netrc.py ============================================================================== --- python/branches/release27-maint/Lib/netrc.py (original) +++ python/branches/release27-maint/Lib/netrc.py Thu Dec 2 04:16:23 2010 @@ -34,11 +34,15 @@ def _parse(self, file, fp): lexer = shlex.shlex(fp) lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" + lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword toplevel = tt = lexer.get_token() if not tt: break + elif tt[0] == '#': + fp.readline(); + continue; elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': Modified: python/branches/release27-maint/Lib/test/test_netrc.py ============================================================================== --- python/branches/release27-maint/Lib/test/test_netrc.py (original) +++ python/branches/release27-maint/Lib/test/test_netrc.py Thu Dec 2 04:16:23 2010 @@ -3,7 +3,13 @@ from test import test_support TEST_NETRC = """ + + #this is a comment +#this is a comment +# this is a comment + machine foo login log1 password pass1 account acct1 +machine bar login log1 password pass# account acct1 macdef macro1 line1 @@ -28,18 +34,21 @@ fp = open(temp_filename, mode) fp.write(TEST_NETRC) fp.close() - self.netrc = netrc.netrc(temp_filename) + self.nrc = netrc.netrc(temp_filename) def tearDown (self): - del self.netrc os.unlink(temp_filename) def test_case_1(self): - self.assertTrue(self.netrc.macros == {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']} - ) - self.assertTrue(self.netrc.hosts['foo'] == ('log1', 'acct1', 'pass1')) - self.assertTrue(self.netrc.hosts['default'] == ('log2', None, 'pass2')) + self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) + self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + + def test_macros(self): + self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], + 'macro2':['line3\n', 'line4\n']}) + + def test_parses_passwords_with_hash_character(self): + self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) def test_main(): test_support.run_unittest(NetrcTestCase) Modified: python/branches/release27-maint/Misc/ACKS ============================================================================== --- python/branches/release27-maint/Misc/ACKS (original) +++ python/branches/release27-maint/Misc/ACKS Thu Dec 2 04:16:23 2010 @@ -472,6 +472,7 @@ Christopher Tur Lesniewski-Laas Mark Levinson William Lewis +Xuanji Li Robert van Liere Ross Light Shawn Ligocki Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Thu Dec 2 04:16:23 2010 @@ -13,6 +13,8 @@ Library ------- +- Issue #10464: netrc now correctly handles lines with embedded '#' characters. + What's New in Python 2.7.1? =========================== From solipsis at pitrou.net Thu Dec 2 04:49:08 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 02 Dec 2010 04:49:08 +0100 Subject: [Python-checkins] Daily py3k reference leaks (r86923): sum=0 Message-ID: py3k results for svn r86923 (hg cset 735f74e110e8) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogpF2Qot', '-x'] From python-checkins at python.org Thu Dec 2 05:11:46 2010 From: python-checkins at python.org (nick.coghlan) Date: Thu, 2 Dec 2010 05:11:46 +0100 (CET) Subject: [Python-checkins] r86928 - in python/branches/py3k: Lib/test/test_fork1.py Misc/NEWS Python/import.c Message-ID: <20101202041146.622C7EE994@mail.python.org> Author: nick.coghlan Date: Thu Dec 2 05:11:46 2010 New Revision: 86928 Log: Issue #9573: os.fork now works when triggered as a side effect of import (the wisdom of actually relying on this remains questionable!) Modified: python/branches/py3k/Lib/test/test_fork1.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/import.c Modified: python/branches/py3k/Lib/test/test_fork1.py ============================================================================== --- python/branches/py3k/Lib/test/test_fork1.py (original) +++ python/branches/py3k/Lib/test/test_fork1.py Thu Dec 2 05:11:46 2010 @@ -8,13 +8,14 @@ import time from test.fork_wait import ForkWait -from test.support import run_unittest, reap_children, get_attribute, import_module +from test.support import (run_unittest, reap_children, get_attribute, + import_module, verbose) + threading = import_module('threading') # Skip test if fork does not exist. get_attribute(os, 'fork') - class ForkTest(ForkWait): def wait_impl(self, cpid): for i in range(10): @@ -28,7 +29,8 @@ self.assertEqual(spid, cpid) self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8)) - def test_import_lock_fork(self): + def test_threaded_import_lock_fork(self): + """Check fork() in main thread works while a subthread is doing an import""" import_started = threading.Event() fake_module_name = "fake test module" partial_module = "partial" @@ -45,11 +47,16 @@ import_started.wait() pid = os.fork() try: + # PyOS_BeforeFork should have waited for the import to complete + # before forking, so the child can recreate the import lock + # correctly, but also won't see a partially initialised module if not pid: m = __import__(fake_module_name) if m == complete_module: os._exit(0) else: + if verbose > 1: + print("Child encountered partial module") os._exit(1) else: t.join() @@ -63,6 +70,39 @@ except OSError: pass + + def test_nested_import_lock_fork(self): + """Check fork() in main thread works while the main thread is doing an import""" + # Issue 9573: this used to trigger RuntimeError in the child process + def fork_with_import_lock(level): + release = 0 + in_child = False + try: + try: + for i in range(level): + imp.acquire_lock() + release += 1 + pid = os.fork() + in_child = not pid + finally: + for i in range(release): + imp.release_lock() + except RuntimeError: + if in_child: + if verbose > 1: + print("RuntimeError in child") + os._exit(1) + raise + if in_child: + os._exit(0) + self.wait_impl(pid) + + # Check this works with various levels of nested + # import in the main thread + for level in range(5): + fork_with_import_lock(level) + + def test_main(): run_unittest(ForkTest) reap_children() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 05:11:46 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #9573: os.fork() now works correctly when triggered as a side effect + of a module import + - Issue #10464: netrc now correctly handles lines with embedded '#' characters. - Added itertools.accumulate(). Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Thu Dec 2 05:11:46 2010 @@ -325,8 +325,17 @@ { if (import_lock != NULL) import_lock = PyThread_allocate_lock(); - import_lock_thread = -1; - import_lock_level = 0; + if (import_lock_level > 1) { + /* Forked as a side effect of import */ + long me = PyThread_get_thread_ident(); + PyThread_acquire_lock(import_lock, 0); + /* XXX: can the previous line fail? */ + import_lock_thread = me; + import_lock_level--; + } else { + import_lock_thread = -1; + import_lock_level = 0; + } } #endif From python-checkins at python.org Thu Dec 2 06:35:36 2010 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 2 Dec 2010 06:35:36 +0100 (CET) Subject: [Python-checkins] r86929 - python/branches/py3k/Doc/library/random.rst Message-ID: <20101202053536.46D81EE989@mail.python.org> Author: raymond.hettinger Date: Thu Dec 2 06:35:35 2010 New Revision: 86929 Log: Neaten-up random module docs. Modified: python/branches/py3k/Doc/library/random.rst Modified: python/branches/py3k/Doc/library/random.rst ============================================================================== --- python/branches/py3k/Doc/library/random.rst (original) +++ python/branches/py3k/Doc/library/random.rst Thu Dec 2 06:35:35 2010 @@ -233,41 +233,18 @@ parameter. -Alternative Generators: +Alternative Generator: .. class:: SystemRandom([seed]) Class that uses the :func:`os.urandom` function for generating random numbers from sources provided by the operating system. Not available on all systems. - Does not rely on software state and sequences are not reproducible. Accordingly, + Does not rely on software state, and sequences are not reproducible. Accordingly, the :meth:`seed` method has no effect and is ignored. The :meth:`getstate` and :meth:`setstate` methods raise :exc:`NotImplementedError` if called. -Examples of basic usage:: - - >>> random.random() # Random float x, 0.0 <= x < 1.0 - 0.37444887175646646 - >>> random.uniform(1, 10) # Random float x, 1.0 <= x < 10.0 - 1.1800146073117523 - >>> random.randint(1, 10) # Integer from 1 to 10, endpoints included - 7 - >>> random.randrange(0, 101, 2) # Even integer from 0 to 100 - 26 - >>> random.choice('abcdefghij') # Choose a random element - 'c' - - >>> items = [1, 2, 3, 4, 5, 6, 7] - >>> random.shuffle(items) - >>> items - [7, 3, 2, 5, 6, 4, 1] - - >>> random.sample([1, 2, 3, 4, 5], 3) # Choose 3 elements - [4, 1, 5] - - - .. seealso:: M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-dimensionally @@ -280,6 +257,7 @@ random number generator with a long period and comparatively simple update operations. + Notes on Reproducibility ======================== @@ -297,11 +275,34 @@ sequence when the compatible seeder is given the same seed. -.. _random-examples: - Examples and Recipes ==================== +Basic usage:: + + >>> random.random() # Random float x, 0.0 <= x < 1.0 + 0.37444887175646646 + + >>> random.uniform(1, 10) # Random float x, 1.0 <= x < 10.0 + 1.1800146073117523 + + >>> random.randrange(10) # Integer from 0 to 9 + 7 + + >>> random.randrange(0, 101, 2) # Even integer from 0 to 100 + 26 + + >>> random.choice('abcdefghij') # Single random element + 'c' + + >>> items = [1, 2, 3, 4, 5, 6, 7] + >>> random.shuffle(items) + >>> items + [7, 3, 2, 5, 6, 4, 1] + + >>> random.sample([1, 2, 3, 4, 5], 3) # Three samples without replacement + [4, 1, 5] + A common task is to make a :func:`random.choice` with weighted probababilites. If the weights are small integer ratios, a simple technique is to build a sample @@ -312,9 +313,9 @@ >>> random.choice(population) 'Green' -A more general approach is to arrange the weights in a cumulative probability -distribution with :func:`itertools.accumulate`, and then locate the random value -with :func:`bisect.bisect`:: +A more general approach is to arrange the weights in a cumulative distribution +with :func:`itertools.accumulate`, and then locate the random value with +:func:`bisect.bisect`:: >>> choices, weights = zip(*weighted_choices) >>> cumdist = list(itertools.accumulate(weights)) From python-checkins at python.org Thu Dec 2 08:05:57 2010 From: python-checkins at python.org (terry.reedy) Date: Thu, 2 Dec 2010 08:05:57 +0100 (CET) Subject: [Python-checkins] r86930 - in python/branches/py3k: Doc/library/os.rst Lib/os.py Lib/test/test_os.py Misc/ACKS Misc/NEWS Message-ID: <20101202070557.1D971EE98C@mail.python.org> Author: terry.reedy Date: Thu Dec 2 08:05:56 2010 New Revision: 86930 Log: Issue 9299 Add exist_ok parameter to os.makedirs to suppress 'File exists' exception. Patch by Ray Allen. Modified: python/branches/py3k/Doc/library/os.rst python/branches/py3k/Lib/os.py python/branches/py3k/Lib/test/test_os.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Thu Dec 2 08:05:56 2010 @@ -1143,17 +1143,20 @@ Availability: Unix, Windows. -.. function:: makedirs(path[, mode]) +.. function:: makedirs(path[, mode][, exist_ok=False]) .. index:: single: directory; creating single: UNC paths; and os.makedirs() Recursive directory creation function. Like :func:`mkdir`, but makes all - intermediate-level directories needed to contain the leaf directory. Raises - an :exc:`error` exception if the leaf directory already exists or cannot be - created. The default *mode* is ``0o777`` (octal). On some systems, *mode* - is ignored. Where it is used, the current umask value is first masked out. + intermediate-level directories needed to contain the leaf directory. If + the target directory with the same mode as we specified already exists, + raises an :exc:`OSError` exception if *exist_ok* is False, otherwise no + exception is raised. If the directory cannot be created in other cases, + raises an :exc:`OSError` exception. The default *mode* is ``0o777`` (octal). + On some systems, *mode* is ignored. Where it is used, the current umask + value is first masked out. .. note:: @@ -1162,6 +1165,9 @@ This function handles UNC paths correctly. + .. versionadded:: 3.2 + The *exist_ok* parameter. + .. function:: pathconf(path, name) Modified: python/branches/py3k/Lib/os.py ============================================================================== --- python/branches/py3k/Lib/os.py (original) +++ python/branches/py3k/Lib/os.py Thu Dec 2 08:05:56 2010 @@ -114,18 +114,26 @@ SEEK_CUR = 1 SEEK_END = 2 + +def _get_masked_mode(mode): + mask = umask(0) + umask(mask) + return mode & ~mask + #' # Super directory utilities. # (Inspired by Eric Raymond; the doc strings are mostly his) -def makedirs(name, mode=0o777): - """makedirs(path [, mode=0o777]) +def makedirs(name, mode=0o777, exist_ok=False): + """makedirs(path [, mode=0o777][, exist_ok=False]) Super-mkdir; create a leaf directory and all intermediate ones. Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. This is - recursive. + just the rightmost) will be created if it does not exist. If the + target directory with the same mode as we specified already exists, + raises an OSError if exist_ok is False, otherwise no exception is + raised. This is recursive. """ head, tail = path.split(name) @@ -133,14 +141,20 @@ head, tail = path.split(head) if head and tail and not path.exists(head): try: - makedirs(head, mode) + makedirs(head, mode, exist_ok) except OSError as e: # be happy if someone already created the path if e.errno != errno.EEXIST: raise if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists return - mkdir(name, mode) + try: + mkdir(name, mode) + except OSError as e: + import stat as st + if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and + st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)): + raise def removedirs(name): """removedirs(path) Modified: python/branches/py3k/Lib/test/test_os.py ============================================================================== --- python/branches/py3k/Lib/test/test_os.py (original) +++ python/branches/py3k/Lib/test/test_os.py Thu Dec 2 08:05:56 2010 @@ -630,6 +630,28 @@ 'dir5', 'dir6') os.makedirs(path) + def test_exist_ok_existing_directory(self): + path = os.path.join(support.TESTFN, 'dir1') + mode = 0o777 + old_mask = os.umask(0o022) + os.makedirs(path, mode) + self.assertRaises(OSError, os.makedirs, path, mode) + self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False) + self.assertRaises(OSError, os.makedirs, path, 0o776, exist_ok=True) + os.makedirs(path, mode=mode, exist_ok=True) + os.umask(old_mask) + + def test_exist_ok_existing_regular_file(self): + base = support.TESTFN + path = os.path.join(support.TESTFN, 'dir1') + f = open(path, 'w') + f.write('abc') + f.close() + self.assertRaises(OSError, os.makedirs, path) + self.assertRaises(OSError, os.makedirs, path, exist_ok=False) + self.assertRaises(OSError, os.makedirs, path, exist_ok=True) + os.remove(path) + def tearDown(self): path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', 'dir6') Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Thu Dec 2 08:05:56 2010 @@ -18,6 +18,7 @@ Nir Aides Yaniv Aknin Jyrki Alakuijala +Ray Allen Billy G. Allie Kevin Altis Joe Amenta Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 08:05:56 2010 @@ -46,6 +46,10 @@ Library ------- +- Issue #9299: Add exist_ok parameter to os.makedirs to suppress the + 'File exists' exception when a target directory already exists with the + specified mode. Patch by Ray Allen. + - Issue #9573: os.fork() now works correctly when triggered as a side effect of a module import From python-checkins at python.org Thu Dec 2 10:06:13 2010 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Dec 2010 10:06:13 +0100 (CET) Subject: [Python-checkins] r86931 - python/branches/py3k/Doc/library/os.rst Message-ID: <20101202090613.093E5EE98C@mail.python.org> Author: georg.brandl Date: Thu Dec 2 10:06:12 2010 New Revision: 86931 Log: Fix-up documentation of makedirs(). Modified: python/branches/py3k/Doc/library/os.rst Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Thu Dec 2 10:06:12 2010 @@ -1143,7 +1143,7 @@ Availability: Unix, Windows. -.. function:: makedirs(path[, mode][, exist_ok=False]) +.. function:: makedirs(path, mode=0o777, exist_ok=False) .. index:: single: directory; creating @@ -1151,17 +1151,17 @@ Recursive directory creation function. Like :func:`mkdir`, but makes all intermediate-level directories needed to contain the leaf directory. If - the target directory with the same mode as we specified already exists, + the target directory with the same mode as specified already exists, raises an :exc:`OSError` exception if *exist_ok* is False, otherwise no exception is raised. If the directory cannot be created in other cases, raises an :exc:`OSError` exception. The default *mode* is ``0o777`` (octal). - On some systems, *mode* is ignored. Where it is used, the current umask + On some systems, *mode* is ignored. Where it is used, the current umask value is first masked out. .. note:: - :func:`makedirs` will become confused if the path elements to create include - :data:`os.pardir`. + :func:`makedirs` will become confused if the path elements to create + include :data:`pardir`. This function handles UNC paths correctly. From ncoghlan at gmail.com Thu Dec 2 10:32:19 2010 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 2 Dec 2010 19:32:19 +1000 Subject: [Python-checkins] r86930 - in python/branches/py3k: Doc/library/os.rst Lib/os.py Lib/test/test_os.py Misc/ACKS Misc/NEWS In-Reply-To: <20101202070557.1D971EE98C@mail.python.org> References: <20101202070557.1D971EE98C@mail.python.org> Message-ID: On Thu, Dec 2, 2010 at 5:05 PM, terry.reedy wrote: > + If > + ? the target directory with the same mode as we specified already exists, > + ? raises an :exc:`OSError` exception if *exist_ok* is False, otherwise no > + ? exception is raised. ?If the directory cannot be created in other cases, > + ? raises an :exc:`OSError` exception. I would suggest being explicit here that "directory exists, but has a mode other than the one requested" always triggers an exception. Perhaps something like the following: "Raises an :exc:`OSError` exception if the target directory already exists, unless *exist_ok* is True and the existing directory has the same mode as is specified in the current call. Also raises an :exc:`OSError` exception if the directory cannot be created for any other reason." Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From ocean-city at m2.ccsnet.ne.jp Thu Dec 2 16:50:51 2010 From: ocean-city at m2.ccsnet.ne.jp (Hirokazu Yamamoto) Date: Fri, 03 Dec 2010 00:50:51 +0900 Subject: [Python-checkins] r86817 - python/branches/py3k-stat-on-windows/Lib/test/test_shutil.py In-Reply-To: References: <20101126184428.E04A0EE984@mail.python.org> <4CF00E4E.6030507@m2.ccsnet.ne.jp> <4CF01632.8070504@m2.ccsnet.ne.jp> Message-ID: <4CF7C05B.7030909@m2.ccsnet.ne.jp> On 2010/11/27 5:31, Brian Curtin wrote: > On Fri, Nov 26, 2010 at 14:18, Hirokazu Yamamoto> wrote: > >> On 2010/11/27 5:02, Brian Curtin wrote: >> >>> We briefly chatted about this on the os.link >>> feature issue, but I never found a way around it. >>> >> >> How about implementing os.path.samefile in >> Modules/posixmodule.c like this? >> >> http://bugs.python.org/file19262/py3k_fix_kill_python_for_short_path.patch >> >> # I hope this works. >> > > That's almost identical to what the current os.path.sameopenfile is. > > Lib/ntpath.py opens both files, then compares them via _getfileinformation. > That function is implemented to take in a file descriptor, call > GetFileInformationByHandle with it, then returns a tuple > of dwVolumeSerialNumber, nFileIndexHigh, and nFileIndexLow. > Yes. Difference is, file object cannot represent directory, and probably FILE_FLAG_BACKUP_SEMANTICS makes it faster to open file. From python-checkins at python.org Thu Dec 2 17:41:00 2010 From: python-checkins at python.org (david.malcolm) Date: Thu, 2 Dec 2010 17:41:00 +0100 (CET) Subject: [Python-checkins] r86932 - python/branches/py3k/Lib/urllib/parse.py Message-ID: <20101202164100.567B4EE9EA@mail.python.org> Author: david.malcolm Date: Thu Dec 2 17:41:00 2010 New Revision: 86932 Log: Fix spelling of Jamie Zawinski's surname in urllib.parse docstring (issue 10606) Modified: python/branches/py3k/Lib/urllib/parse.py Modified: python/branches/py3k/Lib/urllib/parse.py ============================================================================== --- python/branches/py3k/Lib/urllib/parse.py (original) +++ python/branches/py3k/Lib/urllib/parse.py Thu Dec 2 17:41:00 2010 @@ -11,7 +11,7 @@ RFC 2396: "Uniform Resource Identifiers (URI)": Generic Syntax by T. Berners-Lee, R. Fielding, and L. Masinter, August 1998. -RFC 2368: "The mailto URL scheme", by P.Hoffman , L Masinter, J. Zwinski, July 1998. +RFC 2368: "The mailto URL scheme", by P.Hoffman , L Masinter, J. Zawinski, July 1998. RFC 1808: "Relative Uniform Resource Locators", by R. Fielding, UC Irvine, June 1995. From python-checkins at python.org Thu Dec 2 19:02:02 2010 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Dec 2010 19:02:02 +0100 (CET) Subject: [Python-checkins] r86933 - python/branches/py3k/Doc/c-api/init.rst Message-ID: <20101202180202.4C1ADEE9AA@mail.python.org> Author: georg.brandl Date: Thu Dec 2 19:02:01 2010 New Revision: 86933 Log: #10597: fix Py_SetPythonHome docs by pointing to where the meaning of PYTHONHOME is already documented. Modified: python/branches/py3k/Doc/c-api/init.rst Modified: python/branches/py3k/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k/Doc/c-api/init.rst (original) +++ python/branches/py3k/Doc/c-api/init.rst Thu Dec 2 19:02:01 2010 @@ -412,8 +412,9 @@ .. c:function:: void Py_SetPythonHome(wchar_t *home) Set the default "home" directory, that is, the location of the standard - Python libraries. The libraries are searched in - :file:`{home}/lib/python{version}` and :file:`{home}/lib/python{version}`. + Python libraries. See :envvar:`PYTHONHOME` for the meaning of the + argument string. + The argument should point to a zero-terminated character string in static storage whose contents will not change for the duration of the program's execution. No code in the Python interpreter will change the contents of From python-checkins at python.org Thu Dec 2 19:06:51 2010 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Dec 2010 19:06:51 +0100 (CET) Subject: [Python-checkins] r86934 - in python/branches/py3k: Doc/library/codecs.rst Doc/library/stdtypes.rst Lib/codecs.py Lib/encodings/aliases.py Lib/encodings/base64_codec.py Lib/encodings/bz2_codec.py Lib/encodings/hex_codec.py Lib/encodings/quopri_codec.py Lib/encodings/rot_13.py Lib/encodings/uu_codec.py Lib/encodings/zlib_codec.py Lib/test/test_bytes.py Lib/test/test_codecs.py Misc/NEWS Objects/bytearrayobject.c Objects/bytesobject.c Objects/unicodeobject.c Message-ID: <20101202180651.F2AB0EE9CD@mail.python.org> Author: georg.brandl Date: Thu Dec 2 19:06:51 2010 New Revision: 86934 Log: #7475: add (un)transform method to bytes/bytearray and str, add back codecs that can be used with them from Python 2. Added: python/branches/py3k/Lib/encodings/base64_codec.py (contents, props changed) python/branches/py3k/Lib/encodings/bz2_codec.py (contents, props changed) python/branches/py3k/Lib/encodings/hex_codec.py (contents, props changed) python/branches/py3k/Lib/encodings/quopri_codec.py (contents, props changed) python/branches/py3k/Lib/encodings/rot_13.py (contents, props changed) python/branches/py3k/Lib/encodings/uu_codec.py (contents, props changed) python/branches/py3k/Lib/encodings/zlib_codec.py (contents, props changed) Modified: python/branches/py3k/Doc/library/codecs.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Lib/codecs.py python/branches/py3k/Lib/encodings/aliases.py python/branches/py3k/Lib/test/test_bytes.py python/branches/py3k/Lib/test/test_codecs.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytesobject.c python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Doc/library/codecs.rst ============================================================================== --- python/branches/py3k/Doc/library/codecs.rst (original) +++ python/branches/py3k/Doc/library/codecs.rst Thu Dec 2 19:06:51 2010 @@ -1165,6 +1165,46 @@ | | | operand | +--------------------+---------+---------------------------+ +The following codecs provide bytes-to-bytes mappings. They can be used with +:meth:`bytes.transform` and :meth:`bytes.untransform`. + ++--------------------+---------------------------+---------------------------+ +| Codec | Aliases | Purpose | ++====================+===========================+===========================+ +| base64_codec | base64, base-64 | Convert operand to MIME | +| | | base64 | ++--------------------+---------------------------+---------------------------+ +| bz2_codec | bz2 | Compress the operand | +| | | using bz2 | ++--------------------+---------------------------+---------------------------+ +| hex_codec | hex | Convert operand to | +| | | hexadecimal | +| | | representation, with two | +| | | digits per byte | ++--------------------+---------------------------+---------------------------+ +| quopri_codec | quopri, quoted-printable, | Convert operand to MIME | +| | quotedprintable | quoted printable | ++--------------------+---------------------------+---------------------------+ +| uu_codec | uu | Convert the operand using | +| | | uuencode | ++--------------------+---------------------------+---------------------------+ +| zlib_codec | zip, zlib | Compress the operand | +| | | using gzip | ++--------------------+---------------------------+---------------------------+ + +The following codecs provide string-to-string mappings. They can be used with +:meth:`str.transform` and :meth:`str.untransform`. + ++--------------------+---------------------------+---------------------------+ +| Codec | Aliases | Purpose | ++====================+===========================+===========================+ +| rot_13 | rot13 | Returns the Caesar-cypher | +| | | encryption of the operand | ++--------------------+---------------------------+---------------------------+ + +.. versionadded:: 3.2 + bytes-to-bytes and string-to-string codecs. + :mod:`encodings.idna` --- Internationalized Domain Names in Applications ------------------------------------------------------------------------ Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Thu Dec 2 19:06:51 2010 @@ -1352,6 +1352,19 @@ "They're Bill's Friends." +.. method:: str.transform(encoding, errors='strict') + + Return an encoded version of the string. In contrast to :meth:`encode`, this + method works with codecs that provide string-to-string mappings, and not + string-to-bytes mappings. :meth:`transform` therefore returns a string + object. + + The codecs that can be used with this method are listed in + :ref:`standard-encodings`. + + .. versionadded:: 3.2 + + .. method:: str.translate(map) Return a copy of the *s* where all characters have been mapped through the @@ -1369,6 +1382,14 @@ example). +.. method:: str.untransform(encoding, errors='strict') + + Return a decoded version of the string. This provides the reverse operation + of :meth:`transform`. + + .. versionadded:: 3.2 + + .. method:: str.upper() Return a copy of the string converted to uppercase. @@ -1800,6 +1821,20 @@ The maketrans and translate methods differ in semantics from the versions available on strings: +.. method:: bytes.transform(encoding, errors='strict') + bytearray.transform(encoding, errors='strict') + + Return an encoded version of the bytes object. In contrast to + :meth:`encode`, this method works with codecs that provide bytes-to-bytes + mappings, and not string-to-bytes mappings. :meth:`transform` therefore + returns a bytes or bytearray object. + + The codecs that can be used with this method are listed in + :ref:`standard-encodings`. + + .. versionadded:: 3.2 + + .. method:: bytes.translate(table[, delete]) bytearray.translate(table[, delete]) @@ -1817,6 +1852,15 @@ b'rd ths shrt txt' +.. method:: bytes.untransform(encoding, errors='strict') + bytearray.untransform(encoding, errors='strict') + + Return an decoded version of the bytes object. This provides the reverse + operation of :meth:`transform`. + + .. versionadded:: 3.2 + + .. staticmethod:: bytes.maketrans(from, to) bytearray.maketrans(from, to) Modified: python/branches/py3k/Lib/codecs.py ============================================================================== --- python/branches/py3k/Lib/codecs.py (original) +++ python/branches/py3k/Lib/codecs.py Thu Dec 2 19:06:51 2010 @@ -396,6 +396,8 @@ class StreamReader(Codec): + charbuffertype = str + def __init__(self, stream, errors='strict'): """ Creates a StreamReader instance. @@ -417,9 +419,8 @@ self.stream = stream self.errors = errors self.bytebuffer = b"" - # For str->str decoding this will stay a str - # For str->unicode decoding the first read will promote it to unicode - self.charbuffer = "" + self._empty_charbuffer = self.charbuffertype() + self.charbuffer = self._empty_charbuffer self.linebuffer = None def decode(self, input, errors='strict'): @@ -455,7 +456,7 @@ """ # If we have lines cached, first merge them back into characters if self.linebuffer: - self.charbuffer = "".join(self.linebuffer) + self.charbuffer = self._empty_charbuffer.join(self.linebuffer) self.linebuffer = None # read until we get the required number of characters (if available) @@ -498,7 +499,7 @@ if chars < 0: # Return everything we've got result = self.charbuffer - self.charbuffer = "" + self.charbuffer = self._empty_charbuffer else: # Return the first chars characters result = self.charbuffer[:chars] @@ -529,7 +530,7 @@ return line readsize = size or 72 - line = "" + line = self._empty_charbuffer # If size is given, we call read() only once while True: data = self.read(readsize, firstline=True) @@ -537,7 +538,8 @@ # If we're at a "\r" read one extra character (which might # be a "\n") to get a proper line ending. If the stream is # temporarily exhausted we return the wrong line ending. - if data.endswith("\r"): + if (isinstance(data, str) and data.endswith("\r")) or \ + (isinstance(data, bytes) and data.endswith(b"\r")): data += self.read(size=1, chars=1) line += data @@ -563,7 +565,8 @@ line0withoutend = lines[0].splitlines(False)[0] if line0withend != line0withoutend: # We really have a line end # Put the rest back together and keep it until the next call - self.charbuffer = "".join(lines[1:]) + self.charbuffer + self.charbuffer = self._empty_charbuffer.join(lines[1:]) + \ + self.charbuffer if keepends: line = line0withend else: @@ -574,7 +577,7 @@ if line and not keepends: line = line.splitlines(False)[0] break - if readsize<8000: + if readsize < 8000: readsize *= 2 return line @@ -603,7 +606,7 @@ """ self.bytebuffer = b"" - self.charbuffer = "" + self.charbuffer = self._empty_charbuffer self.linebuffer = None def seek(self, offset, whence=0): Modified: python/branches/py3k/Lib/encodings/aliases.py ============================================================================== --- python/branches/py3k/Lib/encodings/aliases.py (original) +++ python/branches/py3k/Lib/encodings/aliases.py Thu Dec 2 19:06:51 2010 @@ -33,9 +33,9 @@ 'us' : 'ascii', 'us_ascii' : 'ascii', - ## base64_codec codec - #'base64' : 'base64_codec', - #'base_64' : 'base64_codec', + # base64_codec codec + 'base64' : 'base64_codec', + 'base_64' : 'base64_codec', # big5 codec 'big5_tw' : 'big5', @@ -45,8 +45,8 @@ 'big5_hkscs' : 'big5hkscs', 'hkscs' : 'big5hkscs', - ## bz2_codec codec - #'bz2' : 'bz2_codec', + # bz2_codec codec + 'bz2' : 'bz2_codec', # cp037 codec '037' : 'cp037', @@ -248,8 +248,8 @@ 'cp936' : 'gbk', 'ms936' : 'gbk', - ## hex_codec codec - #'hex' : 'hex_codec', + # hex_codec codec + 'hex' : 'hex_codec', # hp_roman8 codec 'roman8' : 'hp_roman8', @@ -450,13 +450,13 @@ 'cp154' : 'ptcp154', 'cyrillic_asian' : 'ptcp154', - ## quopri_codec codec - #'quopri' : 'quopri_codec', - #'quoted_printable' : 'quopri_codec', - #'quotedprintable' : 'quopri_codec', + # quopri_codec codec + 'quopri' : 'quopri_codec', + 'quoted_printable' : 'quopri_codec', + 'quotedprintable' : 'quopri_codec', - ## rot_13 codec - #'rot13' : 'rot_13', + # rot_13 codec + 'rot13' : 'rot_13', # shift_jis codec 'csshiftjis' : 'shift_jis', @@ -518,12 +518,12 @@ 'utf8_ucs2' : 'utf_8', 'utf8_ucs4' : 'utf_8', - ## uu_codec codec - #'uu' : 'uu_codec', + # uu_codec codec + 'uu' : 'uu_codec', - ## zlib_codec codec - #'zip' : 'zlib_codec', - #'zlib' : 'zlib_codec', + # zlib_codec codec + 'zip' : 'zlib_codec', + 'zlib' : 'zlib_codec', # temporary mac CJK aliases, will be replaced by proper codecs in 3.1 'x_mac_japanese' : 'shift_jis', Added: python/branches/py3k/Lib/encodings/base64_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/base64_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,55 @@ +"""Python 'base64_codec' Codec - base64 content transfer encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Written by Marc-Andre Lemburg (mal at lemburg.com). +""" + +import codecs +import base64 + +### Codec APIs + +def base64_encode(input, errors='strict'): + assert errors == 'strict' + return (base64.encodestring(input), len(input)) + +def base64_decode(input, errors='strict'): + assert errors == 'strict' + return (base64.decodestring(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return base64_encode(input, errors) + def decode(self, input, errors='strict'): + return base64_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return base64.encodestring(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return base64.decodestring(input) + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='base64', + encode=base64_encode, + decode=base64_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) Added: python/branches/py3k/Lib/encodings/bz2_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/bz2_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,77 @@ +"""Python 'bz2_codec' Codec - bz2 compression encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Adapted by Raymond Hettinger from zlib_codec.py which was written +by Marc-Andre Lemburg (mal at lemburg.com). +""" + +import codecs +import bz2 # this codec needs the optional bz2 module ! + +### Codec APIs + +def bz2_encode(input, errors='strict'): + assert errors == 'strict' + return (bz2.compress(input), len(input)) + +def bz2_decode(input, errors='strict'): + assert errors == 'strict' + return (bz2.decompress(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return bz2_encode(input, errors) + def decode(self, input, errors='strict'): + return bz2_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = bz2.BZ2Compressor() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = bz2.BZ2Compressor() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = bz2.BZ2Decompressor() + + def decode(self, input, final=False): + try: + return self.decompressobj.decompress(input) + except EOFError: + return '' + + def reset(self): + self.decompressobj = bz2.BZ2Decompressor() + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name="bz2", + encode=bz2_encode, + decode=bz2_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) Added: python/branches/py3k/Lib/encodings/hex_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/hex_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,55 @@ +"""Python 'hex_codec' Codec - 2-digit hex content transfer encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Written by Marc-Andre Lemburg (mal at lemburg.com). +""" + +import codecs +import binascii + +### Codec APIs + +def hex_encode(input, errors='strict'): + assert errors == 'strict' + return (binascii.b2a_hex(input), len(input)) + +def hex_decode(input, errors='strict'): + assert errors == 'strict' + return (binascii.a2b_hex(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return hex_encode(input, errors) + def decode(self, input, errors='strict'): + return hex_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return binascii.b2a_hex(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return binascii.a2b_hex(input) + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hex', + encode=hex_encode, + decode=hex_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) Added: python/branches/py3k/Lib/encodings/quopri_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/quopri_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,56 @@ +"""Codec for quoted-printable encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). +""" + +import codecs +import quopri +from io import BytesIO + +def quopri_encode(input, errors='strict'): + assert errors == 'strict' + f = BytesIO(input) + g = BytesIO() + quopri.encode(f, g, 1) + return (g.getvalue(), len(input)) + +def quopri_decode(input, errors='strict'): + assert errors == 'strict' + f = BytesIO(input) + g = BytesIO() + quopri.decode(f, g) + return (g.getvalue(), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return quopri_encode(input, errors) + def decode(self, input, errors='strict'): + return quopri_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return quopri_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return quopri_decode(input, self.errors)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +# encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='quopri', + encode=quopri_encode, + decode=quopri_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) Added: python/branches/py3k/Lib/encodings/rot_13.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/rot_13.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,113 @@ +#!/usr/bin/env python +""" Python Character Mapping Codec for ROT13. + +This codec de/encodes from str to str and is therefore usable with +str.transform() and str.untransform(). + +Written by Marc-Andre Lemburg (mal at lemburg.com). +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return (input.translate(rot13_map), len(input)) + + def decode(self, input, errors='strict'): + return (input.translate(rot13_map), len(input)) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return input.translate(rot13_map) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return input.translate(rot13_map) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='rot-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + +### Map + +rot13_map = codecs.make_identity_dict(range(256)) +rot13_map.update({ + 0x0041: 0x004e, + 0x0042: 0x004f, + 0x0043: 0x0050, + 0x0044: 0x0051, + 0x0045: 0x0052, + 0x0046: 0x0053, + 0x0047: 0x0054, + 0x0048: 0x0055, + 0x0049: 0x0056, + 0x004a: 0x0057, + 0x004b: 0x0058, + 0x004c: 0x0059, + 0x004d: 0x005a, + 0x004e: 0x0041, + 0x004f: 0x0042, + 0x0050: 0x0043, + 0x0051: 0x0044, + 0x0052: 0x0045, + 0x0053: 0x0046, + 0x0054: 0x0047, + 0x0055: 0x0048, + 0x0056: 0x0049, + 0x0057: 0x004a, + 0x0058: 0x004b, + 0x0059: 0x004c, + 0x005a: 0x004d, + 0x0061: 0x006e, + 0x0062: 0x006f, + 0x0063: 0x0070, + 0x0064: 0x0071, + 0x0065: 0x0072, + 0x0066: 0x0073, + 0x0067: 0x0074, + 0x0068: 0x0075, + 0x0069: 0x0076, + 0x006a: 0x0077, + 0x006b: 0x0078, + 0x006c: 0x0079, + 0x006d: 0x007a, + 0x006e: 0x0061, + 0x006f: 0x0062, + 0x0070: 0x0063, + 0x0071: 0x0064, + 0x0072: 0x0065, + 0x0073: 0x0066, + 0x0074: 0x0067, + 0x0075: 0x0068, + 0x0076: 0x0069, + 0x0077: 0x006a, + 0x0078: 0x006b, + 0x0079: 0x006c, + 0x007a: 0x006d, +}) + +### Filter API + +def rot13(infile, outfile): + outfile.write(infile.read().encode('rot-13')) + +if __name__ == '__main__': + import sys + rot13(sys.stdin, sys.stdout) Added: python/branches/py3k/Lib/encodings/uu_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/uu_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,99 @@ +"""Python 'uu_codec' Codec - UU content transfer encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Written by Marc-Andre Lemburg (mal at lemburg.com). Some details were +adapted from uu.py which was written by Lance Ellinghouse and +modified by Jack Jansen and Fredrik Lundh. +""" + +import codecs +import binascii +from io import BytesIO + +### Codec APIs + +def uu_encode(input, errors='strict', filename='', mode=0o666): + assert errors == 'strict' + infile = BytesIO(input) + outfile = BytesIO() + read = infile.read + write = outfile.write + + # Encode + write(('begin %o %s\n' % (mode & 0o777, filename)).encode('ascii')) + chunk = read(45) + while chunk: + write(binascii.b2a_uu(chunk)) + chunk = read(45) + write(b' \nend\n') + + return (outfile.getvalue(), len(input)) + +def uu_decode(input, errors='strict'): + assert errors == 'strict' + infile = BytesIO(input) + outfile = BytesIO() + readline = infile.readline + write = outfile.write + + # Find start of encoded data + while 1: + s = readline() + if not s: + raise ValueError('Missing "begin" line in input data') + if s[:5] == b'begin': + break + + # Decode + while True: + s = readline() + if not s or s == b'end\n': + break + try: + data = binascii.a2b_uu(s) + except binascii.Error as v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 + data = binascii.a2b_uu(s[:nbytes]) + #sys.stderr.write("Warning: %s\n" % str(v)) + write(data) + if not s: + raise ValueError('Truncated input data') + + return (outfile.getvalue(), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return uu_encode(input, errors) + + def decode(self, input, errors='strict'): + return uu_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return uu_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return uu_decode(input, self.errors)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='uu', + encode=uu_encode, + decode=uu_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) Added: python/branches/py3k/Lib/encodings/zlib_codec.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/encodings/zlib_codec.py Thu Dec 2 19:06:51 2010 @@ -0,0 +1,77 @@ +"""Python 'zlib_codec' Codec - zlib compression encoding. + +This codec de/encodes from bytes to bytes and is therefore usable with +bytes.transform() and bytes.untransform(). + +Written by Marc-Andre Lemburg (mal at lemburg.com). +""" + +import codecs +import zlib # this codec needs the optional zlib module ! + +### Codec APIs + +def zlib_encode(input, errors='strict'): + assert errors == 'strict' + return (zlib.compress(input), len(input)) + +def zlib_decode(input, errors='strict'): + assert errors == 'strict' + return (zlib.decompress(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return zlib_encode(input, errors) + def decode(self, input, errors='strict'): + return zlib_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = zlib.compressobj() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = zlib.compressobj() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = zlib.decompressobj() + + def decode(self, input, final=False): + if final: + c = self.decompressobj.decompress(input) + return c + self.decompressobj.flush() + else: + return self.decompressobj.decompress(input) + + def reset(self): + self.decompressobj = zlib.decompressobj() + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='zlib', + encode=zlib_encode, + decode=zlib_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Thu Dec 2 19:06:51 2010 @@ -207,6 +207,11 @@ self.assertEqual(b.decode(errors="ignore", encoding="utf8"), "Hello world\n") + def test_transform(self): + b1 = self.type2test(range(256)) + b2 = b1.transform("base64").untransform("base64") + self.assertEqual(b2, b1) + def test_from_int(self): b = self.type2test(0) self.assertEqual(b, self.type2test()) Modified: python/branches/py3k/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k/Lib/test/test_codecs.py (original) +++ python/branches/py3k/Lib/test/test_codecs.py Thu Dec 2 19:06:51 2010 @@ -1659,6 +1659,67 @@ self.assertEqual(f.read(), data * 2) +bytes_transform_encodings = [ + "base64_codec", + "uu_codec", + "quopri_codec", + "hex_codec", +] +try: + import zlib +except ImportError: + pass +else: + bytes_transform_encodings.append("zlib_codec") +try: + import bz2 +except ImportError: + pass +else: + bytes_transform_encodings.append("bz2_codec") + +class TransformCodecTest(unittest.TestCase): + def test_basics(self): + binput = bytes(range(256)) + ainput = bytearray(binput) + for encoding in bytes_transform_encodings: + # generic codecs interface + (o, size) = codecs.getencoder(encoding)(binput) + self.assertEqual(size, len(binput)) + (i, size) = codecs.getdecoder(encoding)(o) + self.assertEqual(size, len(o)) + self.assertEqual(i, binput) + + # transform interface + boutput = binput.transform(encoding) + aoutput = ainput.transform(encoding) + self.assertEqual(boutput, aoutput) + self.assertIsInstance(boutput, bytes) + self.assertIsInstance(aoutput, bytearray) + bback = boutput.untransform(encoding) + aback = aoutput.untransform(encoding) + self.assertEqual(bback, aback) + self.assertEqual(bback, binput) + self.assertIsInstance(bback, bytes) + self.assertIsInstance(aback, bytearray) + + def test_read(self): + for encoding in bytes_transform_encodings: + sin = b"\x80".transform(encoding) + reader = codecs.getreader(encoding)(io.BytesIO(sin)) + sout = reader.read() + self.assertEqual(sout, b"\x80") + + def test_readline(self): + for encoding in bytes_transform_encodings: + if encoding in ['uu_codec', 'zlib_codec']: + continue + sin = b"\x80".transform(encoding) + reader = codecs.getreader(encoding)(io.BytesIO(sin)) + sout = reader.readline() + self.assertEqual(sout, b"\x80") + + def test_main(): support.run_unittest( UTF32Test, @@ -1686,6 +1747,7 @@ TypesTest, SurrogateEscapeTest, BomTest, + TransformCodecTest, ) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 19:06:51 2010 @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #7475: Added transform() and untransform() methods to both bytes + and string types. They can be used to access those codecs providing + bytes-to-bytes and string-to-string mappings. + - Issue #8685: Speed up set difference ``a - b`` when source set ``a`` is much larger than operand ``b``. Patch by Andrew Bennetts. Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Thu Dec 2 19:06:51 2010 @@ -2488,6 +2488,75 @@ return PyUnicode_FromEncodedObject(self, encoding, errors); } +PyDoc_STRVAR(transform__doc__, +"B.transform(encoding, errors='strict') -> bytearray\n\ +\n\ +Transform B using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +bytearray_transform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v, *w; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Encode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "encoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), + PyBytes_GET_SIZE(v)); + Py_DECREF(v); + return w; +} + + +PyDoc_STRVAR(untransform__doc__, +"B.untransform(encoding, errors='strict') -> bytearray\n\ +\n\ +Reverse-transform B using the codec registered for encoding. errors may\n\ +be given to set a different error handling scheme."); + +static PyObject * +bytearray_untransform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v, *w; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Decode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "decoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), + PyBytes_GET_SIZE(v)); + Py_DECREF(v); + return w; +} + PyDoc_STRVAR(alloc_doc, "B.__alloc__() -> int\n\ \n\ @@ -2782,8 +2851,12 @@ {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"transform", (PyCFunction)bytearray_transform, METH_VARARGS | METH_KEYWORDS, + transform__doc__}, {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, + {"untransform", (PyCFunction)bytearray_untransform, METH_VARARGS | METH_KEYWORDS, + untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Thu Dec 2 19:06:51 2010 @@ -2312,6 +2312,68 @@ return PyUnicode_FromEncodedObject(self, encoding, errors); } +PyDoc_STRVAR(transform__doc__, +"B.transform(encoding, errors='strict') -> bytes\n\ +\n\ +Transform B using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +bytes_transform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Encode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "encoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + return v; +} + + +PyDoc_STRVAR(untransform__doc__, +"B.untransform(encoding, errors='strict') -> bytes\n\ +\n\ +Reverse-transform B using the codec registered for encoding. errors may\n\ +be given to set a different error handling scheme."); + +static PyObject * +bytes_untransform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Decode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "decoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + return v; +} PyDoc_STRVAR(splitlines__doc__, "B.splitlines([keepends]) -> list of lines\n\ @@ -2475,8 +2537,10 @@ {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"transform", (PyCFunction)bytes_transform, METH_VARARGS | METH_KEYWORDS, transform__doc__}, {"translate", (PyCFunction)bytes_translate, METH_VARARGS, translate__doc__}, + {"untransform", (PyCFunction)bytes_untransform, METH_VARARGS | METH_KEYWORDS, untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Dec 2 19:06:51 2010 @@ -7432,6 +7432,7 @@ v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); if (v == NULL) goto onError; + /* XXX this check is redundant */ if (!PyBytes_Check(v)) { PyErr_Format(PyExc_TypeError, "encoder did not return a bytes object " @@ -7446,6 +7447,44 @@ return NULL; } +PyDoc_STRVAR(transform__doc__, + "S.transform(encoding, errors='strict') -> str\n\ +\n\ +Transform S using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +unicode_transform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + return PyUnicode_AsEncodedUnicode((PyObject *)self, encoding, errors); +} + +PyDoc_STRVAR(untransform__doc__, + "S.untransform(encoding, errors='strict') -> str\n\ +\n\ +Reverse-transform S using the codec registered for encoding. errors may be\n\ +given to set a different error handling scheme."); + +static PyObject * +unicode_untransform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + return PyUnicode_AsDecodedUnicode((PyObject *)self, encoding, errors); +} + PyDoc_STRVAR(expandtabs__doc__, "S.expandtabs([tabsize]) -> str\n\ \n\ @@ -9091,7 +9130,8 @@ /* Order is according to common usage: often used methods should appear first, since lookup is done sequentially. */ - {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__}, + {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, + encode__doc__}, {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__}, {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__}, {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__}, @@ -9136,6 +9176,10 @@ {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, + {"transform", (PyCFunction) unicode_transform, METH_VARARGS | METH_KEYWORDS, + transform__doc__}, + {"untransform", (PyCFunction) unicode_untransform, METH_VARARGS | METH_KEYWORDS, + untransform__doc__}, {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__}, #if 0 {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__}, From python-checkins at python.org Thu Dec 2 19:29:19 2010 From: python-checkins at python.org (brian.curtin) Date: Thu, 2 Dec 2010 19:29:19 +0100 (CET) Subject: [Python-checkins] r86935 - in python/branches/py3k: Doc/library/os.rst Lib/test/support.py Lib/test/test_glob.py Lib/test/test_httpservers.py Lib/test/test_os.py Lib/test/test_platform.py Lib/test/test_posixpath.py Lib/test/test_shutil.py Lib/test/test_sysconfig.py Lib/test/test_tarfile.py Misc/NEWS Modules/posixmodule.c Message-ID: <20101202182919.275BEEE9C4@mail.python.org> Author: brian.curtin Date: Thu Dec 2 19:29:18 2010 New Revision: 86935 Log: Fix #9333. Expose os.symlink on Windows only when usable. In order to create symlinks on Windows, SeCreateSymbolicLinkPrivilege is an account privilege that is required to be held by the user. Not only must the privilege be enabled for the account, the activated privileges for the currently running application must be adjusted to enable the requested privilege. Rather than exposing an additional function to be called prior to the user's first os.symlink call, we handle the AdjustTokenPrivileges Windows API call internally and only expose os.symlink when the privilege escalation was successful. Due to the change of only exposing os.symlink when it's available, we can go back to the original test skipping methods of checking via `hasattr`. Modified: python/branches/py3k/Doc/library/os.rst python/branches/py3k/Lib/test/support.py python/branches/py3k/Lib/test/test_glob.py python/branches/py3k/Lib/test/test_httpservers.py python/branches/py3k/Lib/test/test_os.py python/branches/py3k/Lib/test/test_platform.py python/branches/py3k/Lib/test/test_posixpath.py python/branches/py3k/Lib/test/test_shutil.py python/branches/py3k/Lib/test/test_sysconfig.py python/branches/py3k/Lib/test/test_tarfile.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/posixmodule.c Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Thu Dec 2 19:29:18 2010 @@ -1392,7 +1392,15 @@ Symbolic link support was introduced in Windows 6.0 (Vista). :func:`symlink` will raise a :exc:`NotImplementedError` on Windows versions earlier than 6.0. - The *SeCreateSymbolicLinkPrivilege* is required in order to create symlinks. + + .. note:: + + The *SeCreateSymbolicLinkPrivilege* is required in order to create + symlinks, so the function is only available when the privilege is held. + This privilege is not typically granted to regular users but is available + to accounts which can escalate privileges to the administrator level. + Either obtaining the privilege or running your application as an + administrator are ways to successfully create symlinks. Availability: Unix, Windows. Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Thu Dec 2 19:29:18 2010 @@ -42,7 +42,7 @@ "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", "reap_children", "cpython_only", "check_impl_detail", "get_attribute", - "swap_item", "swap_attr", "can_symlink", "skip_unless_symlink"] + "swap_item", "swap_attr"] class Error(Exception): @@ -1256,27 +1256,6 @@ except: break -try: - from .symlink_support import enable_symlink_privilege -except: - enable_symlink_privilege = lambda: True - -def can_symlink(): - """It's no longer sufficient to test for the presence of symlink in the - os module - on Windows XP and earlier, os.symlink exists but a - NotImplementedError is thrown. - """ - has_symlink = hasattr(os, 'symlink') - is_old_windows = sys.platform == "win32" and sys.getwindowsversion().major < 6 - has_privilege = False if is_old_windows else enable_symlink_privilege() - return has_symlink and (not is_old_windows) and has_privilege - -def skip_unless_symlink(test): - """Skip decorator for tests that require functional symlink""" - selector = can_symlink() - msg = "Requires functional symlink implementation" - return [unittest.skip(msg)(test), test][selector] - @contextlib.contextmanager def swap_attr(obj, attr, new_val): """Temporary swap out an attribute with a new object. Modified: python/branches/py3k/Lib/test/test_glob.py ============================================================================== --- python/branches/py3k/Lib/test/test_glob.py (original) +++ python/branches/py3k/Lib/test/test_glob.py Thu Dec 2 19:29:18 2010 @@ -1,5 +1,5 @@ import unittest -from test.support import run_unittest, TESTFN, skip_unless_symlink, can_symlink +from test.support import run_unittest, TESTFN import glob import os import shutil @@ -25,7 +25,7 @@ self.mktemp('ZZZ') self.mktemp('a', 'bcd', 'EF') self.mktemp('a', 'bcd', 'efg', 'ha') - if can_symlink(): + if hasattr(os, "symlink"): os.symlink(self.norm('broken'), self.norm('sym1')) os.symlink(self.norm('broken'), self.norm('sym2')) @@ -98,7 +98,8 @@ # either of these results are reasonable self.assertIn(res[0], [self.tempdir, self.tempdir + os.sep]) - @skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_glob_broken_symlinks(self): eq = self.assertSequencesEqual_noorder eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')]) Modified: python/branches/py3k/Lib/test/test_httpservers.py ============================================================================== --- python/branches/py3k/Lib/test/test_httpservers.py (original) +++ python/branches/py3k/Lib/test/test_httpservers.py Thu Dec 2 19:29:18 2010 @@ -304,7 +304,7 @@ # The shebang line should be pure ASCII: use symlink if possible. # See issue #7668. - if support.can_symlink(): + if hasattr(os, "symlink"): self.pythonexe = os.path.join(self.parent_dir, 'python') os.symlink(sys.executable, self.pythonexe) else: Modified: python/branches/py3k/Lib/test/test_os.py ============================================================================== --- python/branches/py3k/Lib/test/test_os.py (original) +++ python/branches/py3k/Lib/test/test_os.py Thu Dec 2 19:29:18 2010 @@ -541,7 +541,7 @@ f = open(path, "w") f.write("I'm " + path + " and proud of it. Blame test_os.\n") f.close() - if support.can_symlink(): + if hasattr(os, "symlink"): os.symlink(os.path.abspath(t2_path), link_path) sub2_tree = (sub2_path, ["link"], ["tmp3"]) else: @@ -585,7 +585,7 @@ self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) self.assertEqual(all[2 - 2 * flipped], sub2_tree) - if support.can_symlink(): + if hasattr(os, "symlink"): # Walk, following symlinks. for root, dirs, files in os.walk(walk_path, followlinks=True): if root == link_path: @@ -1146,14 +1146,8 @@ self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT") -def skipUnlessWindows6(test): - if (hasattr(sys, 'getwindowsversion') - and sys.getwindowsversion().major >= 6): - return test - return unittest.skip("Requires Windows Vista or later")(test) - @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") - at support.skip_unless_symlink + at unittest.skipUnless(hasattr(os, "symlink"), "Requires symlink implementation") class Win32SymlinkTests(unittest.TestCase): filelink = 'filelinktest' filelink_target = os.path.abspath(__file__) Modified: python/branches/py3k/Lib/test/test_platform.py ============================================================================== --- python/branches/py3k/Lib/test/test_platform.py (original) +++ python/branches/py3k/Lib/test/test_platform.py Thu Dec 2 19:29:18 2010 @@ -10,7 +10,8 @@ def test_architecture(self): res = platform.architecture() - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_architecture_via_symlink(self): # issue3762 # On Windows, the EXE needs to know where pythonXY.dll is at so we have # to add the directory to the path. Modified: python/branches/py3k/Lib/test/test_posixpath.py ============================================================================== --- python/branches/py3k/Lib/test/test_posixpath.py (original) +++ python/branches/py3k/Lib/test/test_posixpath.py Thu Dec 2 19:29:18 2010 @@ -155,7 +155,7 @@ f.write(b"foo") f.close() self.assertIs(posixpath.islink(support.TESTFN + "1"), False) - if support.can_symlink(): + if hasattr(os, "symlink"): os.symlink(support.TESTFN + "1", support.TESTFN + "2") self.assertIs(posixpath.islink(support.TESTFN + "2"), True) os.remove(support.TESTFN + "1") @@ -180,7 +180,8 @@ @unittest.skipIf( sys.platform.startswith('win'), "posixpath.samefile does not work on links in Windows") - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_samefile_on_links(self): test_fn1 = support.TESTFN + "1" test_fn2 = support.TESTFN + "2" @@ -204,7 +205,8 @@ @unittest.skipIf( sys.platform.startswith('win'), "posixpath.samestat does not work on links in Windows") - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_samestat_on_links(self): test_fn1 = support.TESTFN + "1" test_fn2 = support.TESTFN + "2" @@ -273,7 +275,8 @@ self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"), b"/foo/bar") - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash def test_realpath_basic(self): # Basic operation. @@ -283,7 +286,8 @@ finally: support.unlink(ABSTFN) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash def test_realpath_symlink_loops(self): # Bug #930024, return the path unchanged if we get into an infinite @@ -307,7 +311,8 @@ support.unlink(ABSTFN+"1") support.unlink(ABSTFN+"2") - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_parents(self): # We also need to resolve any symlinks in the parents of a relative @@ -328,7 +333,8 @@ safe_rmdir(ABSTFN + "/y") safe_rmdir(ABSTFN) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_before_normalizing(self): # Bug #990669: Symbolic links should be resolved before we @@ -358,7 +364,8 @@ safe_rmdir(ABSTFN + "/k") safe_rmdir(ABSTFN) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_first(self): # Bug #1213894: The first component of the path, if not absolute, Modified: python/branches/py3k/Lib/test/test_shutil.py ============================================================================== --- python/branches/py3k/Lib/test/test_shutil.py (original) +++ python/branches/py3k/Lib/test/test_shutil.py Thu Dec 2 19:29:18 2010 @@ -271,7 +271,8 @@ shutil.rmtree(src_dir) shutil.rmtree(os.path.dirname(dst_dir)) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_dont_copy_file_onto_link_to_itself(self): # bug 851123. os.mkdir(TESTFN) @@ -303,7 +304,8 @@ except OSError: pass - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_rmtree_on_symlink(self): # bug 1669. os.mkdir(TESTFN) @@ -328,26 +330,27 @@ finally: os.remove(TESTFN) - @unittest.skipUnless(hasattr(os, 'mkfifo'), 'requires os.mkfifo') - def test_copytree_named_pipe(self): - os.mkdir(TESTFN) - try: - subdir = os.path.join(TESTFN, "subdir") - os.mkdir(subdir) - pipe = os.path.join(subdir, "mypipe") - os.mkfifo(pipe) + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") + def test_copytree_named_pipe(self): + os.mkdir(TESTFN) try: - shutil.copytree(TESTFN, TESTFN2) - except shutil.Error as e: - errors = e.args[0] - self.assertEqual(len(errors), 1) - src, dst, error_msg = errors[0] - self.assertEqual("`%s` is a named pipe" % pipe, error_msg) - else: - self.fail("shutil.Error should have been raised") - finally: - shutil.rmtree(TESTFN, ignore_errors=True) - shutil.rmtree(TESTFN2, ignore_errors=True) + subdir = os.path.join(TESTFN, "subdir") + os.mkdir(subdir) + pipe = os.path.join(subdir, "mypipe") + os.mkfifo(pipe) + try: + shutil.copytree(TESTFN, TESTFN2) + except shutil.Error as e: + errors = e.args[0] + self.assertEqual(len(errors), 1) + src, dst, error_msg = errors[0] + self.assertEqual("`%s` is a named pipe" % pipe, error_msg) + else: + self.fail("shutil.Error should have been raised") + finally: + shutil.rmtree(TESTFN, ignore_errors=True) + shutil.rmtree(TESTFN2, ignore_errors=True) def test_copytree_special_func(self): @@ -364,7 +367,8 @@ shutil.copytree(src_dir, dst_dir, copy_function=_copy) self.assertEqual(len(copied), 2) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_copytree_dangling_symlinks(self): # a dangling symlink raises an error at the end Modified: python/branches/py3k/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/py3k/Lib/test/test_sysconfig.py (original) +++ python/branches/py3k/Lib/test/test_sysconfig.py Thu Dec 2 19:29:18 2010 @@ -12,7 +12,7 @@ from copy import copy, deepcopy from test.support import (run_unittest, TESTFN, unlink, get_attribute, - captured_stdout, skip_unless_symlink) + captured_stdout) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, @@ -245,7 +245,8 @@ 'posix_home', 'posix_prefix', 'posix_user') self.assertEqual(get_scheme_names(), wanted) - @skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_symlink(self): # On Windows, the EXE needs to know where pythonXY.dll is at so we have # to add the directory to the path. Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Thu Dec 2 19:29:18 2010 @@ -322,7 +322,8 @@ @unittest.skipUnless(hasattr(os, "link"), "Missing hardlink implementation") - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") @@ -840,7 +841,8 @@ os.remove(target) os.remove(link) - @support.skip_unless_symlink + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_symlink_size(self): path = os.path.join(TEMPDIR, "symlink") os.symlink("link_target", path) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 19:29:18 2010 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege + is held by the user's account, i.e., when the function can actually be used. + - Issue #7475: Added transform() and untransform() methods to both bytes and string types. They can be used to access those codecs providing bytes-to-bytes and string-to-string mappings. Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Thu Dec 2 19:29:18 2010 @@ -277,6 +277,9 @@ #include #include /* for ShellExecute() */ #include /* for UNLEN */ +#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ +#define HAVE_SYMLINK +#endif #endif /* _MSC_VER */ #if defined(PYCC_VACPP) && defined(PYOS_OS2) @@ -5091,7 +5094,7 @@ #endif /* HAVE_READLINK */ -#ifdef HAVE_SYMLINK +#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS) PyDoc_STRVAR(posix_symlink__doc__, "symlink(src, dst)\n\n\ Create a symbolic link pointing to src named dst."); @@ -5179,7 +5182,7 @@ #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ -#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) +#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) /* Grab CreateSymbolicLinkW dynamically from kernel32 */ static int has_CreateSymbolicLinkW = 0; @@ -5257,7 +5260,7 @@ Py_INCREF(Py_None); return Py_None; } -#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ +#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ #ifdef HAVE_TIMES #if defined(PYCC_VACPP) && defined(PYOS_OS2) @@ -7779,13 +7782,13 @@ {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, -#ifdef HAVE_SYMLINK +#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS) {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, #endif /* HAVE_SYMLINK */ -#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) - {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS, - win_symlink__doc__}, -#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ +#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) + {"_symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS, + win_symlink__doc__}, +#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ #ifdef HAVE_SYSTEM {"system", posix_system, METH_VARARGS, posix_system__doc__}, #endif @@ -8099,6 +8102,46 @@ } #endif +#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) +void +enable_symlink() +{ + HANDLE tok; + TOKEN_PRIVILEGES tok_priv; + LUID luid; + int meth_idx = 0; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) + return; + + if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) + return; + + tok_priv.PrivilegeCount = 1; + tok_priv.Privileges[0].Luid = luid; + tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, + sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) + return; + + if(GetLastError() == ERROR_NOT_ALL_ASSIGNED) { + /* We couldn't acquire the necessary privilege, so leave the + method hidden for this user. */ + return; + } else { + /* We've successfully acquired the symlink privilege so rename + the method to it's proper "os.symlink" name. */ + while(posix_methods[meth_idx].ml_meth != (PyCFunction)win_symlink) + meth_idx++; + posix_methods[meth_idx].ml_name = "symlink"; + + return; + } +} +#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ + static int all_ins(PyObject *d) { @@ -8360,6 +8403,10 @@ { PyObject *m, *v; +#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) + enable_symlink(); +#endif + m = PyModule_Create(&posixmodule); if (m == NULL) return NULL; From python-checkins at python.org Thu Dec 2 22:47:19 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 22:47:19 +0100 (CET) Subject: [Python-checkins] r86936 - in python/branches/py3k: Doc/library/email.util.rst Lib/email/test/test_email.py Lib/email/utils.py Misc/ACKS Misc/NEWS Message-ID: <20101202214719.BE98DEE98A@mail.python.org> Author: r.david.murray Date: Thu Dec 2 22:47:19 2010 New Revision: 86936 Log: #8989: add 'domain' keyword to make_msgid. Patch by Adrian von Bidder. Modified: python/branches/py3k/Doc/library/email.util.rst python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Lib/email/utils.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/email.util.rst ============================================================================== --- python/branches/py3k/Doc/library/email.util.rst (original) +++ python/branches/py3k/Doc/library/email.util.rst Thu Dec 2 22:47:19 2010 @@ -105,11 +105,17 @@ ``False``. The default is ``False``. -.. function:: make_msgid(idstring=None) +.. function:: make_msgid(idstring=None, domain=None) Returns a string suitable for an :rfc:`2822`\ -compliant :mailheader:`Message-ID` header. Optional *idstring* if given, is a string - used to strengthen the uniqueness of the message id. + used to strengthen the uniqueness of the message id. Optional *domain* if + given provides the portion of the msgid after the '@'. The default is the + local hostname. It is not normally necessary to override this default, but + may be useful certain cases, such as a constructing distributed system that + uses a consistent domain name across multiple hosts. + + .. versionchanged:: 3.2 domain keyword added .. function:: decode_rfc2231(s) Modified: python/branches/py3k/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k/Lib/email/test/test_email.py (original) +++ python/branches/py3k/Lib/email/test/test_email.py Thu Dec 2 22:47:19 2010 @@ -2457,6 +2457,10 @@ text/rfc822-headers """) + def test_make_msgid_domain(self): + self.assertEqual( + email.utils.make_msgid(domain='testdomain-string')[-19:], + '@testdomain-string>') # Test the iterator/generators Modified: python/branches/py3k/Lib/email/utils.py ============================================================================== --- python/branches/py3k/Lib/email/utils.py (original) +++ python/branches/py3k/Lib/email/utils.py Thu Dec 2 22:47:19 2010 @@ -148,13 +148,15 @@ -def make_msgid(idstring=None): +def make_msgid(idstring=None, domain=None): """Returns a string suitable for RFC 2822 compliant Message-ID, e.g: <20020201195627.33539.96671 at nightshade.la.mastaler.com> Optional idstring if given is a string used to strengthen the - uniqueness of the message id. + uniqueness of the message id. Optional domain if given provides the + portion of the message id after the '@'. It defaults to the locally + defined hostname. """ timeval = time.time() utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval)) @@ -164,8 +166,9 @@ idstring = '' else: idstring = '.' + idstring - idhost = socket.getfqdn() - msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, idhost) + if domain is None: + domain = socket.getfqdn() + msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, domain) return msgid Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Thu Dec 2 22:47:19 2010 @@ -77,6 +77,7 @@ Steven Bethard Stephen Bevan Ron Bickers +Adrian von Bidder David Binger Dominic Binks Philippe Biondi Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 22:47:19 2010 @@ -53,6 +53,9 @@ Library ------- +- Issue #8989: email.utils.make_msgid now has a domain parameter that can + override the domain name used in the generated msgid. + - Issue #9299: Add exist_ok parameter to os.makedirs to suppress the 'File exists' exception when a target directory already exists with the specified mode. Patch by Ray Allen. From python-checkins at python.org Thu Dec 2 22:55:33 2010 From: python-checkins at python.org (daniel.stutzbach) Date: Thu, 2 Dec 2010 22:55:33 +0100 (CET) Subject: [Python-checkins] r86937 - in python/branches/py3k: Misc/NEWS Objects/listobject.c Message-ID: <20101202215533.761DAEE9CD@mail.python.org> Author: daniel.stutzbach Date: Thu Dec 2 22:55:33 2010 New Revision: 86937 Log: Issue9915: speeding up sorting with a key Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/listobject.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 2 22:55:33 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #9915: Speed up sorting with a key. + - Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege is held by the user's account, i.e., when the function can actually be used. Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Thu Dec 2 22:55:33 2010 @@ -940,6 +940,66 @@ * pieces to this algorithm; read listsort.txt for overviews and details. */ +/* A sortslice contains a pointer to an array of keys and a pointer to + * an array of corresponding values. In other words, keys[i] + * corresponds with values[i]. If values == NULL, then the keys are + * also the values. + * + * Several convenience routines are provided here, so that keys and + * values are always moved in sync. + */ + +typedef struct { + PyObject **keys; + PyObject **values; +} sortslice; + +Py_LOCAL_INLINE(void) +sortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j) +{ + s1->keys[i] = s2->keys[j]; + if (s1->values != NULL) + s1->values[i] = s2->values[j]; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_incr(sortslice *dst, sortslice *src) { + *dst->keys++ = *src->keys++; + if (dst->values != NULL) + *dst->values++ = *src->values++; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_decr(sortslice *dst, sortslice *src) { + *dst->keys-- = *src->keys--; + if (dst->values != NULL) + *dst->values-- = *src->values--; +} + + +Py_LOCAL_INLINE(void) +sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) { + memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) { + memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_advance(sortslice *slice, Py_ssize_t n) { + slice->keys += n; + if (slice->values != NULL) + slice->values += n; +} + /* Comparison function: PyObject_RichCompareBool with Py_LT. * Returns -1 on error, 1 if x < y, 0 if x >= y. */ @@ -965,19 +1025,19 @@ the input (nothing is lost or duplicated). */ static int -binarysort(PyObject **lo, PyObject **hi, PyObject **start) +binarysort(sortslice lo, PyObject **hi, PyObject **start) { register Py_ssize_t k; register PyObject **l, **p, **r; register PyObject *pivot; - assert(lo <= start && start <= hi); + assert(lo.keys <= start && start <= hi); /* assert [lo, start) is sorted */ - if (lo == start) + if (lo.keys == start) ++start; for (; start < hi; ++start) { /* set l to where *start belongs */ - l = lo; + l = lo.keys; r = start; pivot = *r; /* Invariants: @@ -1004,6 +1064,15 @@ for (p = start; p > l; --p) *p = *(p-1); *l = pivot; + if (lo.values != NULL) { + Py_ssize_t offset = lo.values - lo.keys; + p = start + offset; + pivot = *p; + l += offset; + for (p = start + offset; p > l; --p) + *p = *(p-1); + *l = pivot; + } } return 0; @@ -1272,7 +1341,7 @@ * a convenient way to pass state around among the helper functions. */ struct s_slice { - PyObject **base; + sortslice base; Py_ssize_t len; }; @@ -1286,7 +1355,7 @@ /* 'a' is temp storage to help with merges. It contains room for * alloced entries. */ - PyObject **a; /* may point to temparray below */ + sortslice a; /* may point to temparray below */ Py_ssize_t alloced; /* A stack of n pending runs yet to be merged. Run #i starts at @@ -1307,11 +1376,29 @@ /* Conceptually a MergeState's constructor. */ static void -merge_init(MergeState *ms) +merge_init(MergeState *ms, int list_size, int has_keyfunc) { assert(ms != NULL); - ms->a = ms->temparray; - ms->alloced = MERGESTATE_TEMP_SIZE; + if (has_keyfunc) { + /* The temporary space for merging will need at most half the list + * size rounded up. Use the minimum possible space so we can use the + * rest of temparray for other things. In particular, if there is + * enough extra space, listsort() will use it to store the keys. + */ + ms->alloced = (list_size + 1) / 2; + + /* ms->alloced describes how many keys will be stored at + ms->temparray, but we also need to store the values. Hence, + ms->alloced is capped at half of MERGESTATE_TEMP_SIZE. */ + if (MERGESTATE_TEMP_SIZE / 2 < ms->alloced) + ms->alloced = MERGESTATE_TEMP_SIZE / 2; + ms->a.values = &ms->temparray[ms->alloced]; + } + else { + ms->alloced = MERGESTATE_TEMP_SIZE; + ms->a.values = NULL; + } + ms->a.keys = ms->temparray; ms->n = 0; ms->min_gallop = MIN_GALLOP; } @@ -1324,10 +1411,8 @@ merge_freemem(MergeState *ms) { assert(ms != NULL); - if (ms->a != ms->temparray) - PyMem_Free(ms->a); - ms->a = ms->temparray; - ms->alloced = MERGESTATE_TEMP_SIZE; + if (ms->a.keys != ms->temparray) + PyMem_Free(ms->a.keys); } /* Ensure enough temp memory for 'need' array slots is available. @@ -1336,52 +1421,60 @@ static int merge_getmem(MergeState *ms, Py_ssize_t need) { + int multiplier; + assert(ms != NULL); if (need <= ms->alloced) return 0; + + multiplier = ms->a.values != NULL ? 2 : 1; + /* Don't realloc! That can cost cycles to copy the old data, but * we don't care what's in the block. */ merge_freemem(ms); - if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) { + if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*) / multiplier) { PyErr_NoMemory(); return -1; } - ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*)); - if (ms->a) { + ms->a.keys = (PyObject**)PyMem_Malloc(multiplier * need + * sizeof(PyObject *)); + if (ms->a.keys != NULL) { ms->alloced = need; + if (ms->a.values != NULL) + ms->a.values = &ms->a.keys[need]; return 0; } PyErr_NoMemory(); - merge_freemem(ms); /* reset to sane state */ return -1; } #define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 : \ merge_getmem(MS, NEED)) -/* Merge the na elements starting at pa with the nb elements starting at pb - * in a stable way, in-place. na and nb must be > 0, and pa + na == pb. - * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the - * merge, and should have na <= nb. See listsort.txt for more info. - * Return 0 if successful, -1 if error. +/* Merge the na elements starting at ssa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[na-1] belongs at the end of the merge, and + * should have na <= nb. See listsort.txt for more info. Return 0 if + * successful, -1 if error. */ static Py_ssize_t -merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, - PyObject **pb, Py_ssize_t nb) +merge_lo(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) { Py_ssize_t k; - PyObject **dest; + sortslice dest; int result = -1; /* guilty until proved innocent */ Py_ssize_t min_gallop; - assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb); + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); if (MERGE_GETMEM(ms, na) < 0) return -1; - memcpy(ms->a, pa, na * sizeof(PyObject*)); - dest = pa; - pa = ms->a; + sortslice_memcpy(&ms->a, 0, &ssa, 0, na); + dest = ssa; + ssa = ms->a; - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); --nb; if (nb == 0) goto Succeed; @@ -1398,11 +1491,11 @@ */ for (;;) { assert(na > 1 && nb > 0); - k = ISLT(*pb, *pa); + k = ISLT(ssb.keys[0], ssa.keys[0]); if (k) { if (k < 0) goto Fail; - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); ++bcount; acount = 0; --nb; @@ -1412,7 +1505,7 @@ break; } else { - *dest++ = *pa++; + sortslice_copy_incr(&dest, &ssa); ++acount; bcount = 0; --na; @@ -1433,14 +1526,14 @@ assert(na > 1 && nb > 0); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, pa, na, 0); + k = gallop_right(ssb.keys[0], ssa.keys, na, 0); acount = k; if (k) { if (k < 0) goto Fail; - memcpy(dest, pa, k * sizeof(PyObject *)); - dest += k; - pa += k; + sortslice_memcpy(&dest, 0, &ssa, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssa, k); na -= k; if (na == 1) goto CopyB; @@ -1451,24 +1544,24 @@ if (na == 0) goto Succeed; } - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); --nb; if (nb == 0) goto Succeed; - k = gallop_left(*pa, pb, nb, 0); + k = gallop_left(ssa.keys[0], ssb.keys, nb, 0); bcount = k; if (k) { if (k < 0) goto Fail; - memmove(dest, pb, k * sizeof(PyObject *)); - dest += k; - pb += k; + sortslice_memmove(&dest, 0, &ssb, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssb, k); nb -= k; if (nb == 0) goto Succeed; } - *dest++ = *pa++; + sortslice_copy_incr(&dest, &ssa); --na; if (na == 1) goto CopyB; @@ -1480,43 +1573,46 @@ result = 0; Fail: if (na) - memcpy(dest, pa, na * sizeof(PyObject*)); + sortslice_memcpy(&dest, 0, &ssa, 0, na); return result; CopyB: assert(na == 1 && nb > 0); - /* The last element of pa belongs at the end of the merge. */ - memmove(dest, pb, nb * sizeof(PyObject *)); - dest[nb] = *pa; + /* The last element of ssa belongs at the end of the merge. */ + sortslice_memmove(&dest, 0, &ssb, 0, nb); + sortslice_copy(&dest, nb, &ssa, 0); return 0; } -/* Merge the na elements starting at pa with the nb elements starting at pb - * in a stable way, in-place. na and nb must be > 0, and pa + na == pb. - * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the - * merge, and should have na >= nb. See listsort.txt for more info. - * Return 0 if successful, -1 if error. +/* Merge the na elements starting at pa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[na-1] belongs at the end of the merge, and + * should have na >= nb. See listsort.txt for more info. Return 0 if + * successful, -1 if error. */ static Py_ssize_t -merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb) +merge_hi(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) { Py_ssize_t k; - PyObject **dest; + sortslice dest, basea, baseb; int result = -1; /* guilty until proved innocent */ - PyObject **basea; - PyObject **baseb; Py_ssize_t min_gallop; - assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb); + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); if (MERGE_GETMEM(ms, nb) < 0) return -1; - dest = pb + nb - 1; - memcpy(ms->a, pb, nb * sizeof(PyObject*)); - basea = pa; + dest = ssb; + sortslice_advance(&dest, nb-1); + sortslice_memcpy(&ms->a, 0, &ssb, 0, nb); + basea = ssa; baseb = ms->a; - pb = ms->a + nb - 1; - pa += na - 1; + ssb.keys = ms->a.keys + nb - 1; + if (ssb.values != NULL) + ssb.values = ms->a.values + nb - 1; + sortslice_advance(&ssa, na - 1); - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); --na; if (na == 0) goto Succeed; @@ -1533,11 +1629,11 @@ */ for (;;) { assert(na > 0 && nb > 1); - k = ISLT(*pb, *pa); + k = ISLT(ssb.keys[0], ssa.keys[0]); if (k) { if (k < 0) goto Fail; - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); ++acount; bcount = 0; --na; @@ -1547,7 +1643,7 @@ break; } else { - *dest-- = *pb--; + sortslice_copy_decr(&dest, &ssb); ++bcount; acount = 0; --nb; @@ -1568,33 +1664,33 @@ assert(na > 0 && nb > 1); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, basea, na, na-1); + k = gallop_right(ssb.keys[0], basea.keys, na, na-1); if (k < 0) goto Fail; k = na - k; acount = k; if (k) { - dest -= k; - pa -= k; - memmove(dest+1, pa+1, k * sizeof(PyObject *)); + sortslice_advance(&dest, -k); + sortslice_advance(&ssa, -k); + sortslice_memmove(&dest, 1, &ssa, 1, k); na -= k; if (na == 0) goto Succeed; } - *dest-- = *pb--; + sortslice_copy_decr(&dest, &ssb); --nb; if (nb == 1) goto CopyA; - k = gallop_left(*pa, baseb, nb, nb-1); + k = gallop_left(ssa.keys[0], baseb.keys, nb, nb-1); if (k < 0) goto Fail; k = nb - k; bcount = k; if (k) { - dest -= k; - pb -= k; - memcpy(dest+1, pb+1, k * sizeof(PyObject *)); + sortslice_advance(&dest, -k); + sortslice_advance(&ssb, -k); + sortslice_memcpy(&dest, 1, &ssb, 1, k); nb -= k; if (nb == 1) goto CopyA; @@ -1605,7 +1701,7 @@ if (nb == 0) goto Succeed; } - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); --na; if (na == 0) goto Succeed; @@ -1617,15 +1713,15 @@ result = 0; Fail: if (nb) - memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*)); + sortslice_memcpy(&dest, -(nb-1), &baseb, 0, nb); return result; CopyA: assert(nb == 1 && na > 0); - /* The first element of pb belongs at the front of the merge. */ - dest -= na; - pa -= na; - memmove(dest+1, pa+1, na * sizeof(PyObject *)); - *dest = *pb; + /* The first element of ssb belongs at the front of the merge. */ + sortslice_memmove(&dest, 1-na, &ssa, 1-na, na); + sortslice_advance(&dest, -na); + sortslice_advance(&ssa, -na); + sortslice_copy(&dest, 0, &ssb, 0); return 0; } @@ -1635,7 +1731,7 @@ static Py_ssize_t merge_at(MergeState *ms, Py_ssize_t i) { - PyObject **pa, **pb; + sortslice ssa, ssb; Py_ssize_t na, nb; Py_ssize_t k; @@ -1644,12 +1740,12 @@ assert(i >= 0); assert(i == ms->n - 2 || i == ms->n - 3); - pa = ms->pending[i].base; + ssa = ms->pending[i].base; na = ms->pending[i].len; - pb = ms->pending[i+1].base; + ssb = ms->pending[i+1].base; nb = ms->pending[i+1].len; assert(na > 0 && nb > 0); - assert(pa + na == pb); + assert(ssa.keys + na == ssb.keys); /* Record the length of the combined runs; if i is the 3rd-last * run now, also slide over the last run (which isn't involved @@ -1663,10 +1759,10 @@ /* Where does b start in a? Elements in a before that can be * ignored (already in place). */ - k = gallop_right(*pb, pa, na, 0); + k = gallop_right(*ssb.keys, ssa.keys, na, 0); if (k < 0) return -1; - pa += k; + sortslice_advance(&ssa, k); na -= k; if (na == 0) return 0; @@ -1674,7 +1770,7 @@ /* Where does a end in b? Elements in b after that can be * ignored (already in place). */ - nb = gallop_left(pa[na-1], pb, nb, nb-1); + nb = gallop_left(ssa.keys[na-1], ssb.keys, nb, nb-1); if (nb <= 0) return nb; @@ -1682,9 +1778,9 @@ * min(na, nb) elements. */ if (na <= nb) - return merge_lo(ms, pa, na, pb, nb); + return merge_lo(ms, ssa, na, ssb, nb); else - return merge_hi(ms, pa, na, pb, nb); + return merge_hi(ms, ssa, na, ssb, nb); } /* Examine the stack of runs waiting to be merged, merging adjacent runs @@ -1765,103 +1861,12 @@ return n + r; } -/* Special wrapper to support stable sorting using the decorate-sort-undecorate - pattern. Holds a key which is used for comparisons and the original record - which is returned during the undecorate phase. By exposing only the key - during comparisons, the underlying sort stability characteristics are left - unchanged. Also, the comparison function will only see the key instead of - a full record. */ - -typedef struct { - PyObject_HEAD - PyObject *key; - PyObject *value; -} sortwrapperobject; - -PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key."); -static PyObject * -sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int); static void -sortwrapper_dealloc(sortwrapperobject *); - -PyTypeObject PySortWrapper_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "sortwrapper", /* tp_name */ - sizeof(sortwrapperobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)sortwrapper_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - sortwrapper_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)sortwrapper_richcompare, /* tp_richcompare */ -}; - - -static PyObject * -sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op) +reverse_sortslice(sortslice *s, Py_ssize_t n) { - if (!PyObject_TypeCheck(b, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - return PyObject_RichCompare(a->key, b->key, op); -} - -static void -sortwrapper_dealloc(sortwrapperobject *so) -{ - Py_XDECREF(so->key); - Py_XDECREF(so->value); - PyObject_Del(so); -} - -/* Returns a new reference to a sortwrapper. - Consumes the references to the two underlying objects. */ - -static PyObject * -build_sortwrapper(PyObject *key, PyObject *value) -{ - sortwrapperobject *so; - - so = PyObject_New(sortwrapperobject, &PySortWrapper_Type); - if (so == NULL) - return NULL; - so->key = key; - so->value = value; - return (PyObject *)so; -} - -/* Returns a new reference to the value underlying the wrapper. */ -static PyObject * -sortwrapper_getvalue(PyObject *so) -{ - PyObject *value; - - if (!PyObject_TypeCheck(so, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - value = ((sortwrapperobject *)so)->value; - Py_INCREF(value); - return value; + reverse_slice(s->keys, &s->keys[n]); + if (s->values != NULL) + reverse_slice(s->values, &s->values[n]); } /* An adaptive, stable, natural mergesort. See listsort.txt. @@ -1873,9 +1878,9 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) { MergeState ms; - PyObject **lo, **hi; Py_ssize_t nremaining; Py_ssize_t minrun; + sortslice lo; Py_ssize_t saved_ob_size, saved_allocated; PyObject **saved_ob_item; PyObject **final_ob_item; @@ -1883,8 +1888,8 @@ int reverse = 0; PyObject *keyfunc = NULL; Py_ssize_t i; - PyObject *key, *value, *kvpair; static char *kwlist[] = {"key", "reverse", 0}; + PyObject **keys; assert(self != NULL); assert (PyList_Check(self)); @@ -1913,28 +1918,36 @@ self->ob_item = NULL; self->allocated = -1; /* any operation will reset it to >= 0 */ - if (keyfunc != NULL) { - for (i=0 ; i < saved_ob_size ; i++) { - value = saved_ob_item[i]; - key = PyObject_CallFunctionObjArgs(keyfunc, value, - NULL); - if (key == NULL) { - for (i=i-1 ; i>=0 ; i--) { - kvpair = saved_ob_item[i]; - value = sortwrapper_getvalue(kvpair); - saved_ob_item[i] = value; - Py_DECREF(kvpair); - } - goto dsu_fail; + if (keyfunc == NULL) { + keys = NULL; + lo.keys = saved_ob_item; + lo.values = NULL; + } + else { + if (saved_ob_size < MERGESTATE_TEMP_SIZE/2) + /* Leverage stack space we allocated but won't otherwise use */ + keys = &ms.temparray[saved_ob_size+1]; + else { + keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + if (keys == NULL) + return NULL; + } + + for (i = 0; i < saved_ob_size ; i++) { + keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i], + NULL); + if (keys[i] == NULL) { + for (i=i-1 ; i>=0 ; i--) + Py_DECREF(keys[i]); + goto keyfunc_fail; } - kvpair = build_sortwrapper(key, value); - if (kvpair == NULL) - goto dsu_fail; - saved_ob_item[i] = kvpair; } + + lo.keys = keys; + lo.values = saved_ob_item; } - merge_init(&ms); + merge_init(&ms, saved_ob_size, keys != NULL); nremaining = saved_ob_size; if (nremaining < 2) @@ -1942,30 +1955,31 @@ /* Reverse sort stability achieved by initially reversing the list, applying a stable forward sort, then reversing the final result. */ - if (reverse) - reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size); + if (reverse) { + if (keys != NULL) + reverse_slice(&keys[0], &keys[saved_ob_size]); + reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]); + } /* March over the array once, left to right, finding natural runs, * and extending short natural runs to minrun elements. */ - lo = saved_ob_item; - hi = lo + nremaining; minrun = merge_compute_minrun(nremaining); do { int descending; Py_ssize_t n; /* Identify next run. */ - n = count_run(lo, hi, &descending); + n = count_run(lo.keys, lo.keys + nremaining, &descending); if (n < 0) goto fail; if (descending) - reverse_slice(lo, lo + n); + reverse_sortslice(&lo, n); /* If short, extend to min(minrun, nremaining). */ if (n < minrun) { const Py_ssize_t force = nremaining <= minrun ? nremaining : minrun; - if (binarysort(lo, lo + force, lo + n) < 0) + if (binarysort(lo, lo.keys + force, lo.keys + n) < 0) goto fail; n = force; } @@ -1977,27 +1991,27 @@ if (merge_collapse(&ms) < 0) goto fail; /* Advance to find next run. */ - lo += n; + sortslice_advance(&lo, n); nremaining -= n; } while (nremaining); - assert(lo == hi); if (merge_force_collapse(&ms) < 0) goto fail; assert(ms.n == 1); - assert(ms.pending[0].base == saved_ob_item); + assert(keys == NULL + ? ms.pending[0].base.keys == saved_ob_item + : ms.pending[0].base.keys == &keys[0]); assert(ms.pending[0].len == saved_ob_size); + lo = ms.pending[0].base; succeed: result = Py_None; fail: - if (keyfunc != NULL) { - for (i=0 ; i < saved_ob_size ; i++) { - kvpair = saved_ob_item[i]; - value = sortwrapper_getvalue(kvpair); - saved_ob_item[i] = value; - Py_DECREF(kvpair); - } + if (keys != NULL) { + for (i = 0; i < saved_ob_size; i++) + Py_DECREF(keys[i]); + if (keys != &ms.temparray[saved_ob_size+1]) + PyMem_FREE(keys); } if (self->allocated != -1 && result != NULL) { @@ -2013,7 +2027,7 @@ merge_freemem(&ms); -dsu_fail: +keyfunc_fail: final_ob_item = self->ob_item; i = Py_SIZE(self); Py_SIZE(self) = saved_ob_size; @@ -2862,4 +2876,3 @@ len = 0; return PyLong_FromSsize_t(len); } - From python-checkins at python.org Thu Dec 2 22:55:58 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 22:55:58 +0100 (CET) Subject: [Python-checkins] r86938 - python/branches/release31-maint Message-ID: <20101202215558.1DB9CEE9CD@mail.python.org> Author: r.david.murray Date: Thu Dec 2 22:55:57 2010 New Revision: 86938 Log: Blocked revisions 86936 via svnmerge ........ r86936 | r.david.murray | 2010-12-02 16:47:19 -0500 (Thu, 02 Dec 2010) | 4 lines #8989: add 'domain' keyword to make_msgid. Patch by Adrian von Bidder. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Dec 2 22:56:45 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Dec 2010 22:56:45 +0100 (CET) Subject: [Python-checkins] r86939 - python/branches/release27-maint Message-ID: <20101202215645.89454EE9B7@mail.python.org> Author: r.david.murray Date: Thu Dec 2 22:56:45 2010 New Revision: 86939 Log: Blocked revisions 86936 via svnmerge ........ r86936 | r.david.murray | 2010-12-02 16:47:19 -0500 (Thu, 02 Dec 2010) | 4 lines #8989: add 'domain' keyword to make_msgid. Patch by Adrian von Bidder. ........ Modified: python/branches/release27-maint/ (props changed) From python-checkins at python.org Thu Dec 2 23:16:20 2010 From: python-checkins at python.org (eric.araujo) Date: Thu, 2 Dec 2010 23:16:20 +0100 (CET) Subject: [Python-checkins] r86940 - python/branches/py3k/Lib/test/test_csv.py Message-ID: <20101202221620.01FD2EE9D9@mail.python.org> Author: eric.araujo Date: Thu Dec 2 23:16:19 2010 New Revision: 86940 Log: Fix wrong test code in test_csv (#10602) Modified: python/branches/py3k/Lib/test/test_csv.py Modified: python/branches/py3k/Lib/test/test_csv.py ============================================================================== --- python/branches/py3k/Lib/test/test_csv.py (original) +++ python/branches/py3k/Lib/test/test_csv.py Thu Dec 2 23:16:19 2010 @@ -313,22 +313,17 @@ expected_dialects = csv.list_dialects() + [name] expected_dialects.sort() csv.register_dialect(name, myexceltsv) - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - got_dialects = csv.list_dialects() - got_dialects.sort() - self.assertEqual(expected_dialects, got_dialects) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, '\t') + got_dialects = sorted(csv.list_dialects()) + self.assertEqual(expected_dialects, got_dialects) def test_register_kwargs(self): name = 'fedcba' csv.register_dialect(name, delimiter=';') - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - self.assertTrue(list(csv.reader('X;Y;Z', name)), ['X', 'Y', 'Z']) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, ';') + self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): From python-checkins at python.org Thu Dec 2 23:29:59 2010 From: python-checkins at python.org (eric.araujo) Date: Thu, 2 Dec 2010 23:29:59 +0100 (CET) Subject: [Python-checkins] r86941 - in python/branches/release31-maint: Lib/test/test_csv.py Message-ID: <20101202222959.59616EE9E0@mail.python.org> Author: eric.araujo Date: Thu Dec 2 23:29:59 2010 New Revision: 86941 Log: Merged revisions 86940 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86940 | eric.araujo | 2010-12-02 23:16:19 +0100 (jeu., 02 d?c. 2010) | 2 lines Fix wrong test code in test_csv (#10602) ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_csv.py Modified: python/branches/release31-maint/Lib/test/test_csv.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_csv.py (original) +++ python/branches/release31-maint/Lib/test/test_csv.py Thu Dec 2 23:29:59 2010 @@ -314,22 +314,17 @@ expected_dialects = csv.list_dialects() + [name] expected_dialects.sort() csv.register_dialect(name, myexceltsv) - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - got_dialects = csv.list_dialects() - got_dialects.sort() - self.assertEqual(expected_dialects, got_dialects) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, '\t') + got_dialects = sorted(csv.list_dialects()) + self.assertEqual(expected_dialects, got_dialects) def test_register_kwargs(self): name = 'fedcba' csv.register_dialect(name, delimiter=';') - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - self.assertTrue(list(csv.reader('X;Y;Z', name)), ['X', 'Y', 'Z']) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, ';') + self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): From python-checkins at python.org Thu Dec 2 23:35:10 2010 From: python-checkins at python.org (eric.araujo) Date: Thu, 2 Dec 2010 23:35:10 +0100 (CET) Subject: [Python-checkins] r86942 - in python/branches/release27-maint: Lib/test/test_csv.py Message-ID: <20101202223510.619F7EE9B1@mail.python.org> Author: eric.araujo Date: Thu Dec 2 23:35:10 2010 New Revision: 86942 Log: Merged revisions 86940 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86940 | eric.araujo | 2010-12-02 23:16:19 +0100 (jeu., 02 d?c. 2010) | 2 lines Fix wrong test code in test_csv (#10602) ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/test/test_csv.py Modified: python/branches/release27-maint/Lib/test/test_csv.py ============================================================================== --- python/branches/release27-maint/Lib/test/test_csv.py (original) +++ python/branches/release27-maint/Lib/test/test_csv.py Thu Dec 2 23:35:10 2010 @@ -326,22 +326,17 @@ expected_dialects = csv.list_dialects() + [name] expected_dialects.sort() csv.register_dialect(name, myexceltsv) - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - got_dialects = csv.list_dialects() - got_dialects.sort() - self.assertEqual(expected_dialects, got_dialects) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, '\t') + got_dialects = sorted(csv.list_dialects()) + self.assertEqual(expected_dialects, got_dialects) def test_register_kwargs(self): name = 'fedcba' csv.register_dialect(name, delimiter=';') - try: - self.assertTrue(csv.get_dialect(name).delimiter, '\t') - self.assertTrue(list(csv.reader('X;Y;Z', name)), ['X', 'Y', 'Z']) - finally: - csv.unregister_dialect(name) + self.addCleanup(csv.unregister_dialect, name) + self.assertEqual(csv.get_dialect(name).delimiter, ';') + self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): From python-checkins at python.org Thu Dec 2 23:35:25 2010 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Dec 2010 23:35:25 +0100 (CET) Subject: [Python-checkins] r86943 - python/branches/py3k/Doc/library/unittest.rst Message-ID: <20101202223525.DACD3EE99E@mail.python.org> Author: georg.brandl Date: Thu Dec 2 23:35:25 2010 New Revision: 86943 Log: Re-add accidentally removed line. Modified: python/branches/py3k/Doc/library/unittest.rst Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Thu Dec 2 23:35:25 2010 @@ -1719,6 +1719,7 @@ The total number of tests run so far. + .. attribute:: buffer If set to true, ``sys.stdout`` and ``sys.stderr`` will be buffered in between :meth:`startTest` and :meth:`stopTest` being called. Collected output will From python-checkins at python.org Fri Dec 3 01:53:09 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 01:53:09 +0100 (CET) Subject: [Python-checkins] r86944 - in python/branches/py3k: Doc/library/unittest.rst Lib/unittest/case.py Lib/unittest/test/test_assertions.py Misc/NEWS Message-ID: <20101203005309.F1423F414@mail.python.org> Author: michael.foord Date: Fri Dec 3 01:53:09 2010 New Revision: 86944 Log: Issue 7911: unittest.TestCase.longMessage defaults to True for improved failure messages by default Modified: python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/test/test_assertions.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Fri Dec 3 01:53:09 2010 @@ -1305,8 +1305,8 @@ to ``True`` allows you to have a custom error message in addition to the normal one. - This attribute defaults to ``False``, meaning that a custom message passed - to an assert method will silence the normal message. + This attribute defaults to ``True``. If set to False then a custom message + passed to an assert method will silence the normal message. The class setting can be overridden in individual tests by assigning an instance attribute to ``True`` or ``False`` before calling the assert methods. Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Fri Dec 3 01:53:09 2010 @@ -245,7 +245,7 @@ # objects used in assert methods) will be printed on failure in *addition* # to any explicit message passed. - longMessage = False + longMessage = True # This attribute sets the maximum length of a diff in failure messages # by assert methods using difflib. It is looked up as an instance attribute Modified: python/branches/py3k/Lib/unittest/test/test_assertions.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_assertions.py (original) +++ python/branches/py3k/Lib/unittest/test/test_assertions.py Fri Dec 3 01:53:09 2010 @@ -127,7 +127,7 @@ self.testableFalse = TestableTestFalse('testTest') def testDefault(self): - self.assertFalse(unittest.TestCase.longMessage) + self.assertTrue(unittest.TestCase.longMessage) def test_formatMsg(self): self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 01:53:09 2010 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue 7911: `unittest.TestCase.longMessage` defaults to True for improved + failure messages by default. Patch by Mark Roddy. + - Issue #9915: Speed up sorting with a key. - Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege From python-checkins at python.org Fri Dec 3 02:34:01 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 02:34:01 +0100 (CET) Subject: [Python-checkins] r86945 - python/branches/py3k/Lib/test/__main__.py Message-ID: <20101203013401.A454BEE981@mail.python.org> Author: michael.foord Date: Fri Dec 3 02:34:01 2010 New Revision: 86945 Log: Initial implementation of Lib/test/__main__.py so we can run tests with 'python -m test' Added: python/branches/py3k/Lib/test/__main__.py (contents, props changed) Added: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/__main__.py Fri Dec 3 02:34:01 2010 @@ -0,0 +1,38 @@ +import os +import sys +import sysconfig + +from test import support +from test.regrtest import main + +# findtestdir() gets the dirname out of __file__, so we have to make it +# absolute before changing the working directory. +# For example __file__ may be relative when running trace or profile. +# See issue #9323. +__file__ = os.path.abspath(__file__) + +# sanity check +assert __file__ == os.path.abspath(sys.argv[0]) + +# When tests are run from the Python build directory, it is best practice +# to keep the test files in a subfolder. It eases the cleanup of leftover +# files using command "make distclean". +if sysconfig.is_python_build(): + TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') + TEMPDIR = os.path.abspath(TEMPDIR) + if not os.path.exists(TEMPDIR): + os.mkdir(TEMPDIR) + +# Define a writable temp dir that will be used as cwd while running +# the tests. The name of the dir includes the pid to allow parallel +# testing (see the -j option). +TESTCWD = 'test_python_{}'.format(os.getpid()) + +TESTCWD = os.path.join(TEMPDIR, TESTCWD) + +# Run the tests in a context manager that temporary changes the CWD to a +# temporary and writable directory. If it's not possible to create or +# change the CWD, the original CWD will be used. The original CWD is +# available from support.SAVEDCWD. +with support.temp_cwd(TESTCWD, quiet=True): + main() From python-checkins at python.org Fri Dec 3 02:44:16 2010 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 3 Dec 2010 02:44:16 +0100 (CET) Subject: [Python-checkins] r86946 - python/branches/py3k/Objects/listobject.c Message-ID: <20101203014416.67837EE9AC@mail.python.org> Author: benjamin.peterson Date: Fri Dec 3 02:44:10 2010 New Revision: 86946 Log: code style Modified: python/branches/py3k/Objects/listobject.c Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Fri Dec 3 02:44:10 2010 @@ -963,14 +963,16 @@ } Py_LOCAL_INLINE(void) -sortslice_copy_incr(sortslice *dst, sortslice *src) { +sortslice_copy_incr(sortslice *dst, sortslice *src) +{ *dst->keys++ = *src->keys++; if (dst->values != NULL) *dst->values++ = *src->values++; } Py_LOCAL_INLINE(void) -sortslice_copy_decr(sortslice *dst, sortslice *src) { +sortslice_copy_decr(sortslice *dst, sortslice *src) +{ *dst->keys-- = *src->keys--; if (dst->values != NULL) *dst->values-- = *src->values--; @@ -979,7 +981,8 @@ Py_LOCAL_INLINE(void) sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, - Py_ssize_t n) { + Py_ssize_t n) +{ memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); if (s1->values != NULL) memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); @@ -987,14 +990,16 @@ Py_LOCAL_INLINE(void) sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, - Py_ssize_t n) { + Py_ssize_t n) +{ memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); if (s1->values != NULL) memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); } Py_LOCAL_INLINE(void) -sortslice_advance(sortslice *slice, Py_ssize_t n) { +sortslice_advance(sortslice *slice, Py_ssize_t n) +{ slice->keys += n; if (slice->values != NULL) slice->values += n; From python-checkins at python.org Fri Dec 3 03:03:30 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 03:03:30 +0100 (CET) Subject: [Python-checkins] r86947 - python/branches/py3k/Lib/test/__main__.py Message-ID: <20101203020330.E7A85EE983@mail.python.org> Author: michael.foord Date: Fri Dec 3 03:03:30 2010 New Revision: 86947 Log: Set test.regrtest.TEMPDIR correctly when run with 'python -m test' Modified: python/branches/py3k/Lib/test/__main__.py Modified: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- python/branches/py3k/Lib/test/__main__.py (original) +++ python/branches/py3k/Lib/test/__main__.py Fri Dec 3 03:03:30 2010 @@ -3,7 +3,7 @@ import sysconfig from test import support -from test.regrtest import main +from test import regrtest # findtestdir() gets the dirname out of __file__, so we have to make it # absolute before changing the working directory. @@ -22,6 +22,7 @@ TEMPDIR = os.path.abspath(TEMPDIR) if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) + regrtest.TEMPDIR = TEMPDIR # Define a writable temp dir that will be used as cwd while running # the tests. The name of the dir includes the pid to allow parallel @@ -29,10 +30,11 @@ TESTCWD = 'test_python_{}'.format(os.getpid()) TESTCWD = os.path.join(TEMPDIR, TESTCWD) +regrtest.TESTCWD = TESTCWD # Run the tests in a context manager that temporary changes the CWD to a # temporary and writable directory. If it's not possible to create or # change the CWD, the original CWD will be used. The original CWD is # available from support.SAVEDCWD. with support.temp_cwd(TESTCWD, quiet=True): - main() + regrtest.main() From python-checkins at python.org Fri Dec 3 03:09:34 2010 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Dec 2010 03:09:34 +0100 (CET) Subject: [Python-checkins] r86948 - in python/branches/py3k: Doc/library/itertools.rst Lib/test/test_itertools.py Modules/itertoolsmodule.c Message-ID: <20101203020934.70CCAEE98C@mail.python.org> Author: raymond.hettinger Date: Fri Dec 3 03:09:34 2010 New Revision: 86948 Log: Simplify the signature for itertools.accumulate() to match numpy. Handle one item iterable the same way as min()/max(). Modified: python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Fri Dec 3 03:09:34 2010 @@ -90,13 +90,15 @@ parameter (which defaults to :const:`0`). Elements may be any addable type including :class:`Decimal` or :class:`Fraction`. Equivalent to:: - def accumulate(iterable, start=0): + def accumulate(iterable): 'Return running totals' - # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 - total = start - for element in iterable: - total += element - yield total + # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 + it = iter(iterable) + total = next(it) + yield total + for element in it: + total += element + yield total .. versionadded:: 3.2 Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Fri Dec 3 03:09:34 2010 @@ -59,18 +59,18 @@ def test_accumulate(self): self.assertEqual(list(accumulate(range(10))), # one positional arg - [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) - self.assertEqual(list(accumulate(range(10), 100)), # two positional args - [100, 101, 103, 106, 110, 115, 121, 128, 136, 145]) - self.assertEqual(list(accumulate(iterable=range(10), start=100)), # kw args - [100, 101, 103, 106, 110, 115, 121, 128, 136, 145]) + [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) + self.assertEqual(list(accumulate(iterable=range(10))), # kw arg + [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) for typ in int, complex, Decimal, Fraction: # multiple types - self.assertEqual(list(accumulate(range(10), typ(0))), + self.assertEqual( + list(accumulate(map(typ, range(10)))), list(map(typ, [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]))) self.assertEqual(list(accumulate([])), []) # empty iterable - self.assertRaises(TypeError, accumulate, range(10), 0, 5) # too many args + self.assertEqual(list(accumulate([7])), [7]) # iterable of length one + self.assertRaises(TypeError, accumulate, range(10), 5) # too many args self.assertRaises(TypeError, accumulate) # too few args - self.assertRaises(TypeError, accumulate, range(10), x=7) # unexpected kwd args + self.assertRaises(TypeError, accumulate, x=range(10)) # unexpected kwd arg self.assertRaises(TypeError, list, accumulate([1, []])) # args that don't add def test_chain(self): Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Fri Dec 3 03:09:34 2010 @@ -2597,41 +2597,27 @@ static PyObject * accumulate_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - static char *kwargs[] = {"iterable", "start", NULL}; + static char *kwargs[] = {"iterable", NULL}; PyObject *iterable; PyObject *it; - PyObject *start = NULL; accumulateobject *lz; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:accumulate", - kwargs, &iterable, &start)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:accumulate", kwargs, &iterable)) + return NULL; /* Get iterator. */ it = PyObject_GetIter(iterable); if (it == NULL) return NULL; - /* Default start value */ - if (start == NULL) { - start = PyLong_FromLong(0); - if (start == NULL) { - Py_DECREF(it); - return NULL; - } - } else { - Py_INCREF(start); - } - /* create accumulateobject structure */ lz = (accumulateobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(it); - Py_DECREF(start); - return NULL; + return NULL; } - lz->total = start; + lz->total = NULL; lz->it = it; return (PyObject *)lz; } @@ -2661,11 +2647,17 @@ val = PyIter_Next(lz->it); if (val == NULL) return NULL; - + + if (lz->total == NULL) { + Py_INCREF(val); + lz->total = val; + return lz->total; + } + newtotal = PyNumber_Add(lz->total, val); - Py_DECREF(val); + Py_DECREF(val); if (newtotal == NULL) - return NULL; + return NULL; oldtotal = lz->total; lz->total = newtotal; @@ -2676,7 +2668,7 @@ } PyDoc_STRVAR(accumulate_doc, -"accumulate(iterable, start=0) --> accumulate object\n\ +"accumulate(iterable) --> accumulate object\n\ \n\ Return series of accumulated sums."); From python-checkins at python.org Fri Dec 3 03:27:45 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 03:27:45 +0100 (CET) Subject: [Python-checkins] r86949 - python/branches/py3k/Lib/test/__main__.py Message-ID: <20101203022745.08CE1EE989@mail.python.org> Author: michael.foord Date: Fri Dec 3 03:27:44 2010 New Revision: 86949 Log: Remove test/__main__.py until runpy tests can be fixed Removed: python/branches/py3k/Lib/test/__main__.py Deleted: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- python/branches/py3k/Lib/test/__main__.py Fri Dec 3 03:27:44 2010 +++ (empty file) @@ -1,40 +0,0 @@ -import os -import sys -import sysconfig - -from test import support -from test import regrtest - -# findtestdir() gets the dirname out of __file__, so we have to make it -# absolute before changing the working directory. -# For example __file__ may be relative when running trace or profile. -# See issue #9323. -__file__ = os.path.abspath(__file__) - -# sanity check -assert __file__ == os.path.abspath(sys.argv[0]) - -# When tests are run from the Python build directory, it is best practice -# to keep the test files in a subfolder. It eases the cleanup of leftover -# files using command "make distclean". -if sysconfig.is_python_build(): - TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') - TEMPDIR = os.path.abspath(TEMPDIR) - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) - regrtest.TEMPDIR = TEMPDIR - -# Define a writable temp dir that will be used as cwd while running -# the tests. The name of the dir includes the pid to allow parallel -# testing (see the -j option). -TESTCWD = 'test_python_{}'.format(os.getpid()) - -TESTCWD = os.path.join(TEMPDIR, TESTCWD) -regrtest.TESTCWD = TESTCWD - -# Run the tests in a context manager that temporary changes the CWD to a -# temporary and writable directory. If it's not possible to create or -# change the CWD, the original CWD will be used. The original CWD is -# available from support.SAVEDCWD. -with support.temp_cwd(TESTCWD, quiet=True): - regrtest.main() From python-checkins at python.org Fri Dec 3 03:33:54 2010 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Dec 2010 03:33:54 +0100 (CET) Subject: [Python-checkins] r86950 - in python/branches/py3k: Doc/library/itertools.rst Lib/test/test_itertools.py Message-ID: <20101203023354.1557BEE981@mail.python.org> Author: raymond.hettinger Date: Fri Dec 3 03:33:53 2010 New Revision: 86950 Log: Update the itertools.accumulate() docs. Modified: python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Lib/test/test_itertools.py Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Fri Dec 3 03:33:53 2010 @@ -46,7 +46,7 @@ ==================== ============================ ================================================= ============================================================= Iterator Arguments Results Example ==================== ============================ ================================================= ============================================================= -:func:`accumulate` p[, start=0] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`accumulate` p p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` @@ -84,11 +84,10 @@ streams of infinite length, so they should only be accessed by functions or loops that truncate the stream. -.. function:: accumulate(iterable, start=0) +.. function:: accumulate(iterable) - Make an iterator that returns accumulated sums plus the value of the *start* - parameter (which defaults to :const:`0`). Elements may be any addable type - including :class:`Decimal` or :class:`Fraction`. Equivalent to:: + Make an iterator that returns accumulated sums. Elements may be any addable + type including :class:`Decimal` or :class:`Fraction`. Equivalent to:: def accumulate(iterable): 'Return running totals' Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Fri Dec 3 03:33:53 2010 @@ -66,6 +66,7 @@ self.assertEqual( list(accumulate(map(typ, range(10)))), list(map(typ, [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]))) + self.assertEqual(list(accumulate('abc')), ['a', 'ab', 'abc']) # works with non-numeric self.assertEqual(list(accumulate([])), []) # empty iterable self.assertEqual(list(accumulate([7])), [7]) # iterable of length one self.assertRaises(TypeError, accumulate, range(10), 5) # too many args From python-checkins at python.org Fri Dec 3 03:46:02 2010 From: python-checkins at python.org (brian.curtin) Date: Fri, 3 Dec 2010 03:46:02 +0100 (CET) Subject: [Python-checkins] r86951 - in python/branches/py3k: Doc/library/subprocess.rst Lib/subprocess.py Lib/test/test_subprocess.py Misc/NEWS Message-ID: <20101203024602.3E450EE9BB@mail.python.org> Author: brian.curtin Date: Fri Dec 3 03:46:02 2010 New Revision: 86951 Log: Fix #10554. Added context manager support to Popen objects. Added a few common Popen uses to the tests like we've done for a few other instances of adding context managers. Eventually the entire test suite could be converted to use the context manager format. Modified: python/branches/py3k/Doc/library/subprocess.rst python/branches/py3k/Lib/subprocess.py python/branches/py3k/Lib/test/test_subprocess.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Fri Dec 3 03:46:02 2010 @@ -208,6 +208,16 @@ underlying CreateProcess() function. They can specify things such as appearance of the main window and priority for the new process. (Windows only) + Popen objects are supported as context managers via the :keyword:`with` statement, + closing any open file descriptors on exit. + :: + + with Popen(["ifconfig"], stdout=PIPE) as proc: + log.write(proc.stdout.read()) + + .. versionchanged:: 3.2 + Added context manager support. + .. data:: PIPE Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Fri Dec 3 03:46:02 2010 @@ -697,6 +697,16 @@ data = data.replace(b"\r\n", b"\n").replace(b"\r", b"\n") return data.decode(encoding) + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + if self.stdout: + self.stdout.close() + if self.stderr: + self.stderr.close() + if self.stdin: + self.stdin.close() def __del__(self, _maxsize=sys.maxsize, _active=_active): if not self._child_created: Modified: python/branches/py3k/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k/Lib/test/test_subprocess.py (original) +++ python/branches/py3k/Lib/test/test_subprocess.py Fri Dec 3 03:46:02 2010 @@ -1183,6 +1183,47 @@ # call() function with sequence argument with spaces on Windows self.with_spaces([sys.executable, self.fname, "ab cd"]) + +class ContextManagerTests(ProcessTestCase): + + def test_pipe(self): + with subprocess.Popen([sys.executable, "-c", + "import sys;" + "sys.stdout.write('stdout');" + "sys.stderr.write('stderr');"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) as proc: + self.assertEqual(proc.stdout.read(), b"stdout") + self.assertStderrEqual(proc.stderr.read(), b"stderr") + + self.assertTrue(proc.stdout.closed) + self.assertTrue(proc.stderr.closed) + + def test_returncode(self): + with subprocess.Popen([sys.executable, "-c", + "import sys; sys.exit(100)"]) as proc: + proc.wait() + self.assertEqual(proc.returncode, 100) + + def test_communicate_stdin(self): + with subprocess.Popen([sys.executable, "-c", + "import sys;" + "sys.exit(sys.stdin.read() == 'context')"], + stdin=subprocess.PIPE) as proc: + proc.communicate(b"context") + self.assertEqual(proc.returncode, 1) + + def test_invalid_args(self): + with self.assertRaises(EnvironmentError) as c: + with subprocess.Popen(['nonexisting_i_hope'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) as proc: + pass + + if c.exception.errno != errno.ENOENT: # ignore "no such file" + raise c.exception + + def test_main(): unit_tests = (ProcessTestCase, POSIXProcessTestCase, @@ -1191,7 +1232,8 @@ CommandTests, ProcessTestCaseNoPoll, HelperFunctionTests, - CommandsWithSpaces) + CommandsWithSpaces, + ContextManagerTests) support.run_unittest(*unit_tests) support.reap_children() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 03:46:02 2010 @@ -58,6 +58,8 @@ Library ------- +- Issue #10554: Add context manager support to subprocess.Popen objects. + - Issue #8989: email.utils.make_msgid now has a domain parameter that can override the domain name used in the generated msgid. From solipsis at pitrou.net Fri Dec 3 04:49:34 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 03 Dec 2010 04:49:34 +0100 Subject: [Python-checkins] Daily py3k reference leaks (r86948): sum=0 Message-ID: py3k results for svn r86948 (hg cset 798212ac6f3c) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogxzkNCb', '-x'] From python-checkins at python.org Fri Dec 3 05:06:39 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 3 Dec 2010 05:06:39 +0100 (CET) Subject: [Python-checkins] r86952 - in python/branches/py3k: Doc/library/html.parser.rst Lib/html/parser.py Lib/test/test_htmlparser.py Misc/NEWS Message-ID: <20101203040639.AA9BEEE981@mail.python.org> Author: r.david.murray Date: Fri Dec 3 05:06:39 2010 New Revision: 86952 Log: #1486713: Add a tolerant mode to HTMLParser. The motivation for adding this option is that the the functionality it provides used to be provided by sgmllib in Python2, and was used by, for example, BeautifulSoup. Without this option, the Python3 version of BeautifulSoup and the many programs that use it are crippled. The original patch was by 'kxroberto'. I modified it heavily but kept his heuristics and test. I also added additional heuristics to fix #975556, #1046092, and part of #6191. This patch should be completely backward compatible: the behavior with the default strict=True is unchanged. Modified: python/branches/py3k/Doc/library/html.parser.rst python/branches/py3k/Lib/html/parser.py python/branches/py3k/Lib/test/test_htmlparser.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/html.parser.rst ============================================================================== --- python/branches/py3k/Doc/library/html.parser.rst (original) +++ python/branches/py3k/Doc/library/html.parser.rst Fri Dec 3 05:06:39 2010 @@ -12,9 +12,13 @@ This module defines a class :class:`HTMLParser` which serves as the basis for parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. -.. class:: HTMLParser() +.. class:: HTMLParser(strict=True) - The :class:`HTMLParser` class is instantiated without arguments. + Create a parser instance. If *strict* is ``True`` (the default), invalid + html results in :exc:`~html.parser.HTMLParseError` exceptions [#]_. If + *strict* is ``False``, the parser uses heuristics to make a best guess at + the intention of any invalid html it encounters, similar to the way most + browsers do. An :class:`HTMLParser` instance is fed HTML data and calls handler functions when tags begin and end. The :class:`HTMLParser` class is meant to be overridden by the @@ -191,3 +195,8 @@ Encountered a html end tag +.. rubric:: Footnotes + +.. [#] For backward compatibility reasons *strict* mode does not throw + errors for all non-compliant HTML. That is, some invalid HTML + is tolerated even in *strict* mode. Modified: python/branches/py3k/Lib/html/parser.py ============================================================================== --- python/branches/py3k/Lib/html/parser.py (original) +++ python/branches/py3k/Lib/html/parser.py Fri Dec 3 05:06:39 2010 @@ -24,10 +24,14 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*') +# Note, the strict one of this pair isn't really strict, but we can't +# make it correctly strict without breaking backward compatibility. attrfind = re.compile( r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]*))?') - +attrfind_tolerant = re.compile( + r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' + r'(\'[^\']*\'|"[^"]*"|[^>\s]*))?') locatestarttagend = re.compile(r""" <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name (?:\s+ # whitespace before attribute name @@ -42,6 +46,21 @@ )* \s* # trailing whitespace """, re.VERBOSE) +locatestarttagend_tolerant = re.compile(r""" + <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name + (?:\s* # optional whitespace before attribute name + (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name + (?:\s*=\s* # value indicator + (?:'[^']*' # LITA-enclosed value + |\"[^\"]*\" # LIT-enclosed value + |[^'\">\s]+ # bare value + ) + (?:\s*,)* # possibly followed by a comma + )? + ) + )* + \s* # trailing whitespace +""", re.VERBOSE) endendtag = re.compile('>') endtagfind = re.compile('') @@ -86,9 +105,15 @@ CDATA_CONTENT_ELEMENTS = ("script", "style") + def __init__(self, strict=True): + """Initialize and reset this instance. - def __init__(self): - """Initialize and reset this instance.""" + If strict is set to True (the default), errors are raised when invalid + HTML is encountered. If set to False, an attempt is instead made to + continue parsing, making "best guesses" about the intended meaning, in + a fashion similar to what browsers typically do. + """ + self.strict = strict self.reset() def reset(self): @@ -160,9 +185,18 @@ else: break if k < 0: - if end: + if not end: + break + if self.strict: self.error("EOF in middle of construct") - break + k = rawdata.find('>', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) i = self.updatepos(i, k) elif startswith("&#", i): match = charref.match(rawdata, i) @@ -193,7 +227,12 @@ if match: # match.group() will contain at least 2 chars if end and match.group() == rawdata[i:]: - self.error("EOF in middle of entity or char ref") + if self.strict: + self.error("EOF in middle of entity or char ref") + else: + if k <= i: + k = n + i = self.updatepos(i, i + 1) # incomplete break elif (i + 1) < n: @@ -240,7 +279,10 @@ self.lasttag = tag = rawdata[i+1:k].lower() while k < endpos: - m = attrfind.match(rawdata, k) + if self.strict: + m = attrfind.match(rawdata, k) + else: + m = attrfind_tolerant.search(rawdata, k) if not m: break attrname, rest, attrvalue = m.group(1, 2, 3) @@ -262,8 +304,11 @@ - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) + if self.strict: + self.error("junk characters in start tag: %r" + % (rawdata[k:endpos][:20],)) + self.handle_data(rawdata[i:endpos]) + return endpos if end.endswith('/>'): # XHTML-style empty tag: self.handle_startendtag(tag, attrs) @@ -277,7 +322,10 @@ # or -1 if incomplete. def check_for_whole_start_tag(self, i): rawdata = self.rawdata - m = locatestarttagend.match(rawdata, i) + if self.strict: + m = locatestarttagend.match(rawdata, i) + else: + m = locatestarttagend_tolerant.match(rawdata, i) if m: j = m.end() next = rawdata[j:j+1] @@ -290,8 +338,13 @@ # buffer boundary return -1 # else bogus input - self.updatepos(i, j + 1) - self.error("malformed empty start tag") + if self.strict: + self.updatepos(i, j + 1) + self.error("malformed empty start tag") + if j > i: + return j + else: + return i + 1 if next == "": # end of input return -1 @@ -300,8 +353,13 @@ # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - self.updatepos(i, j) - self.error("malformed start tag") + if self.strict: + self.updatepos(i, j) + self.error("malformed start tag") + if j > i: + return j + else: + return i + 1 raise AssertionError("we should not get here!") # Internal -- parse endtag, return end or -1 if incomplete @@ -314,7 +372,15 @@ j = match.end() match = endtagfind.match(rawdata, i) # if not match: - self.error("bad end tag: %r" % (rawdata[i:j],)) + if self.strict: + self.error("bad end tag: %r" % (rawdata[i:j],)) + k = rawdata.find('<', i + 1, j) + if k > i: + j = k + if j <= i: + j = i + 1 + self.handle_data(rawdata[i:j]) + return j tag = match.group(1) self.handle_endtag(tag.lower()) self.clear_cdata_mode() @@ -358,7 +424,8 @@ pass def unknown_decl(self, data): - self.error("unknown declaration: %r" % (data,)) + if self.strict: + self.error("unknown declaration: %r" % (data,)) # Internal -- helper to remove special character quoting entitydefs = None Modified: python/branches/py3k/Lib/test/test_htmlparser.py ============================================================================== --- python/branches/py3k/Lib/test/test_htmlparser.py (original) +++ python/branches/py3k/Lib/test/test_htmlparser.py Fri Dec 3 05:06:39 2010 @@ -8,10 +8,10 @@ class EventCollector(html.parser.HTMLParser): - def __init__(self): + def __init__(self, *args, **kw): self.events = [] self.append = self.events.append - html.parser.HTMLParser.__init__(self) + html.parser.HTMLParser.__init__(self, *args, **kw) def get_events(self): # Normalize the list of events so that buffer artefacts don't @@ -72,8 +72,10 @@ class TestCaseBase(unittest.TestCase): - def _run_check(self, source, expected_events, collector=EventCollector): - parser = collector() + def _run_check(self, source, expected_events, collector=None): + if collector is None: + collector = EventCollector() + parser = collector for s in source: parser.feed(s) parser.close() @@ -84,7 +86,7 @@ "\nReceived:\n" + pprint.pformat(events)) def _run_check_extra(self, source, events): - self._run_check(source, events, EventCollectorExtra) + self._run_check(source, events, EventCollectorExtra()) def _parse_error(self, source): def parse(source=source): @@ -321,8 +323,42 @@ ]) +class HTMLParserTolerantTestCase(TestCaseBase): + + def setUp(self): + self.collector = EventCollector(strict=False) + + def test_tolerant_parsing(self): + self._run_check('te>>xt&a<\n' + '', [ + ('starttag', 'form', + [('action', '/xxx.php?a=1&b=2&'), + ('method', 'post')])], + collector = self.collector) + + def test_weird_chars_in_unquoted_attribute_values(self): + self._run_check('
', [ + ('starttag', 'form', + [('action', 'bogus|&#()value')])], + collector = self.collector) + + def test_main(): - support.run_unittest(HTMLParserTestCase) + support.run_unittest(HTMLParserTestCase, HTMLParserTolerantTestCase) if __name__ == "__main__": Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 05:06:39 2010 @@ -58,6 +58,9 @@ Library ------- +- Issue #1486713: HTMLParser now has an optional tolerant mode where it + tries to guess at the correct parsing of invalid html. + - Issue #10554: Add context manager support to subprocess.Popen objects. - Issue #8989: email.utils.make_msgid now has a domain parameter that can From python-checkins at python.org Fri Dec 3 05:26:18 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 3 Dec 2010 05:26:18 +0100 (CET) Subject: [Python-checkins] r86953 - python/branches/py3k/Doc/library/html.parser.rst Message-ID: <20101203042618.35E9FEE982@mail.python.org> Author: r.david.murray Date: Fri Dec 3 05:26:18 2010 New Revision: 86953 Log: Add missing versionchanged, correct 'throw' wording to 'raise'. Modified: python/branches/py3k/Doc/library/html.parser.rst Modified: python/branches/py3k/Doc/library/html.parser.rst ============================================================================== --- python/branches/py3k/Doc/library/html.parser.rst (original) +++ python/branches/py3k/Doc/library/html.parser.rst Fri Dec 3 05:26:18 2010 @@ -27,6 +27,8 @@ This parser does not check that end tags match start tags or call the end-tag handler for elements which are closed implicitly by closing an outer element. + .. versionchanged:: 3.2 *strict* keyword added + An exception is defined as well: @@ -197,6 +199,6 @@ .. rubric:: Footnotes -.. [#] For backward compatibility reasons *strict* mode does not throw - errors for all non-compliant HTML. That is, some invalid HTML +.. [#] For backward compatibility reasons *strict* mode does not raise + exceptions for all non-compliant HTML. That is, some invalid HTML is tolerated even in *strict* mode. From python-checkins at python.org Fri Dec 3 08:37:16 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:37:16 +0100 (CET) Subject: [Python-checkins] r86954 - python/branches/py3k/Misc/NEWS Message-ID: <20101203073716.F2894EE9CF@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:37:16 2010 New Revision: 86954 Log: Move entries from "core" section to where they belong. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 08:37:16 2010 @@ -9,15 +9,9 @@ Core and Builtins ----------------- - -- Issue 7911: `unittest.TestCase.longMessage` defaults to True for improved - failure messages by default. Patch by Mark Roddy. - + - Issue #9915: Speed up sorting with a key. -- Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege - is held by the user's account, i.e., when the function can actually be used. - - Issue #7475: Added transform() and untransform() methods to both bytes and string types. They can be used to access those codecs providing bytes-to-bytes and string-to-string mappings. @@ -27,37 +21,35 @@ - Issue #10518: Bring back the callable() builtin. -- Issue #8879. Add os.link support for Windows. - -- Issue #10027. st_nlink was not being set on Windows calls to os.stat or - os.lstat. Patch by Hirokazu Yamamoto. - - Issue #7094: Added alternate formatting (specified by '#') to __format__ method of float, complex, and Decimal. This allows more precise control over when decimal points are displayed. - Issue #10474: range().count() should return integers. -- Issue #10255: Fix reference leak in Py_InitializeEx(). Patch by Neil - Schemenauer. +- Issue #1574217: isinstance now catches only AttributeError, rather than + masking all errors. + +Library +------- - Issue #4925: Add filename to error message when executable can't be found in subprocess. -- Issue #1574217: isinstance now catches only AttributeError, rather than - masking all errors. - - Issue #10391: Don't dereference invalid memory in error messages in the ast module. -- Issue #9518: Extend the PyModuleDef_HEAD_INIT macro to explicitly - zero-initialize all fields, fixing compiler warnings seen when building - extension modules with gcc with "-Wmissing-field-initializers" (implied - by "-W") +- Issue #10027: st_nlink was not being set on Windows calls to os.stat or + os.lstat. Patch by Hirokazu Yamamoto. -Library -------- +- Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege + is held by the user's account, i.e., when the function can actually be used. + +- Issue #8879: Add os.link support for Windows. +- Issue #7911: `unittest.TestCase.longMessage` defaults to True for improved + failure messages by default. Patch by Mark Roddy. + - Issue #1486713: HTMLParser now has an optional tolerant mode where it tries to guess at the correct parsing of invalid html. @@ -181,6 +173,14 @@ C-API ----- +- Issue #9518: Extend the PyModuleDef_HEAD_INIT macro to explicitly + zero-initialize all fields, fixing compiler warnings seen when building + extension modules with gcc with "-Wmissing-field-initializers" (implied + by "-W"). + +- Issue #10255: Fix reference leak in Py_InitializeEx(). Patch by Neil + Schemenauer. + - structseq.h is now included in Python.h. - Loosen PyArg_ValidateKeywordArguments to allow dict subclasses. From python-checkins at python.org Fri Dec 3 08:38:23 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:38:23 +0100 (CET) Subject: [Python-checkins] r86955 - in python/branches/py3k: Lib/smtpd.py Lib/test/test_smtpd.py Misc/NEWS Message-ID: <20101203073823.2AF0FEE9C9@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:38:22 2010 New Revision: 86955 Log: #1745035: add limits for command and data size to smtpd; patch by Savio Sena. Modified: python/branches/py3k/Lib/smtpd.py python/branches/py3k/Lib/test/test_smtpd.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/smtpd.py ============================================================================== --- python/branches/py3k/Lib/smtpd.py (original) +++ python/branches/py3k/Lib/smtpd.py Fri Dec 3 08:38:22 2010 @@ -109,6 +109,9 @@ COMMAND = 0 DATA = 1 + data_size_limit = 33554432 + command_size_limit = 512 + def __init__(self, server, conn, addr): asynchat.async_chat.__init__(self, conn) self.smtp_server = server @@ -121,6 +124,7 @@ self.rcpttos = [] self.received_data = '' self.fqdn = socket.getfqdn() + self.num_bytes = 0 try: self.peer = conn.getpeername() except socket.error as err: @@ -262,6 +266,15 @@ # Implementation of base class abstract method def collect_incoming_data(self, data): + limit = None + if self.smtp_state == self.COMMAND: + limit = self.command_size_limit + elif self.smtp_state == self.DATA: + limit = self.data_size_limit + if limit and self.num_bytes > limit: + return + elif limit: + self.num_bytes += len(data) self.received_lines.append(str(data, "utf8")) # Implementation of base class abstract method @@ -270,6 +283,11 @@ print('Data:', repr(line), file=DEBUGSTREAM) self.received_lines = [] if self.smtp_state == self.COMMAND: + if self.num_bytes > self.command_size_limit: + self.push('500 Error: line too long') + self.num_bytes = 0 + return + self.num_bytes = 0 if not line: self.push('500 Error: bad syntax') return @@ -290,6 +308,11 @@ else: if self.smtp_state != self.DATA: self.push('451 Internal confusion') + self.num_bytes = 0 + return + if self.num_bytes > self.data_size_limit: + self.push('552 Error: Too much mail data') + self.num_bytes = 0 return # Remove extraneous carriage returns and de-transparency according # to RFC 821, Section 4.5.2. @@ -307,6 +330,7 @@ self.rcpttos = [] self.mailfrom = None self.smtp_state = self.COMMAND + self.num_bytes = 0 self.set_terminator(b'\r\n') if not status: self.push('250 Ok') Modified: python/branches/py3k/Lib/test/test_smtpd.py ============================================================================== --- python/branches/py3k/Lib/test/test_smtpd.py (original) +++ python/branches/py3k/Lib/test/test_smtpd.py Fri Dec 3 08:38:22 2010 @@ -121,6 +121,24 @@ self.assertEqual(self.channel.socket.last, b'451 Internal confusion\r\n') + def test_command_too_long(self): + self.write_line(b'MAIL from ' + + b'a' * self.channel.command_size_limit + + b'@example') + self.assertEqual(self.channel.socket.last, + b'500 Error: line too long\r\n') + + def test_data_too_long(self): + # Small hack. Setting limit to 2K octets here will save us some time. + self.channel.data_size_limit = 2048 + self.write_line(b'MAIL From:eggs at example') + self.write_line(b'RCPT To:spam at example') + self.write_line(b'DATA') + self.write_line(b'A' * self.channel.data_size_limit + + b'A\r\n.') + self.assertEqual(self.channel.socket.last, + b'552 Error: Too much mail data\r\n') + def test_need_MAIL(self): self.write_line(b'RCPT to:spam at example') self.assertEqual(self.channel.socket.last, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 08:38:22 2010 @@ -33,6 +33,9 @@ Library ------- +- Issue #1745035: Add a command size and data size limit to smtpd.py, to + prevent DoS attacks. Patch by Savio Sena. + - Issue #4925: Add filename to error message when executable can't be found in subprocess. From python-checkins at python.org Fri Dec 3 08:44:34 2010 From: python-checkins at python.org (nick.coghlan) Date: Fri, 3 Dec 2010 08:44:34 +0100 (CET) Subject: [Python-checkins] r86956 - in python/branches/py3k: Lib/test/regrtest.py Misc/NEWS Message-ID: <20101203074434.5FA8EEE987@mail.python.org> Author: nick.coghlan Date: Fri Dec 3 08:44:33 2010 New Revision: 86956 Log: Partially revert r78719 - it removed a check that is still needed in some cases (i.e. this will allow Michael to add the test.__main__ support that broke the buildbots previously) Modified: python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Fri Dec 3 08:44:33 2010 @@ -1468,7 +1468,20 @@ assert self.isvalid() return self.expected + if __name__ == '__main__': + # Remove regrtest.py's own directory from the module search path. Despite + # the elimination of implicit relative imports, this is still needed to + # ensure that submodules of the test package do not inappropriately appear + # as top-level modules even when people (or buildbots!) invoke regrtest.py + # directly instead of using the -m switch + mydir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0]))) + i = len(sys.path) + while i >= 0: + i -= 1 + if os.path.abspath(os.path.normpath(sys.path[i])) == mydir: + del sys.path[i] + # findtestdir() gets the dirname out of __file__, so we have to make it # absolute before changing the working directory. # For example __file__ may be relative when running trace or profile. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 08:44:33 2010 @@ -191,6 +191,9 @@ Tests ----- +- regrtest.py once again ensures the test directory is removed from + sys.path when it is invoked directly as the __main__ module + - Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, `assertNotEquals`, `assertAlmostEquals`, `assertNotAlmostEquals` and `assert_` and replace them with the correct methods in the Python test suite. From python-checkins at python.org Fri Dec 3 08:47:22 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:47:22 +0100 (CET) Subject: [Python-checkins] r86957 - in python/branches/py3k: Lib/pydoc.py Lib/test/test_pydoc.py Misc/NEWS Message-ID: <20101203074722.72160EE987@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:47:22 2010 New Revision: 86957 Log: #940286: pydoc.Helper.help() ignores input/output init parameters. Modified: python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/test/test_pydoc.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Dec 3 08:47:22 2010 @@ -1310,6 +1310,11 @@ line += '\n' + self.indent(str(doc)) return line +class _PlainTextDoc(TextDoc): + """Subclass of TextDoc which overrides string styling""" + def bold(self, text): + return text + # --------------------------------------------------------- user interfaces def pager(text): @@ -1464,6 +1469,7 @@ # --------------------------------------- interactive interpreter interface text = TextDoc() +plaintext = _PlainTextDoc() html = HTMLDoc() def resolve(thing, forceload=0): @@ -1476,8 +1482,11 @@ else: return thing, getattr(thing, '__name__', None) -def render_doc(thing, title='Python Library Documentation: %s', forceload=0): +def render_doc(thing, title='Python Library Documentation: %s', forceload=0, + renderer=None): """Render text documentation, given an object or a path to an object.""" + if renderer is None: + renderer = text object, name = resolve(thing, forceload) desc = describe(object) module = inspect.getmodule(object) @@ -1496,12 +1505,16 @@ # document its available methods instead of its value. object = type(object) desc += ' object' - return title % desc + '\n\n' + text.document(object, name) + return title % desc + '\n\n' + renderer.document(object, name) -def doc(thing, title='Python Library Documentation: %s', forceload=0): +def doc(thing, title='Python Library Documentation: %s', forceload=0, + output=None): """Display text documentation, given an object or a path to an object.""" try: - pager(render_doc(thing, title, forceload)) + if output is None: + pager(render_doc(thing, title, forceload)) + else: + output.write(render_doc(thing, title, forceload, plaintext)) except (ImportError, ErrorDuringImport) as value: print(value) @@ -1755,9 +1768,9 @@ elif request in self.symbols: self.showsymbol(request) elif request in self.keywords: self.showtopic(request) elif request in self.topics: self.showtopic(request) - elif request: doc(request, 'Help on %s:') + elif request: doc(request, 'Help on %s:', output=self._output) elif isinstance(request, Helper): self() - else: doc(request, 'Help on %s:') + else: doc(request, 'Help on %s:', output=self._output) self.output.write('\n') def intro(self): Modified: python/branches/py3k/Lib/test/test_pydoc.py ============================================================================== --- python/branches/py3k/Lib/test/test_pydoc.py (original) +++ python/branches/py3k/Lib/test/test_pydoc.py Fri Dec 3 08:47:22 2010 @@ -9,9 +9,11 @@ import unittest import test.support import xml.etree +import textwrap +from io import StringIO from contextlib import contextmanager -from test.support import ( - TESTFN, forget, rmtree, EnvironmentVarGuard, reap_children) +from test.support import TESTFN, forget, rmtree, EnvironmentVarGuard, \ + reap_children, captured_output from test import pydoc_mod @@ -327,6 +329,41 @@ self.assertEqual(stripid(""), "") + @unittest.skipIf(sys.flags.optimize >= 2, + 'Docstrings are omitted with -O2 and above') + def test_help_output_redirect(self): + # issue 940286, if output is set in Helper, then all output from + # Helper.help should be redirected + old_pattern = expected_text_pattern + getpager_old = pydoc.getpager + getpager_new = lambda: (lambda x: x) + self.maxDiff = None + + buf = StringIO() + helper = pydoc.Helper(output=buf) + unused, doc_loc = get_pydoc_text(pydoc_mod) + module = "test.pydoc_mod" + help_header = """ + Help on module test.pydoc_mod in test: + + """.lstrip() + help_header = textwrap.dedent(help_header) + expected_help_pattern = help_header + expected_text_pattern + + pydoc.getpager = getpager_new + try: + with captured_output('stdout') as output, \ + captured_output('stderr') as err: + helper.help(module) + result = buf.getvalue().strip() + expected_text = expected_help_pattern % \ + (doc_loc, inspect.getabsfile(pydoc_mod)) + self.assertEqual('', output.getvalue()) + self.assertEqual('', err.getvalue()) + self.assertEqual(expected_text, result) + finally: + pydoc.getpager = getpager_old + class TestDescriptions(unittest.TestCase): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 08:47:22 2010 @@ -33,6 +33,8 @@ Library ------- +- Issue #940286: pydoc.Helper.help() ignores input/output init parameters. + - Issue #1745035: Add a command size and data size limit to smtpd.py, to prevent DoS attacks. Patch by Savio Sena. From python-checkins at python.org Fri Dec 3 08:49:09 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:49:09 +0100 (CET) Subject: [Python-checkins] r86958 - python/branches/py3k/Lib/weakref.py Message-ID: <20101203074909.255FCEC04@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:49:09 2010 New Revision: 86958 Log: Use booleans. Modified: python/branches/py3k/Lib/weakref.py Modified: python/branches/py3k/Lib/weakref.py ============================================================================== --- python/branches/py3k/Lib/weakref.py (original) +++ python/branches/py3k/Lib/weakref.py Fri Dec 3 08:49:09 2010 @@ -166,7 +166,7 @@ def popitem(self): if self._pending_removals: self._commit_removals() - while 1: + while True: key, wr = self.data.popitem() o = wr() if o is not None: @@ -324,7 +324,7 @@ try: wr = ref(key) except TypeError: - return 0 + return False return wr in self.data def items(self): @@ -362,7 +362,7 @@ return list(self.data) def popitem(self): - while 1: + while True: key, value = self.data.popitem() o = key() if o is not None: From python-checkins at python.org Fri Dec 3 08:54:09 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:54:09 +0100 (CET) Subject: [Python-checkins] r86959 - python/branches/py3k/Objects/unicodeobject.c Message-ID: <20101203075409.A8176F20A@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:54:09 2010 New Revision: 86959 Log: Remove redundant check for PyBytes in unicode_encode. Modified: python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Fri Dec 3 08:54:09 2010 @@ -7424,27 +7424,11 @@ static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; - PyObject *v; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", kwlist, &encoding, &errors)) return NULL; - v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); - if (v == NULL) - goto onError; - /* XXX this check is redundant */ - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a bytes object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - return v; - - onError: - return NULL; + return PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); } PyDoc_STRVAR(transform__doc__, From python-checkins at python.org Fri Dec 3 08:55:44 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 08:55:44 +0100 (CET) Subject: [Python-checkins] r86960 - in python/branches/py3k: Lib/_weakrefset.py Lib/test/test_weakset.py Misc/NEWS Message-ID: <20101203075544.71C4FEE981@mail.python.org> Author: georg.brandl Date: Fri Dec 3 08:55:44 2010 New Revision: 86960 Log: #10360: catch TypeError in WeakSet.__contains__, just like WeakKeyDictionary does. Modified: python/branches/py3k/Lib/_weakrefset.py python/branches/py3k/Lib/test/test_weakset.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/_weakrefset.py ============================================================================== --- python/branches/py3k/Lib/_weakrefset.py (original) +++ python/branches/py3k/Lib/_weakrefset.py Fri Dec 3 08:55:44 2010 @@ -66,7 +66,11 @@ return sum(x() is not None for x in self.data) def __contains__(self, item): - return ref(item) in self.data + try: + wr = ref(item) + except TypeError: + return False + return wr in self.data def __reduce__(self): return (self.__class__, (list(self),), Modified: python/branches/py3k/Lib/test/test_weakset.py ============================================================================== --- python/branches/py3k/Lib/test/test_weakset.py (original) +++ python/branches/py3k/Lib/test/test_weakset.py Fri Dec 3 08:55:44 2010 @@ -50,7 +50,8 @@ def test_contains(self): for c in self.letters: self.assertEqual(c in self.s, c in self.d) - self.assertRaises(TypeError, self.s.__contains__, [[]]) + # 1 is not weakref'able, but that TypeError is caught by __contains__ + self.assertNotIn(1, self.s) self.assertIn(self.obj, self.fs) del self.obj self.assertNotIn(ustr('F'), self.fs) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 08:55:44 2010 @@ -33,6 +33,9 @@ Library ------- +- Issue #10360: In WeakSet, do not raise TypeErrors when testing for + membership of non-weakrefable objects. + - Issue #940286: pydoc.Helper.help() ignores input/output init parameters. - Issue #1745035: Add a command size and data size limit to smtpd.py, to From python-checkins at python.org Fri Dec 3 10:18:37 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 10:18:37 +0100 (CET) Subject: [Python-checkins] r86961 - python/branches/py3k/Misc/NEWS Message-ID: <20101203091837.E330AEE992@mail.python.org> Author: georg.brandl Date: Fri Dec 3 10:18:37 2010 New Revision: 86961 Log: Rewrap NEWS (Builbot test commit.) Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 10:18:37 2010 @@ -9,23 +9,23 @@ Core and Builtins ----------------- - + - Issue #9915: Speed up sorting with a key. -- Issue #7475: Added transform() and untransform() methods to both bytes - and string types. They can be used to access those codecs providing +- Issue #7475: Added transform() and untransform() methods to both bytes and + string types. They can be used to access those codecs providing bytes-to-bytes and string-to-string mappings. -- Issue #8685: Speed up set difference ``a - b`` when source set ``a`` is - much larger than operand ``b``. Patch by Andrew Bennetts. +- Issue #8685: Speed up set difference ``a - b`` when source set ``a`` is much + larger than operand ``b``. Patch by Andrew Bennetts. - Issue #10518: Bring back the callable() builtin. -- Issue #7094: Added alternate formatting (specified by '#') to - __format__ method of float, complex, and Decimal. This allows more - precise control over when decimal points are displayed. +- Issue #7094: Added alternate formatting (specified by '#') to ``__format__`` + method of float, complex, and Decimal. This allows more precise control over + when decimal points are displayed. -- Issue #10474: range().count() should return integers. +- Issue #10474: range.count() should return integers. - Issue #1574217: isinstance now catches only AttributeError, rather than masking all errors. @@ -33,13 +33,13 @@ Library ------- -- Issue #10360: In WeakSet, do not raise TypeErrors when testing for - membership of non-weakrefable objects. +- Issue #10360: In WeakSet, do not raise TypeErrors when testing for membership + of non-weakrefable objects. - Issue #940286: pydoc.Helper.help() ignores input/output init parameters. -- Issue #1745035: Add a command size and data size limit to smtpd.py, to - prevent DoS attacks. Patch by Savio Sena. +- Issue #1745035: Add a command size and data size limit to smtpd.py, to prevent + DoS attacks. Patch by Savio Sena. - Issue #4925: Add filename to error message when executable can't be found in subprocess. @@ -50,28 +50,28 @@ - Issue #10027: st_nlink was not being set on Windows calls to os.stat or os.lstat. Patch by Hirokazu Yamamoto. -- Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege - is held by the user's account, i.e., when the function can actually be used. +- Issue #9333: Expose os.symlink only when the SeCreateSymbolicLinkPrivilege is + held by the user's account, i.e., when the function can actually be used. - Issue #8879: Add os.link support for Windows. -- Issue #7911: `unittest.TestCase.longMessage` defaults to True for improved +- Issue #7911: ``unittest.TestCase.longMessage`` defaults to True for improved failure messages by default. Patch by Mark Roddy. - -- Issue #1486713: HTMLParser now has an optional tolerant mode where it - tries to guess at the correct parsing of invalid html. + +- Issue #1486713: HTMLParser now has an optional tolerant mode where it tries to + guess at the correct parsing of invalid html. - Issue #10554: Add context manager support to subprocess.Popen objects. - Issue #8989: email.utils.make_msgid now has a domain parameter that can override the domain name used in the generated msgid. -- Issue #9299: Add exist_ok parameter to os.makedirs to suppress the - 'File exists' exception when a target directory already exists with the - specified mode. Patch by Ray Allen. +- Issue #9299: Add exist_ok parameter to os.makedirs to suppress the 'File + exists' exception when a target directory already exists with the specified + mode. Patch by Ray Allen. -- Issue #9573: os.fork() now works correctly when triggered as a side effect - of a module import +- Issue #9573: os.fork() now works correctly when triggered as a side effect of + a module import. - Issue #10464: netrc now correctly handles lines with embedded '#' characters. @@ -85,26 +85,26 @@ - Issue #10535: Enable silenced warnings in unittest by default. -- Issue #9873: The URL parsing functions in urllib.parse now accept - ASCII byte sequences as input in addition to character strings. +- Issue #9873: The URL parsing functions in urllib.parse now accept ASCII byte + sequences as input in addition to character strings. -- Issue #10586: The statistics API for the new functools.lru_cache has - been changed to a single cache_info() method returning a named tuple. +- Issue #10586: The statistics API for the new functools.lru_cache has been + changed to a single cache_info() method returning a named tuple. -- Issue #10323: itertools.islice() now consumes the minimum number of - inputs before stopping. Formerly, the final state of the underlying - iterator was undefined. +- Issue #10323: itertools.islice() now consumes the minimum number of inputs + before stopping. Formerly, the final state of the underlying iterator was + undefined. -- Issue #10565: The collections.Iterator ABC now checks for both - __iter__ and __next__. +- Issue #10565: The collections.Iterator ABC now checks for both __iter__ and + __next__. -- Issue #10242: Fixed implementation of unittest.ItemsEqual and gave it - a new more informative name, unittest.CountEqual. +- Issue #10242: Fixed implementation of unittest.ItemsEqual and gave it a new + more informative name, unittest.CountEqual. - Issue #10561: In pdb, clear the breakpoints by the breakpoint number. -- Issue #2986: difflib.SequenceMatcher gets a new parameter, autojunk, which - can be set to False to turn off the previously undocumented 'popularity' +- Issue #2986: difflib.SequenceMatcher gets a new parameter, autojunk, which can + be set to False to turn off the previously undocumented 'popularity' heuristic. Patch by Terry Reedy and Eli Bendersky. - Issue #9846: zipfile is now correctly closing underlying file objects. @@ -124,14 +124,14 @@ output stream only when end_headers is invoked. This is a speedup and an internal optimization. Patch by endian. -- Issue #10220: Added inspect.getgeneratorstate. Initial patch by - Rodolpho Eckhardt. +- Issue #10220: Added inspect.getgeneratorstate. Initial patch by Rodolpho + Eckhardt. - Issue #10453: compileall now uses argparse instead of getopt, and thus provides clean output when called with '-h'. -- Issue #8078: Add constants for higher baud rates in the termios module. - Patch by Rodolpho Eckhardt. +- Issue #8078: Add constants for higher baud rates in the termios module. Patch + by Rodolpho Eckhardt. - Issue #10407: Fix two NameErrors in distutils. @@ -159,9 +159,9 @@ - Issue 9926: Wrapped TestSuite subclass does not get __call__ executed. -- Issue #9920: Skip tests for cmath.atan and cmath.atanh applied to - complex zeros on systems where the log1p function fails to respect - the sign of zero. This fixes a test failure on AIX. +- Issue #9920: Skip tests for cmath.atan and cmath.atanh applied to complex + zeros on systems where the log1p function fails to respect the sign of zero. + This fixes a test failure on AIX. - Issue #9732: Addition of getattr_static to the inspect module. @@ -175,16 +175,16 @@ - Issue #10440: Support RUSAGE_THREAD as a constant in the resource module. Patch by Robert Collins. -- Issue #10429: IMAP.starttls() stored the capabilities as bytes objects, - rather than strings. +- Issue #10429: IMAP.starttls() stored the capabilities as bytes objects, rather + than strings. C-API ----- - Issue #9518: Extend the PyModuleDef_HEAD_INIT macro to explicitly zero-initialize all fields, fixing compiler warnings seen when building - extension modules with gcc with "-Wmissing-field-initializers" (implied - by "-W"). + extension modules with gcc with "-Wmissing-field-initializers" (implied by + "-W"). - Issue #10255: Fix reference leak in Py_InitializeEx(). Patch by Neil Schemenauer. @@ -196,15 +196,15 @@ Tests ----- -- regrtest.py once again ensures the test directory is removed from - sys.path when it is invoked directly as the __main__ module +- regrtest.py once again ensures the test directory is removed from sys.path + when it is invoked directly as the __main__ module - Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, `assertNotEquals`, `assertAlmostEquals`, `assertNotAlmostEquals` and `assert_` and replace them with the correct methods in the Python test suite. -- Do not fail test_socket when the IP address of the local hostname - cannot be looked up. +- Do not fail test_socket when the IP address of the local hostname cannot be + looked up. - Issue #8886: Use context managers throughout test_zipfile. Patch by Eric Carstensen. From python-checkins at python.org Fri Dec 3 10:29:12 2010 From: python-checkins at python.org (nick.coghlan) Date: Fri, 3 Dec 2010 10:29:12 +0100 (CET) Subject: [Python-checkins] r86962 - in python/branches/py3k: Doc/library/pydoc.rst Doc/whatsnew/3.2.rst Lib/pydoc.py Lib/test/test_pydoc.py Misc/ACKS Misc/NEWS Message-ID: <20101203092912.3D2A0EE981@mail.python.org> Author: nick.coghlan Date: Fri Dec 3 10:29:11 2010 New Revision: 86962 Log: Improve Pydoc interactive browsing (#2001). Patch by Ron Adam. * A -b option to start an enhanced browsing session. * Allow -b and -p options to be used together. * Specifying port 0 will pick an arbitrary unused socket port. * A new browse() function to start the new server and browser. * Show Python version information in the header. * A *Get* field which takes the same input as the help() function. * A *Search* field which replaces the Tkinter search box. * Links to *Module Index*, *Topics*, and *Keywords*. * Improved source file viewing. * An HTMLDoc.filelink() method. * The -g option and the gui() and serve() functions are deprecated. Modified: python/branches/py3k/Doc/library/pydoc.rst python/branches/py3k/Doc/whatsnew/3.2.rst python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/test/test_pydoc.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/pydoc.rst ============================================================================== --- python/branches/py3k/Doc/library/pydoc.rst (original) +++ python/branches/py3k/Doc/library/pydoc.rst Fri Dec 3 10:29:11 2010 @@ -50,12 +50,21 @@ module is the first line of its documentation string. You can also use :program:`pydoc` to start an HTTP server on the local machine -that will serve documentation to visiting Web browsers. :program:`pydoc -p 1234` -will start a HTTP server on port 1234, allowing you to browse -the documentation at ``http://localhost:1234/`` in your preferred Web browser. +that will serve documentation to visiting Web browsers. :program:`pydoc -p 1234` +will start a HTTP server on port 1234, allowing you to browse the +documentation at ``http://localhost:1234/`` in your preferred Web browser. +Specifying ``0`` as the port number will select an arbitrary unused port. + :program:`pydoc -g` will start the server and additionally bring up a small :mod:`tkinter`\ -based graphical interface to help you search for -documentation pages. +documentation pages. The ``-g`` option is deprecated, since the server can +now be controlled directly from HTTP clients. + +:program:`pydoc -b` will start the server and additionally open a web +browser to a module index page. Each served page has a navigation bar at the +top where you can *Get* help on an individual item, *Search* all modules with a +keyword in their synopsis line, and go to the *Module index*, *Topics* and +*Keywords* pages. When :program:`pydoc` generates documentation, it uses the current environment and path to locate modules. Thus, invoking :program:`pydoc spam` @@ -69,3 +78,4 @@ to a different URL or to a local directory containing the Library Reference Manual pages. +.. versionchanged:: 3.2 Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Fri Dec 3 10:29:11 2010 @@ -566,7 +566,6 @@ (Contributed by R. David Murray, :issue:`10321`.) - * The :mod:`inspect` module has a new function :func:`getgenatorstate` to easily identify the current state of a generator as one of ``GEN_CREATED``, ``GEN_RUNNING``, ``GEN_SUSPENDED`` or ``GEN_CLOSED``. @@ -583,6 +582,12 @@ - non-UTF8 percent encoding of non-ASCII characters Issue 2987 for IPv6 (RFC2732) support in urlparse +* The :mod:`pydoc` module now provides a much improved Web server interface, + as well as a new command-line option to automatically open a browser + window to display that server. + + (Contributed by Ron Adam; :issue:`2001`.) + Multi-threading =============== Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Dec 3 10:29:11 2010 @@ -15,11 +15,17 @@ Run "pydoc -k " to search for a keyword in the synopsis lines of all available modules. -Run "pydoc -p " to start an HTTP server on a given port on the -local machine to generate documentation web pages. +Run "pydoc -p " to start an HTTP server on the given port on the +local machine. Port number 0 can be used to get an arbitrary unused port. + +Run "pydoc -b" to start an HTTP server on an arbitrary unused port and +open a Web browser to interactively browse documentation. The -p option +can be used with the -b option to explicitly specify the server port. For platforms without a command line, "pydoc -g" starts the HTTP server -and also pops up a little window for controlling it. +and also pops up a little window for controlling it. This option is +deprecated, since the server can now be controlled directly from HTTP +clients. Run "pydoc -w " to write out the HTML documentation for a module to a file named ".html". @@ -51,10 +57,22 @@ # the current directory is changed with os.chdir(), an incorrect # path will be displayed. -import sys, imp, os, re, inspect, builtins, pkgutil -from reprlib import Repr -from traceback import extract_tb as _extract_tb +import os +import sys +import builtins +import imp +import io +import inspect +import pkgutil +import platform +import re +import time +import warnings from collections import deque +from reprlib import Repr +from traceback import extract_tb + + # --------------------------------------------------------- common routines def pathdirs(): @@ -285,7 +303,7 @@ elif exc is SyntaxError: # A SyntaxError occurred before we could execute the module. raise ErrorDuringImport(value.filename, info) - elif exc is ImportError and _extract_tb(tb)[-1][2]=='safeimport': + elif exc is ImportError and extract_tb(tb)[-1][2]=='safeimport': # The import error occurred directly in this function, # which means there is no such module in the path. return None @@ -513,6 +531,10 @@ text = name return '%s' % (url, text) + def filelink(self, url, path): + """Make a link to source file.""" + return '%s' % (url, path) + def markup(self, text, escape=None, funcs={}, classes={}, methods={}): """Mark up some plain text, given a context of symbols to look for. Each context dictionary maps object names to anchor names.""" @@ -591,7 +613,7 @@ if sys.platform == 'win32': import nturl2path url = nturl2path.pathname2url(path) - filelink = '%s' % (url, path) + filelink = self.filelink(url, path) except TypeError: filelink = '(built-in)' info = [] @@ -1851,12 +1873,40 @@ if more_xrefs: xrefs = (xrefs or '') + ' ' + more_xrefs if xrefs: - import io, formatter + import formatter buffer = io.StringIO() formatter.DumbWriter(buffer).send_flowing_data( 'Related help topics: ' + ', '.join(xrefs.split()) + '\n') self.output.write('\n%s\n' % buffer.getvalue()) + def _gettopic(self, topic, more_xrefs=''): + """Return unbuffered tuple of (topic, xrefs). + + If an error occurs, topic is the error message, and xrefs is ''. + This function duplicates the showtopic method but returns its + result directly so it can be formatted for display in an html page. + """ + try: + import pydoc_data.topics + except ImportError: + return(''' +Sorry, topic and keyword documentation is not available because the +module "pydoc_data.topics" could not be found. +''' , '') + target = self.topics.get(topic, self.keywords.get(topic)) + if not target: + return 'no documentation found for %r' % topic, '' + if isinstance(target, str): + return self._gettopic(target, more_xrefs) + label, xrefs = target + try: + doc = pydoc_data.topics.topics[label] + except KeyError: + return 'no documentation found for %r' % topic, '' + if more_xrefs: + xrefs = (xrefs or '') + ' ' + more_xrefs + return doc, xrefs + def showsymbol(self, symbol): target = self.symbols[symbol] topic, _, xrefs = target.partition(' ') @@ -1938,6 +1988,15 @@ for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror): if self.quit: break + + # XXX Skipping this file is a workaround for a bug + # that causes python to crash with a segfault. + # http://bugs.python.org/issue9319 + # + # TODO Remove this once the bug is fixed. + if modname in {'test.badsyntax_pep3120', 'badsyntax_pep3120'}: + continue + if key is None: callback(None, modname, '') else: @@ -1953,7 +2012,6 @@ if onerror: onerror(modname) continue - import io desc = source_synopsis(io.StringIO(source)) or '' if hasattr(loader, 'get_filename'): path = loader.get_filename(modname) @@ -1983,16 +2041,18 @@ print(modname, desc and '- ' + desc) def onerror(modname): pass - try: import warnings - except ImportError: pass - else: warnings.filterwarnings('ignore') # ignore problems during import - ModuleScanner().run(callback, key, onerror=onerror) + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') # ignore problems during import + ModuleScanner().run(callback, key, onerror=onerror) -# --------------------------------------------------- web browser interface +# --------------------------------------------------- Web browser interface def serve(port, callback=None, completer=None): import http.server, email.message, select + msg = 'the pydoc.serve() function is deprecated' + warnings.warn(msg, DeprecationWarning, stacklevel=2) + class DocHandler(http.server.BaseHTTPRequestHandler): def send_document(self, title, contents): try: @@ -2071,7 +2131,12 @@ # ----------------------------------------------------- graphical interface def gui(): - """Graphical interface (starts web server and pops up a control window).""" + """Graphical interface (starts Web server and pops up a control window).""" + + msg = ('the pydoc.gui() function and "pydoc -g" option are deprecated\n', + 'use "pydoc.browse() function and "pydoc -b" option instead.') + warnings.warn(msg, DeprecationWarning, stacklevel=2) + class GUI: def __init__(self, window, port=7464): self.window = window @@ -2151,15 +2216,8 @@ def open(self, event=None, url=None): url = url or self.server.url - try: - import webbrowser - webbrowser.open(url) - except ImportError: # pre-webbrowser.py compatibility - if sys.platform == 'win32': - os.system('start "%s"' % url) - else: - rc = os.system('netscape -remote "openURL(%s)" &' % url) - if rc: os.system('netscape "%s" &' % url) + import webbrowser + webbrowser.open(url) def quit(self, event=None): if self.server: @@ -2251,6 +2309,433 @@ except KeyboardInterrupt: pass + +# --------------------------------------- enhanced Web browser interface + +def _start_server(urlhandler, port): + """Start an HTTP server thread on a specific port. + + Start an HTML/text server thread, so HTML or text documents can be + browsed dynamically and interactively with a Web browser. Example use: + + >>> import time + >>> import pydoc + + Define a URL handler. To determine what the client is asking + for, check the URL and content_type. + + Then get or generate some text or HTML code and return it. + + >>> def my_url_handler(url, content_type): + ... text = 'the URL sent was: (%s, %s)' % (url, content_type) + ... return text + + Start server thread on port 0. + If you use port 0, the server will pick a random port number. + You can then use serverthread.port to get the port number. + + >>> port = 0 + >>> serverthread = pydoc._start_server(my_url_handler, port) + + Check that the server is really started. If it is, open browser + and get first page. Use serverthread.url as the starting page. + + >>> if serverthread.serving: + ... import webbrowser + + The next two lines are commented out so a browser doesn't open if + doctest is run on this module. + + #... webbrowser.open(serverthread.url) + #True + + Let the server do its thing. We just need to monitor its status. + Use time.sleep so the loop doesn't hog the CPU. + + >>> starttime = time.time() + >>> timeout = 1 #seconds + + This is a short timeout for testing purposes. + + >>> while serverthread.serving: + ... time.sleep(.01) + ... if serverthread.serving and time.time() - starttime > timeout: + ... serverthread.stop() + ... break + + Print any errors that may have occurred. + + >>> print(serverthread.error) + None + """ + import http.server + import email.message + import select + import threading + + class DocHandler(http.server.BaseHTTPRequestHandler): + + def do_GET(self): + """Process a request from an HTML browser. + + The URL received is in self.path. + Get an HTML page from self.urlhandler and send it. + """ + if self.path.endswith('.css'): + content_type = 'text/css' + else: + content_type = 'text/html' + self.send_response(200) + self.send_header('Content-Type', '%s;charset=UTF-8' % content_type) + self.end_headers() + self.wfile.write(self.urlhandler( + self.path, content_type).encode('utf-8')) + + def log_message(self, *args): + # Don't log messages. + pass + + class DocServer(http.server.HTTPServer): + + def __init__(self, port, callback): + self.host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost' + self.address = ('', port) + self.callback = callback + self.base.__init__(self, self.address, self.handler) + self.quit = False + + def serve_until_quit(self): + while not self.quit: + rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) + if rd: + self.handle_request() + + def server_activate(self): + self.base.server_activate(self) + if self.callback: + self.callback(self) + + class ServerThread(threading.Thread): + + def __init__(self, urlhandler, port): + self.urlhandler = urlhandler + self.port = int(port) + threading.Thread.__init__(self) + self.serving = False + self.error = None + + def run(self): + """Start the server.""" + try: + DocServer.base = http.server.HTTPServer + DocServer.handler = DocHandler + DocHandler.MessageClass = email.message.Message + DocHandler.urlhandler = staticmethod(self.urlhandler) + docsvr = DocServer(self.port, self.ready) + self.docserver = docsvr + docsvr.serve_until_quit() + except Exception as e: + self.error = e + + def ready(self, server): + self.serving = True + self.host = server.host + self.port = server.server_port + self.url = 'http://%s:%d/' % (self.host, self.port) + + def stop(self): + """Stop the server and this thread nicely""" + self.docserver.quit = True + self.serving = False + self.url = None + + thread = ServerThread(urlhandler, port) + thread.start() + # Wait until thread.serving is True to make sure we are + # really up before returning. + while not thread.error and not thread.serving: + time.sleep(.01) + return thread + + +def _url_handler(url, content_type="text/html"): + """The pydoc url handler for use with the pydoc server. + + If the content_type is 'text/css', the _pydoc.css style + sheet is read and returned if it exits. + + If the content_type is 'text/html', then the result of + get_html_page(url) is returned. + """ + class _HTMLDoc(HTMLDoc): + + def page(self, title, contents): + """Format an HTML page.""" + css_path = "pydoc_data/_pydoc.css" + css_link = ( + '' % + css_path) + return '''\ + +Python: %s + +%s%s +''' % (title, css_link, contents) + + def filelink(self, url, path): + return '%s' % (url, path) + + + html = _HTMLDoc() + + def html_navbar(): + version = "%s [%s, %s]" % (platform.python_version(), + platform.python_build()[0], + platform.python_compiler()) + return """ +
+ Python %s
%s

+
+
+ +
+ + + +     + +
+ + +
+
+
+
 
+ """ % (version, platform.platform(terse=True)) + + def html_index(): + """Module Index page.""" + + def bltinlink(name): + return '%s' % (name, name) + + heading = html.heading( + 'Index of Modules', + '#ffffff', '#7799ee') + names = [name for name in sys.builtin_module_names + if name != '__main__'] + contents = html.multicolumn(names, bltinlink) + contents = [heading, '

' + html.bigsection( + 'Built-in Modules', '#ffffff', '#ee77aa', contents)] + + seen = {} + for dir in sys.path: + contents.append(html.index(dir, seen)) + + contents.append( + '

pydoc by Ka-Ping Yee' + '<ping at lfw.org>') + return html.page('Index of Modules', ''.join(contents)) + + def html_search(key): + """Search results page.""" + # scan for modules + search_result = [] + + def callback(path, modname, desc): + if modname[-9:] == '.__init__': + modname = modname[:-9] + ' (package)' + search_result.append((modname, desc and '- ' + desc)) + + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') # ignore problems during import + ModuleScanner().run(callback, key) + + # format page + def bltinlink(name): + return '%s' % (name, name) + + results = [] + heading = html.heading( + 'Search Results', + '#ffffff', '#7799ee') + for name, desc in search_result: + results.append(bltinlink(name) + desc) + contents = heading + html.bigsection( + 'key = %s' % key, '#ffffff', '#ee77aa', '
'.join(results)) + return html.page('Search Results', contents) + + def html_getfile(path): + """Get and display a source file listing safely.""" + path = os.sep + path.replace('%20', ' ') + with open(path, 'r') as fp: + lines = html.escape(fp.read()) + body = '

%s
' % lines + heading = html.heading( + 'File Listing', + '#ffffff', '#7799ee') + contents = heading + html.bigsection( + 'File: %s' % path, '#ffffff', '#ee77aa', body) + return html.page('getfile %s' % path, contents) + + def html_topics(): + """Index of topic texts available.""" + + def bltinlink(name): + return '%s' % (name, name) + + heading = html.heading( + 'INDEX', + '#ffffff', '#7799ee') + names = sorted(Helper.topics.keys()) + + contents = html.multicolumn(names, bltinlink) + contents = heading + html.bigsection( + 'Topics', '#ffffff', '#ee77aa', contents) + return html.page('Topics', contents) + + def html_keywords(): + """Index of keywords.""" + heading = html.heading( + 'INDEX', + '#ffffff', '#7799ee') + names = sorted(Helper.keywords.keys()) + + def bltinlink(name): + return '%s' % (name, name) + + contents = html.multicolumn(names, bltinlink) + contents = heading + html.bigsection( + 'Keywords', '#ffffff', '#ee77aa', contents) + return html.page('Keywords', contents) + + def html_topicpage(topic): + """Topic or keyword help page.""" + buf = io.StringIO() + htmlhelp = Helper(buf, buf) + contents, xrefs = htmlhelp._gettopic(topic) + if topic in htmlhelp.keywords: + title = 'KEYWORD' + else: + title = 'TOPIC' + heading = html.heading( + '%s' % title, + '#ffffff', '#7799ee') + contents = '
%s
' % contents + contents = html.bigsection(topic , '#ffffff','#ee77aa', contents) + xrefs = sorted(xrefs.split()) + + def bltinlink(name): + return '%s' % (name, name) + + xrefs = html.multicolumn(xrefs, bltinlink) + xrefs = html.section('Related help topics: ', + '#ffffff', '#ee77aa', xrefs) + return html.page('%s %s' % (title, topic), + ''.join((heading, contents, xrefs))) + + def html_error(url): + heading = html.heading( + 'Error', + '#ffffff', '#ee0000') + return heading + url + + def get_html_page(url): + """Generate an HTML page for url.""" + if url.endswith('.html'): + url = url[:-5] + if url.startswith('/'): + url = url[1:] + if url.startswith("get?key="): + url = url[8:] + title = url + contents = '' + if url in ("", ".", "index"): + contents = html_index() + elif url == "topics": + contents = html_topics() + elif url == "keywords": + contents = html_keywords() + elif url.startswith("search?key="): + contents = html_search(url[11:]) + elif url.startswith("getfile?key="): + url = url[12:] + try: + contents = html_getfile(url) + except IOError: + contents = html_error('could not read file %r' % url) + title = 'Read Error' + else: + obj = None + try: + obj = locate(url, forceload=1) + except ErrorDuringImport as value: + contents = html.escape(str(value)) + if obj: + title = describe(obj) + contents = html.document(obj, url) + elif url in Helper.keywords or url in Helper.topics: + contents = html_topicpage(url) + else: + contents = html_error( + 'no Python documentation found for %r' % url) + title = 'Error' + return html.page(title, html_navbar() + contents) + + if url.startswith('/'): + url = url[1:] + if content_type == 'text/css': + path_here = os.path.dirname(os.path.realpath(__file__)) + try: + with open(os.path.join(path_here, url)) as fp: + return ''.join(fp.readlines()) + except IOError: + return 'Error: can not open css file %r' % url + elif content_type == 'text/html': + return get_html_page(url) + return 'Error: unknown content type %r' % content_type + + +def browse(port=0, *, open_browser=True): + """Start the enhanced pydoc Web server and open a Web browser. + + Use port '0' to start the server on an arbitrary port. + Set open_browser to False to suppress opening a browser. + """ + import webbrowser + serverthread = _start_server(_url_handler, port) + if serverthread.error: + print(serverthread.error) + return + if serverthread.serving: + server_help_msg = 'Server commands: [b]rowser, [q]uit' + if open_browser: + webbrowser.open(serverthread.url) + try: + print('Server ready at', serverthread.url) + print(server_help_msg) + while serverthread.serving: + cmd = input('server> ') + cmd = cmd.lower() + if cmd == 'q': + break + elif cmd == 'b': + webbrowser.open(serverthread.url) + else: + print(server_help_msg) + except (KeyboardInterrupt, EOFError): + print() + finally: + if serverthread.serving: + serverthread.stop() + print('Server stopped') + + # -------------------------------------------------- command-line interface def ispath(x): @@ -2270,29 +2755,32 @@ sys.path.insert(0, '.') try: - opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') - writing = 0 - + opts, args = getopt.getopt(sys.argv[1:], 'bgk:p:w') + writing = False + start_server = False + open_browser = False + port = None for opt, val in opts: if opt == '-g': gui() return + if opt == '-b': + start_server = True + open_browser = True if opt == '-k': apropos(val) return if opt == '-p': - try: - port = int(val) - except ValueError: - raise BadUsage - def ready(server): - print('pydoc server ready at %s' % server.url) - def stopped(): - print('pydoc server stopped') - serve(port, ready, stopped) - return + start_server = True + port = val if opt == '-w': - writing = 1 + writing = True + + if start_server == True: + if port == None: + port = 0 + browse(port, open_browser=open_browser) + return if not args: raise BadUsage for arg in args: @@ -2313,30 +2801,37 @@ print(value) except (getopt.error, BadUsage): - cmd = os.path.basename(sys.argv[0]) + cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0] print("""pydoc - the Python documentation tool -%s ... +{cmd} ... Show text documentation on something. may be the name of a Python keyword, topic, function, module, or package, or a dotted reference to a class or function within a module or module in a - package. If contains a '%s', it is used as the path to a + package. If contains a '{sep}', it is used as the path to a Python source file to document. If name is 'keywords', 'topics', or 'modules', a listing of these things is displayed. -%s -k +{cmd} -k Search for a keyword in the synopsis lines of all available modules. -%s -p - Start an HTTP server on the given port on the local machine. +{cmd} -p + Start an HTTP server on the given port on the local machine. Port + number 0 can be used to get an arbitrary unused port. + +{cmd} -b + Start an HTTP server on an arbitrary unused port and open a Web browser + to interactively browse documentation. The -p option can be used with + the -b option to explicitly specify the server port. -%s -g - Pop up a graphical interface for finding and serving documentation. +{cmd} -g + Deprecated. -%s -w ... +{cmd} -w ... Write out the HTML documentation for a module to a file in the current - directory. If contains a '%s', it is treated as a filename; if + directory. If contains a '{sep}', it is treated as a filename; if it names a directory, documentation is written for all the contents. -""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)) +""".format(cmd=cmd, sep=os.sep)) -if __name__ == '__main__': cli() +if __name__ == '__main__': + cli() Modified: python/branches/py3k/Lib/test/test_pydoc.py ============================================================================== --- python/branches/py3k/Lib/test/test_pydoc.py (original) +++ python/branches/py3k/Lib/test/test_pydoc.py Fri Dec 3 10:29:11 2010 @@ -1,13 +1,14 @@ -import sys import os -import os.path +import sys import difflib -import subprocess -import re -import pydoc import inspect -import unittest +import pydoc +import re +import string +import subprocess import test.support +import time +import unittest import xml.etree import textwrap from io import StringIO @@ -221,19 +222,25 @@ output = doc.docmodule(module) - # cleanup the extra text formatting that pydoc preforms + # clean up the extra text formatting that pydoc performs patt = re.compile('\b.') output = patt.sub('', output) return output.strip(), loc def print_diffs(text1, text2): "Prints unified diffs for two texts" + # XXX now obsolete, use unittest built-in support lines1 = text1.splitlines(True) lines2 = text2.splitlines(True) diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected', tofile='got') print('\n' + ''.join(diffs)) +def get_html_title(text): + _, _, text = text.rpartition("") + title, _, _ = text.rpartition("") + return title + class PyDocDocTest(unittest.TestCase): @@ -373,16 +380,8 @@ doc = pydoc.render_doc(pydocfodder) self.assertIn("pydocfodder", doc) - def test_classic_class(self): - class C: "Classic class" - c = C() - self.assertEqual(pydoc.describe(C), 'class C') - self.assertEqual(pydoc.describe(c), 'C') - expected = 'C in module %s' % __name__ - self.assertIn(expected, pydoc.render_doc(c)) - def test_class(self): - class C(object): "New-style class" + class C: "New-style class" c = C() self.assertEqual(pydoc.describe(C), 'class C') @@ -391,8 +390,78 @@ self.assertIn(expected, pydoc.render_doc(c)) +class PyDocServerTest(unittest.TestCase): + """Tests for pydoc._start_server""" + + def test_server(self): + + # Minimal test that starts the server, then stops it. + def my_url_handler(url, content_type): + text = 'the URL sent was: (%s, %s)' % (url, content_type) + return text + + serverthread = pydoc._start_server(my_url_handler, port=0) + starttime = time.time() + timeout = 1 #seconds + + while serverthread.serving: + time.sleep(.01) + if serverthread.serving and time.time() - starttime > timeout: + serverthread.stop() + break + + self.assertEqual(serverthread.error, None) + + +class PyDocUrlHandlerTest(unittest.TestCase): + """Tests for pydoc._url_handler""" + + def test_content_type_err(self): + err = 'Error: unknown content type ' + f = pydoc._url_handler + result = f("", "") + self.assertEqual(result, err + "''") + result = f("", "foobar") + self.assertEqual(result, err + "'foobar'") + + def test_url_requests(self): + # Test for the correct title in the html pages returned. + # This tests the different parts of the URL handler without + # getting too picky about the exact html. + requests = [ + ("", "Python: Index of Modules"), + ("get?key=", "Python: Index of Modules"), + ("index", "Python: Index of Modules"), + ("topics", "Python: Topics"), + ("keywords", "Python: Keywords"), + ("pydoc", "Python: module pydoc"), + ("get?key=pydoc", "Python: module pydoc"), + ("search?key=pydoc", "Python: Search Results"), + ("def", "Python: KEYWORD def"), + ("STRINGS", "Python: TOPIC STRINGS"), + ("foobar", "Python: Error"), + ("getfile?key=foobar", "Python: Read Error"), + ] + + for url, title in requests: + text = pydoc._url_handler(url, "text/html") + result = get_html_title(text) + self.assertEqual(result, title) + + path = string.__file__ + title = "Python: getfile /" + path + url = "getfile?key=" + path + text = pydoc._url_handler(url, "text/html") + result = get_html_title(text) + self.assertEqual(result, title) + + def test_main(): - test.support.run_unittest(PyDocDocTest, TestDescriptions) + test.support.run_unittest(PyDocDocTest, + TestDescriptions, + PyDocServerTest, + PyDocUrlHandlerTest, + ) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Fri Dec 3 10:29:11 2010 @@ -12,6 +12,7 @@ and the list is in rough alphabetical order by last names. David Abrahams +Ron Adam Jim Ahlstrom Farhan Ahmad Matthew Ahrens Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 10:29:11 2010 @@ -33,6 +33,9 @@ Library ------- +- Issue #2001: New HTML server with enhanced Web page features. Patch by Ron + Adam. + - Issue #10360: In WeakSet, do not raise TypeErrors when testing for membership of non-weakrefable objects. From python-checkins at python.org Fri Dec 3 10:45:33 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 10:45:33 +0100 (CET) Subject: [Python-checkins] r86963 - python/branches/py3k/Doc/library/pydoc.rst Message-ID: <20101203094533.43270EC04@mail.python.org> Author: georg.brandl Date: Fri Dec 3 10:45:33 2010 New Revision: 86963 Log: Add a line with the actual changes. Modified: python/branches/py3k/Doc/library/pydoc.rst Modified: python/branches/py3k/Doc/library/pydoc.rst ============================================================================== --- python/branches/py3k/Doc/library/pydoc.rst (original) +++ python/branches/py3k/Doc/library/pydoc.rst Fri Dec 3 10:45:33 2010 @@ -79,3 +79,4 @@ Reference Manual pages. .. versionchanged:: 3.2 + Added the ``-b`` option, deprecated the ``-g`` option. From python-checkins at python.org Fri Dec 3 10:58:38 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 10:58:38 +0100 (CET) Subject: [Python-checkins] r86964 - in python/branches/py3k: Lib/pydoc.py Misc/NEWS Message-ID: <20101203095838.ABF4BEE982@mail.python.org> Author: georg.brandl Date: Fri Dec 3 10:58:38 2010 New Revision: 86964 Log: #10549: fix interface of docclass() for text documenter. Modified: python/branches/py3k/Lib/pydoc.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Dec 3 10:58:38 2010 @@ -1132,7 +1132,7 @@ result = result + self.section('FILE', file) return result - def docclass(self, object, name=None, mod=None): + def docclass(self, object, name=None, mod=None, *ignored): """Produce text documentation for a given class object.""" realname = object.__name__ name = name or realname Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 10:58:38 2010 @@ -33,6 +33,8 @@ Library ------- +- Issue #10549: Fix pydoc traceback when text-documenting certain classes. + - Issue #2001: New HTML server with enhanced Web page features. Patch by Ron Adam. From python-checkins at python.org Fri Dec 3 11:42:03 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 11:42:03 +0100 (CET) Subject: [Python-checkins] r86965 - python/branches/py3k/Lib/test/__main__.py Message-ID: <20101203104203.E5461EE982@mail.python.org> Author: michael.foord Date: Fri Dec 3 11:42:03 2010 New Revision: 86965 Log: Adding lib/test/__main__.py for running tests with 'python -m test' Added: python/branches/py3k/Lib/test/__main__.py (contents, props changed) Added: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/__main__.py Fri Dec 3 11:42:03 2010 @@ -0,0 +1,40 @@ +import os +import sys +import sysconfig + +from test import support +from test import regrtest + +# findtestdir() gets the dirname out of __file__, so we have to make it +# absolute before changing the working directory. +# For example __file__ may be relative when running trace or profile. +# See issue #9323. +__file__ = os.path.abspath(__file__) + +# sanity check +assert __file__ == os.path.abspath(sys.argv[0]) + +# When tests are run from the Python build directory, it is best practice +# to keep the test files in a subfolder. It eases the cleanup of leftover +# files using command "make distclean". +if sysconfig.is_python_build(): + TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') + TEMPDIR = os.path.abspath(TEMPDIR) + if not os.path.exists(TEMPDIR): + os.mkdir(TEMPDIR) + regrtest.TEMPDIR = TEMPDIR + +# Define a writable temp dir that will be used as cwd while running +# the tests. The name of the dir includes the pid to allow parallel +# testing (see the -j option). +TESTCWD = 'test_python_{}'.format(os.getpid()) + +TESTCWD = os.path.join(TEMPDIR, TESTCWD) +regrtest.TESTCWD = TESTCWD + +# Run the tests in a context manager that temporary changes the CWD to a +# temporary and writable directory. If it's not possible to create or +# change the CWD, the original CWD will be used. The original CWD is +# available from support.SAVEDCWD. +with support.temp_cwd(TESTCWD, quiet=True): + regrtest.main() From ncoghlan at gmail.com Fri Dec 3 11:53:04 2010 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 3 Dec 2010 20:53:04 +1000 Subject: [Python-checkins] r86965 - python/branches/py3k/Lib/test/__main__.py In-Reply-To: <20101203104203.E5461EE982@mail.python.org> References: <20101203104203.E5461EE982@mail.python.org> Message-ID: On Fri, Dec 3, 2010 at 8:42 PM, michael.foord wrote: > +# When tests are run from the Python build directory, it is best practice > +# to keep the test files in a subfolder. ?It eases the cleanup of leftover > +# files using command "make distclean". > +if sysconfig.is_python_build(): > + ? ?TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') > + ? ?TEMPDIR = os.path.abspath(TEMPDIR) > + ? ?if not os.path.exists(TEMPDIR): > + ? ? ? ?os.mkdir(TEMPDIR) > + ? ?regrtest.TEMPDIR = TEMPDIR If syconfig.is_python_build() returns False... > +# Define a writable temp dir that will be used as cwd while running > +# the tests. The name of the dir includes the pid to allow parallel > +# testing (see the -j option). > +TESTCWD = 'test_python_{}'.format(os.getpid()) > + > +TESTCWD = os.path.join(TEMPDIR, TESTCWD) ... this line is going to blow up with a NameError. I would suggest putting this common setup code into a _make_test_dir() helper function in regrtest, then have both regrtest and test.__main__ call it. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Fri Dec 3 11:59:16 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 11:59:16 +0100 (CET) Subject: [Python-checkins] r86966 - python/branches/py3k/Lib/test/__main__.py Message-ID: <20101203105916.219F7EE99A@mail.python.org> Author: michael.foord Date: Fri Dec 3 11:59:15 2010 New Revision: 86966 Log: Fix lib/test/__main__.py to work even outside a Python build. Modified: python/branches/py3k/Lib/test/__main__.py Modified: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- python/branches/py3k/Lib/test/__main__.py (original) +++ python/branches/py3k/Lib/test/__main__.py Fri Dec 3 11:59:15 2010 @@ -5,6 +5,8 @@ from test import support from test import regrtest +TEMPDIR = regrtest.TEMPDIR + # findtestdir() gets the dirname out of __file__, so we have to make it # absolute before changing the working directory. # For example __file__ may be relative when running trace or profile. From python-checkins at python.org Fri Dec 3 12:50:38 2010 From: python-checkins at python.org (vinay.sajip) Date: Fri, 3 Dec 2010 12:50:38 +0100 (CET) Subject: [Python-checkins] r86967 - in python/branches/py3k: Doc/library/logging.rst Lib/logging/__init__.py Lib/test/test_logging.py Misc/NEWS Message-ID: <20101203115038.A03FBEE982@mail.python.org> Author: vinay.sajip Date: Fri Dec 3 12:50:38 2010 New Revision: 86967 Log: logging: Added getLogRecordFactory/setLogRecordFactory with docs and tests. Modified: python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Lib/logging/__init__.py python/branches/py3k/Lib/test/test_logging.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Fri Dec 3 12:50:38 2010 @@ -750,6 +750,19 @@ # ... override behaviour here +.. function:: getLogRecordFactory() + + Return a callable which is used to create a :class:`LogRecord`. + + .. versionadded:: 3.2 + + This function has been provided, along with :func:`setLogRecordFactory`, + to allow developers more control over how the :class:`LogRecord` + representing a logging event is constructed. + + See :func:`setLogRecordFactory` for more information about the how the + factory is called. + .. function:: debug(msg, *args, **kwargs) Logs a message with level :const:`DEBUG` on the root logger. The *msg* is the @@ -973,6 +986,34 @@ function is typically called before any loggers are instantiated by applications which need to use custom logger behavior. +.. function:: setLogRecordFactory(factory) + + Set a callable which is used to create a :class:`LogRecord`. + + :param factory: The factory callable to be used to instantiate a log record. + + .. versionadded:: 3.2 + + This function has been provided, along with :func:`getLogRecordFactory`, to + allow developers more control over how the :class:`LogRecord` representing + a logging event is constructed. + + The factory has the following signature. + + factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, \*\*kwargs) + + :name: The logger name. + :level: The logging level (numeric). + :fn: The full pathname of the file where the logging call was made. + :lno: The line number in the file where the logging call was made. + :msg: The logging message. + :args: The arguments for the logging message. + :exc_info: An exception tuple, or None. + :func: The name of the function or method which invoked the logging + call. + :sinfo: A stack traceback such as is provided by + :func:`traceback.print_stack`, showing the call hierarchy. + :kwargs: Additional keyword arguments. .. seealso:: @@ -3244,6 +3285,29 @@ messages, whose ``__str__`` method can return the actual format string to be used. + .. versionchanged:: 3.2 + The creation of a ``LogRecord`` has been made more configurable by + providing a factory which is used to create the record. The factory can be + set using :func:`getLogRecordFactory` and :func:`setLogRecordFactory` + (see this for the factory's signature). + + This functionality can be used to inject your own values into a + LogRecord at creation time. You can use the following pattern:: + + old_factory = logging.getLogRecordFactory() + + def record_factory(*args, **kwargs): + record = old_factory(*args, **kwargs) + record.custom_attribute = 0xdecafbad + return record + + logging.setLogRecordFactory(record_factory) + + With this pattern, multiple factories could be chained, and as long + as they don't overwrite each other's attributes or unintentionally + overwrite the standard attributes listed above, there should be no + surprises. + .. _logger-adapter: LoggerAdapter Objects Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Fri Dec 3 12:50:38 2010 @@ -33,7 +33,7 @@ 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning', - 'getLogRecordClass', 'setLogRecordClass'] + 'getLogRecordFactory', 'setLogRecordFactory'] try: import codecs @@ -238,7 +238,7 @@ information to be logged. """ def __init__(self, name, level, pathname, lineno, - msg, args, exc_info, func=None, sinfo=None): + msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ @@ -322,21 +322,24 @@ # # Determine which class to use when instantiating log records. # -_logRecordClass = LogRecord +_logRecordFactory = LogRecord -def setLogRecordClass(cls): +def setLogRecordFactory(factory): """ Set the class to be used when instantiating a log record. + + :param factory: A callable which will be called to instantiate + a log record. """ - global _logRecordClass - _logRecordClass = cls + global _logRecordFactory + _logRecordFactory = factory -def getLogRecordClass(): +def getLogRecordFactory(): """ Return the class to be used when instantiating a log record. """ - return _logRecordClass + return _logRecordFactory def makeLogRecord(dict): """ @@ -345,7 +348,7 @@ a socket connection (which is sent as a dictionary) into a LogRecord instance. """ - rv = _logRecordClass(None, None, "", 0, "", (), None, None) + rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv @@ -1056,7 +1059,7 @@ self.emittedNoHandlerWarning = 0 self.loggerDict = {} self.loggerClass = None - self.logRecordClass = None + self.logRecordFactory = None def getLogger(self, name): """ @@ -1100,12 +1103,12 @@ + klass.__name__) self.loggerClass = klass - def setLogRecordClass(self, cls): + def setLogRecordFactory(self, factory): """ Set the class to be used when instantiating a log record with this Manager. """ - self.logRecordClass = cls + self.logRecordFactory = factory def _fixupParents(self, alogger): """ @@ -1305,7 +1308,7 @@ A factory method which can be overridden in subclasses to create specialized LogRecords. """ - rv = _logRecordClass(name, level, fn, lno, msg, args, exc_info, func, + rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: Modified: python/branches/py3k/Lib/test/test_logging.py ============================================================================== --- python/branches/py3k/Lib/test/test_logging.py (original) +++ python/branches/py3k/Lib/test/test_logging.py Fri Dec 3 12:50:38 2010 @@ -1799,7 +1799,7 @@ class DerivedLogRecord(logging.LogRecord): pass -class LogRecordClassTest(BaseTest): +class LogRecordFactoryTest(BaseTest): def setUp(self): class CheckingFilter(logging.Filter): @@ -1817,17 +1817,17 @@ BaseTest.setUp(self) self.filter = CheckingFilter(DerivedLogRecord) self.root_logger.addFilter(self.filter) - self.orig_cls = logging.getLogRecordClass() + self.orig_factory = logging.getLogRecordFactory() def tearDown(self): self.root_logger.removeFilter(self.filter) BaseTest.tearDown(self) - logging.setLogRecordClass(self.orig_cls) + logging.setLogRecordFactory(self.orig_factory) def test_logrecord_class(self): self.assertRaises(TypeError, self.root_logger.warning, self.next_message()) - logging.setLogRecordClass(DerivedLogRecord) + logging.setLogRecordFactory(DerivedLogRecord) self.root_logger.error(self.next_message()) self.assert_log_lines([ ('root', 'ERROR', '2'), @@ -2015,7 +2015,7 @@ ConfigFileTest, SocketHandlerTest, MemoryTest, EncodingTest, WarningsTest, ConfigDictTest, ManagerTest, FormatterTest, - LogRecordClassTest, ChildLoggerTest, QueueHandlerTest, + LogRecordFactoryTest, ChildLoggerTest, QueueHandlerTest, RotatingFileHandlerTest, #TimedRotatingFileHandlerTest ) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 12:50:38 2010 @@ -33,6 +33,8 @@ Library ------- +- logging: Added getLogRecordFactory/setLogRecordFactory with docs and tests. + - Issue #10549: Fix pydoc traceback when text-documenting certain classes. - Issue #2001: New HTML server with enhanced Web page features. Patch by Ron From python-checkins at python.org Fri Dec 3 13:27:40 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 13:27:40 +0100 (CET) Subject: [Python-checkins] r86968 - in python/branches/py3k: Lib/test/__main__.py Lib/test/regrtest.py Misc/NEWS Message-ID: <20101203122740.D87FCEE985@mail.python.org> Author: michael.foord Date: Fri Dec 3 13:27:40 2010 New Revision: 86968 Log: Factor out common code from lib/test/__main__.py and lib/test/regrtest.py into a function. Modified: python/branches/py3k/Lib/test/__main__.py python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/__main__.py ============================================================================== --- python/branches/py3k/Lib/test/__main__.py (original) +++ python/branches/py3k/Lib/test/__main__.py Fri Dec 3 13:27:40 2010 @@ -1,37 +1,8 @@ -import os -import sys -import sysconfig +from test import regrtest, support -from test import support -from test import regrtest -TEMPDIR = regrtest.TEMPDIR - -# findtestdir() gets the dirname out of __file__, so we have to make it -# absolute before changing the working directory. -# For example __file__ may be relative when running trace or profile. -# See issue #9323. -__file__ = os.path.abspath(__file__) - -# sanity check -assert __file__ == os.path.abspath(sys.argv[0]) - -# When tests are run from the Python build directory, it is best practice -# to keep the test files in a subfolder. It eases the cleanup of leftover -# files using command "make distclean". -if sysconfig.is_python_build(): - TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') - TEMPDIR = os.path.abspath(TEMPDIR) - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) - regrtest.TEMPDIR = TEMPDIR - -# Define a writable temp dir that will be used as cwd while running -# the tests. The name of the dir includes the pid to allow parallel -# testing (see the -j option). -TESTCWD = 'test_python_{}'.format(os.getpid()) - -TESTCWD = os.path.join(TEMPDIR, TESTCWD) +TEMPDIR, TESTCWD = regrtest._make_temp_dir_for_build(regrtest.TEMPDIR) +regrtest.TEMPDIR = TEMPDIR regrtest.TESTCWD = TESTCWD # Run the tests in a context manager that temporary changes the CWD to a Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Fri Dec 3 13:27:40 2010 @@ -1468,6 +1468,23 @@ assert self.isvalid() return self.expected +def _make_temp_dir_for_build(TEMPDIR): + # When tests are run from the Python build directory, it is best practice + # to keep the test files in a subfolder. It eases the cleanup of leftover + # files using command "make distclean". + if sysconfig.is_python_build(): + TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') + TEMPDIR = os.path.abspath(TEMPDIR) + if not os.path.exists(TEMPDIR): + os.mkdir(TEMPDIR) + + # Define a writable temp dir that will be used as cwd while running + # the tests. The name of the dir includes the pid to allow parallel + # testing (see the -j option). + TESTCWD = 'test_python_{}'.format(os.getpid()) + + TESTCWD = os.path.join(TEMPDIR, TESTCWD) + return TEMPDIR, TESTCWD if __name__ == '__main__': # Remove regrtest.py's own directory from the module search path. Despite @@ -1491,21 +1508,7 @@ # sanity check assert __file__ == os.path.abspath(sys.argv[0]) - # When tests are run from the Python build directory, it is best practice - # to keep the test files in a subfolder. It eases the cleanup of leftover - # files using command "make distclean". - if sysconfig.is_python_build(): - TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') - TEMPDIR = os.path.abspath(TEMPDIR) - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) - - # Define a writable temp dir that will be used as cwd while running - # the tests. The name of the dir includes the pid to allow parallel - # testing (see the -j option). - TESTCWD = 'test_python_{}'.format(os.getpid()) - - TESTCWD = os.path.join(TEMPDIR, TESTCWD) + TEMPDIR, TESTCWD = _make_temp_dir_for_build(TEMPDIR) # Run the tests in a context manager that temporary changes the CWD to a # temporary and writable directory. If it's not possible to create or Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 13:27:40 2010 @@ -206,6 +206,9 @@ - regrtest.py once again ensures the test directory is removed from sys.path when it is invoked directly as the __main__ module +- `python -m test` can be used to run the test suite as well as + `python -m test.regrtest`. + - Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, `assertNotEquals`, `assertAlmostEquals`, `assertNotAlmostEquals` and `assert_` and replace them with the correct methods in the Python test suite. From python-checkins at python.org Fri Dec 3 14:01:11 2010 From: python-checkins at python.org (vinay.sajip) Date: Fri, 3 Dec 2010 14:01:11 +0100 (CET) Subject: [Python-checkins] r86969 - python/branches/py3k/Lib/logging/__init__.py Message-ID: <20101203130111.D6EDDEE9AC@mail.python.org> Author: vinay.sajip Date: Fri Dec 3 14:01:11 2010 New Revision: 86969 Log: logging: tidied up some docstrings. Modified: python/branches/py3k/Lib/logging/__init__.py Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Fri Dec 3 14:01:11 2010 @@ -326,7 +326,7 @@ def setLogRecordFactory(factory): """ - Set the class to be used when instantiating a log record. + Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. @@ -336,7 +336,7 @@ def getLogRecordFactory(): """ - Return the class to be used when instantiating a log record. + Return the factory to be used when instantiating a log record. """ return _logRecordFactory @@ -1105,7 +1105,7 @@ def setLogRecordFactory(self, factory): """ - Set the class to be used when instantiating a log record with this + Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory From python-checkins at python.org Fri Dec 3 15:26:13 2010 From: python-checkins at python.org (nick.coghlan) Date: Fri, 3 Dec 2010 15:26:13 +0100 (CET) Subject: [Python-checkins] r86970 - in python/branches/py3k: Doc/library/functions.rst Doc/whatsnew/3.2.rst Lib/test/test_range.py Lib/test/test_sys.py Misc/NEWS Objects/rangeobject.c Message-ID: <20101203142613.E6366EE984@mail.python.org> Author: nick.coghlan Date: Fri Dec 3 15:26:13 2010 New Revision: 86970 Log: Issue 2690: Add support for slicing and negative indices to range objects (includes precalculation and storage of the range length). Refer to the tracker issue for the language moratorium implications of this change Modified: python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/whatsnew/3.2.rst python/branches/py3k/Lib/test/test_range.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/rangeobject.c Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Fri Dec 3 15:26:13 2010 @@ -1023,8 +1023,33 @@ >>> list(range(1, 0)) [] + Range objects implement the :class:`collections.Sequence` ABC, and provide + features such as containment tests, element index lookup, slicing and + support for negative indices: + + >>> r = range(0, 20, 2) + >>> r + range(0, 20, 2) + >>> 11 in r + False + >>> 10 in r + True + >>> r.index(10) + 5 + >>> r[5] + 10 + >>> r[:5] + range(0, 10, 2) + >>> r[-1] + 18 + + Ranges containing absolute values larger than ``sys.maxint`` are permitted + but some features (such as :func:`len`) will raise :exc:`OverflowError`. + .. versionchanged:: 3.2 - Testing integers for membership takes constant time instead of iterating + Implement the Sequence ABC + Support slicing and negative indices + Test integers for membership in constant time instead of iterating through all items. Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Fri Dec 3 15:26:13 2010 @@ -313,6 +313,10 @@ (Added by Antoine Pitrou, :issue:`10093`.) +.. XXX: Issues #9213 and #2690 make the objects returned by range() + more sequence like in accordance with their registration as + implementing the Sequence ABC + New, Improved, and Deprecated Modules ===================================== Modified: python/branches/py3k/Lib/test/test_range.py ============================================================================== --- python/branches/py3k/Lib/test/test_range.py (original) +++ python/branches/py3k/Lib/test/test_range.py Fri Dec 3 15:26:13 2010 @@ -136,7 +136,12 @@ self.assertNotIn(-b, seq) self.assertEqual(len(seq), 2) - self.assertRaises(OverflowError, len, range(0, sys.maxsize**10)) + self.assertRaises(OverflowError, len, + range(-sys.maxsize, sys.maxsize)) + self.assertRaises(OverflowError, len, + range(0, 2*sys.maxsize)) + self.assertRaises(OverflowError, len, + range(0, sys.maxsize**10)) def test_invalid_invocation(self): self.assertRaises(TypeError, range) @@ -248,6 +253,8 @@ always_equal = AlwaysEqual() self.assertEqual(range(10).count(always_equal), 10) + self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10) + def test_repr(self): self.assertEqual(repr(range(1)), 'range(0, 1)') self.assertEqual(repr(range(1, 2)), 'range(1, 2)') @@ -349,6 +356,70 @@ test_id = "reversed(range({}, {}, {}))".format(start, end, step) self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + def test_slice(self): + def check(start, stop, step=None): + i = slice(start, stop, step) + self.assertEqual(list(r[i]), list(r)[i]) + self.assertEqual(len(r[i]), len(list(r)[i])) + for r in [range(10), + range(0), + range(1, 9, 3), + range(8, 0, -3), + range(sys.maxsize+1, sys.maxsize+10), + ]: + check(0, 2) + check(0, 20) + check(1, 2) + check(20, 30) + check(-30, -20) + check(-1, 100, 2) + check(0, -1) + check(-1, -3, -1) + + def test_contains(self): + r = range(10) + self.assertIn(0, r) + self.assertIn(1, r) + self.assertIn(5.0, r) + self.assertNotIn(5.1, r) + self.assertNotIn(-1, r) + self.assertNotIn(10, r) + self.assertNotIn("", r) + r = range(9, -1, -1) + self.assertIn(0, r) + self.assertIn(1, r) + self.assertIn(5.0, r) + self.assertNotIn(5.1, r) + self.assertNotIn(-1, r) + self.assertNotIn(10, r) + self.assertNotIn("", r) + r = range(0, 10, 2) + self.assertIn(0, r) + self.assertNotIn(1, r) + self.assertNotIn(5.0, r) + self.assertNotIn(5.1, r) + self.assertNotIn(-1, r) + self.assertNotIn(10, r) + self.assertNotIn("", r) + r = range(9, -1, -2) + self.assertNotIn(0, r) + self.assertIn(1, r) + self.assertIn(5.0, r) + self.assertNotIn(5.1, r) + self.assertNotIn(-1, r) + self.assertNotIn(10, r) + self.assertNotIn("", r) + + def test_reverse_iteration(self): + for r in [range(10), + range(0), + range(1, 9, 3), + range(8, 0, -3), + range(sys.maxsize+1, sys.maxsize+10), + ]: + self.assertEqual(list(reversed(r)), list(r)[::-1]) + + def test_main(): test.support.run_unittest(RangeTest) Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Fri Dec 3 15:26:13 2010 @@ -782,8 +782,8 @@ # reverse check(reversed(''), size(h + 'PP')) # range - check(range(1), size(h + '3P')) - check(range(66000), size(h + '3P')) + check(range(1), size(h + '4P')) + check(range(66000), size(h + '4P')) # set # frozenset PySet_MINSIZE = 8 Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 15:26:13 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #2690: Range objects support negative indices and slicing + - Issue #9915: Speed up sorting with a key. - Issue #7475: Added transform() and untransform() methods to both bytes and @@ -652,7 +654,7 @@ - Issue #9252: PyImport_Import no longer uses a fromlist hack to return the module that was imported, but instead gets the module from sys.modules. -- Issue #9212: The range type_items now provides index() and count() methods, to +- Issue #9213: The range type_items now provides index() and count() methods, to conform to the Sequence ABC. Patch by Daniel Urban and Daniel Stutzbach. - Issue #7994: Issue a PendingDeprecationWarning if object.__format__ is called Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Fri Dec 3 15:26:13 2010 @@ -14,6 +14,7 @@ PyObject *start; PyObject *stop; PyObject *step; + PyObject *length; } rangeobject; /* Helper function for validating step. Always returns a new reference or @@ -43,6 +44,31 @@ return step; } +static PyObject * +compute_range_length(PyObject *start, PyObject *stop, PyObject *step); + +static rangeobject * +make_range_object(PyTypeObject *type, PyObject *start, + PyObject *stop, PyObject *step) +{ + rangeobject *obj = NULL; + PyObject *length; + length = compute_range_length(start, stop, step); + if (length == NULL) { + return NULL; + } + obj = PyObject_New(rangeobject, type); + if (obj == NULL) { + Py_DECREF(length); + return NULL; + } + obj->start = start; + obj->stop = stop; + obj->step = step; + obj->length = length; + return obj; +} + /* XXX(nnorwitz): should we error check if the user passes any empty ranges? range(-10) range(0, -5) @@ -51,7 +77,7 @@ static PyObject * range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - rangeobject *obj = NULL; + rangeobject *obj; PyObject *start = NULL, *stop = NULL, *step = NULL; if (!_PyArg_NoKeywords("range()", kw)) @@ -97,15 +123,11 @@ } } - obj = PyObject_New(rangeobject, &PyRange_Type); - if (obj == NULL) - goto Fail; - obj->start = start; - obj->stop = stop; - obj->step = step; - return (PyObject *) obj; + obj = make_range_object(type, start, stop, step); + if (obj != NULL) + return (PyObject *) obj; -Fail: + /* Failed to create object, release attributes */ Py_XDECREF(start); Py_XDECREF(stop); Py_XDECREF(step); @@ -115,7 +137,7 @@ PyDoc_STRVAR(range_doc, "range([start,] stop[, step]) -> range object\n\ \n\ -Returns an iterator that generates the numbers in the range on demand."); +Returns a virtual sequence of numbers from start to stop by step."); static void range_dealloc(rangeobject *r) @@ -123,6 +145,7 @@ Py_DECREF(r->start); Py_DECREF(r->stop); Py_DECREF(r->step); + Py_DECREF(r->length); PyObject_Del(r); } @@ -131,7 +154,7 @@ * PyLong_Check(). Return NULL when there is an error. */ static PyObject* -range_length_obj(rangeobject *r) +compute_range_length(PyObject *start, PyObject *stop, PyObject *step) { /* ------------------------------------------------------------- Algorithm is equal to that of get_len_of_range(), but it operates @@ -139,7 +162,6 @@ ---------------------------------------------------------------*/ int cmp_result; PyObject *lo, *hi; - PyObject *step = NULL; PyObject *diff = NULL; PyObject *one = NULL; PyObject *tmp1 = NULL, *tmp2 = NULL, *result; @@ -148,20 +170,19 @@ PyObject *zero = PyLong_FromLong(0); if (zero == NULL) return NULL; - cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT); + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); Py_DECREF(zero); if (cmp_result == -1) return NULL; if (cmp_result == 1) { - lo = r->start; - hi = r->stop; - step = r->step; + lo = start; + hi = stop; Py_INCREF(step); } else { - lo = r->stop; - hi = r->start; - step = PyNumber_Negative(r->step); + lo = stop; + hi = start; + step = PyNumber_Negative(step); if (!step) return NULL; } @@ -206,32 +227,15 @@ static Py_ssize_t range_length(rangeobject *r) { - PyObject *len = range_length_obj(r); - Py_ssize_t result = -1; - if (len) { - result = PyLong_AsSsize_t(len); - Py_DECREF(len); - } - return result; + return PyLong_AsSsize_t(r->length); } /* range(...)[x] is necessary for: seq[:] = range(...) */ - static PyObject * -range_item(rangeobject *r, Py_ssize_t i) +compute_range_item(rangeobject *r, Py_ssize_t i) { - Py_ssize_t len = range_length(r); PyObject *rem, *incr, *result; - /* XXX(nnorwitz): should negative indices be supported? */ - /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */ - if (i < 0 || i >= len) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_IndexError, - "range object index out of range"); - return NULL; - } - /* XXX(nnorwitz): optimize for short ints. */ rem = PyLong_FromSsize_t(i); if (!rem) @@ -246,31 +250,22 @@ } static PyObject * -range_repr(rangeobject *r) +range_item(rangeobject *r, Py_ssize_t i) { - Py_ssize_t istep; - - /* Check for special case values for printing. We don't always - need the step value. We don't care about errors - (it means overflow), so clear the errors. */ - istep = PyNumber_AsSsize_t(r->step, NULL); - if (istep != 1 || (istep == -1 && PyErr_Occurred())) { - PyErr_Clear(); - } + /* XXX(nnorwitz): should we support range[x] where x > PY_SSIZE_T_MAX? */ + Py_ssize_t len = range_length(r); - if (istep == 1) - return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); - else - return PyUnicode_FromFormat("range(%R, %R, %R)", - r->start, r->stop, r->step); -} + if (i < 0) + i += len; -/* Pickling support */ -static PyObject * -range_reduce(rangeobject *r, PyObject *args) -{ - return Py_BuildValue("(O(OOO))", Py_TYPE(r), - r->start, r->stop, r->step); + if (i < 0 || i >= len) { + /* Also handles case where len < 0 due to (e.g) OverflowError */ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_IndexError, + "range object index out of range"); + return NULL; + } + return compute_range_item(r, i); } /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ @@ -388,15 +383,111 @@ static PySequenceMethods range_as_sequence = { (lenfunc)range_length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)range_item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)range_item, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ (objobjproc)range_contains, /* sq_contains */ }; +static PyObject * +range_repr(rangeobject *r) +{ + Py_ssize_t istep; + + /* Check for special case values for printing. We don't always + need the step value. We don't care about errors + (it means overflow), so clear the errors. */ + istep = PyNumber_AsSsize_t(r->step, NULL); + if (istep != 1 || (istep == -1 && PyErr_Occurred())) { + PyErr_Clear(); + } + + if (istep == 1) + return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); + else + return PyUnicode_FromFormat("range(%R, %R, %R)", + r->start, r->stop, r->step); +} + +/* Pickling support */ +static PyObject * +range_reduce(rangeobject *r, PyObject *args) +{ + return Py_BuildValue("(O(OOO))", Py_TYPE(r), + r->start, r->stop, r->step); +} + +static PyObject * +range_subscript(rangeobject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + return range_item(self, i); + } + if (PySlice_Check(item)) { + PySliceObject *slice = (PySliceObject*)item; + Py_ssize_t start, stop, step, len, rlen; + rangeobject *result; + PyObject *substart = NULL, *substep = NULL, *substop = NULL; + + rlen = range_length(self); + if (rlen < 0) { + return NULL; + } + + if (PySlice_GetIndicesEx(slice, rlen, + &start, &stop, &step, &len) < 0) { + return NULL; + } + if (step == 1) { + substep = self->step; + Py_INCREF(substep); + } else { + /* NB: slice step != Py_None here */ + substep = PyNumber_Multiply(self->step, slice->step); + if (substep == NULL) + goto fail; + } + substart = compute_range_item(self, start); + if (substart == NULL) + goto fail; + if (len <= 0) { + substop = substart; + Py_INCREF(substop); + } + else { + substop = compute_range_item(self, stop); + if (substop == NULL) + goto fail; + } + result = make_range_object(Py_TYPE(self), substart, substop, substep); + if (result != NULL) + return (PyObject *) result; + fail: + Py_XDECREF(substart); + Py_XDECREF(substep); + Py_XDECREF(substop); + return NULL; + } + PyErr_Format(PyExc_TypeError, + "range indices must be integers or slices, not %.200s", + item->ob_type->tp_name); + return NULL; +} + + +static PyMappingMethods range_as_mapping = { + (lenfunc)range_length, /* mp_length */ + (binaryfunc)range_subscript, /* mp_subscript */ + (objobjargproc)0, /* mp_ass_subscript */ +}; + static PyObject * range_iter(PyObject *seq); static PyObject * range_reverse(PyObject *seq); @@ -431,7 +522,7 @@ (reprfunc)range_repr, /* tp_repr */ 0, /* tp_as_number */ &range_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ + &range_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ @@ -491,22 +582,6 @@ return PyLong_FromLong(r->len - r->index); } -typedef struct { - PyObject_HEAD - PyObject *index; - PyObject *start; - PyObject *step; - PyObject *len; -} longrangeiterobject; - -static PyObject * -longrangeiter_len(longrangeiterobject *r, PyObject *no_args) -{ - return PyNumber_Subtract(r->len, r->index); -} - -static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); - PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); @@ -516,6 +591,8 @@ {NULL, NULL} /* sentinel */ }; +static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); + PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "range_iterator", /* tp_name */ @@ -590,7 +667,7 @@ is not representable as a C long, OverflowError is raised. */ static PyObject * -int_range_iter(long start, long stop, long step) +fast_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); unsigned long ulen; @@ -622,7 +699,21 @@ &start, &stop, &step)) return NULL; - return int_range_iter(start, stop, step); + return fast_range_iter(start, stop, step); +} + +typedef struct { + PyObject_HEAD + PyObject *index; + PyObject *start; + PyObject *step; + PyObject *len; +} longrangeiterobject; + +static PyObject * +longrangeiter_len(longrangeiterobject *r, PyObject *no_args) +{ + return PyNumber_Subtract(r->len, r->index); } static PyMethodDef longrangeiter_methods[] = { @@ -736,7 +827,7 @@ PyErr_Clear(); goto long_range; } - int_it = int_range_iter(lstart, lstop, lstep); + int_it = fast_range_iter(lstart, lstop, lstep); if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); goto long_range; @@ -751,14 +842,11 @@ /* Do all initialization here, so we can DECREF on failure. */ it->start = r->start; it->step = r->step; + it->len = r->length; Py_INCREF(it->start); Py_INCREF(it->step); + Py_INCREF(it->len); - it->len = it->index = NULL; - - it->len = range_length_obj(r); - if (!it->len) - goto create_failure; it->index = PyLong_FromLong(0); if (!it->index) goto create_failure; @@ -775,7 +863,7 @@ { rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; - PyObject *one, *sum, *diff, *len = NULL, *product; + PyObject *one, *sum, *diff, *product; long lstart, lstop, lstep, new_start, new_stop; unsigned long ulen; @@ -838,7 +926,7 @@ new_stop = lstart - lstep; new_start = (long)(new_stop + ulen * lstep); - return int_range_iter(new_start, new_stop, -lstep); + return fast_range_iter(new_start, new_stop, -lstep); long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); @@ -846,18 +934,14 @@ return NULL; /* start + (len - 1) * step */ - len = range_length_obj(range); - if (!len) - goto create_failure; - - /* Steal reference to len. */ - it->len = len; + it->len = range->length; + Py_INCREF(it->len); one = PyLong_FromLong(1); if (!one) goto create_failure; - diff = PyNumber_Subtract(len, one); + diff = PyNumber_Subtract(it->len, one); Py_DECREF(one); if (!diff) goto create_failure; From python-checkins at python.org Fri Dec 3 15:30:41 2010 From: python-checkins at python.org (nick.coghlan) Date: Fri, 3 Dec 2010 15:30:41 +0100 (CET) Subject: [Python-checkins] r86971 - python/branches/py3k/Lib/pydoc_data/_pydoc.css Message-ID: <20101203143041.635E9EE982@mail.python.org> Author: nick.coghlan Date: Fri Dec 3 15:30:41 2010 New Revision: 86971 Log: Add missing CSS file from r86962 Added: python/branches/py3k/Lib/pydoc_data/_pydoc.css (contents, props changed) Added: python/branches/py3k/Lib/pydoc_data/_pydoc.css ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/pydoc_data/_pydoc.css Fri Dec 3 15:30:41 2010 @@ -0,0 +1,6 @@ +/* + CSS file for pydoc. + + Contents of this file are subject to change without notice. + +*/ From python-checkins at python.org Fri Dec 3 16:26:36 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 3 Dec 2010 16:26:36 +0100 (CET) Subject: [Python-checkins] r86972 - python/branches/release31-maint Message-ID: <20101203152636.CB94BEE98C@mail.python.org> Author: r.david.murray Date: Fri Dec 3 16:26:36 2010 New Revision: 86972 Log: Blocked revisions 86952-86953 via svnmerge ........ r86952 | r.david.murray | 2010-12-02 23:06:39 -0500 (Thu, 02 Dec 2010) | 12 lines #1486713: Add a tolerant mode to HTMLParser. The motivation for adding this option is that the the functionality it provides used to be provided by sgmllib in Python2, and was used by, for example, BeautifulSoup. Without this option, the Python3 version of BeautifulSoup and the many programs that use it are crippled. The original patch was by 'kxroberto'. I modified it heavily but kept his heuristics and test. I also added additional heuristics to fix #975556, #1046092, and part of #6191. This patch should be completely backward compatible: the behavior with the default strict=True is unchanged. ........ r86953 | r.david.murray | 2010-12-02 23:26:18 -0500 (Thu, 02 Dec 2010) | 2 lines Add missing versionchanged, correct 'throw' wording to 'raise'. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Dec 3 16:26:50 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 3 Dec 2010 16:26:50 +0100 (CET) Subject: [Python-checkins] r86973 - python/branches/release27-maint Message-ID: <20101203152650.16AE2EE9CF@mail.python.org> Author: r.david.murray Date: Fri Dec 3 16:26:49 2010 New Revision: 86973 Log: Blocked revisions 86952-86953 via svnmerge ........ r86952 | r.david.murray | 2010-12-02 23:06:39 -0500 (Thu, 02 Dec 2010) | 12 lines #1486713: Add a tolerant mode to HTMLParser. The motivation for adding this option is that the the functionality it provides used to be provided by sgmllib in Python2, and was used by, for example, BeautifulSoup. Without this option, the Python3 version of BeautifulSoup and the many programs that use it are crippled. The original patch was by 'kxroberto'. I modified it heavily but kept his heuristics and test. I also added additional heuristics to fix #975556, #1046092, and part of #6191. This patch should be completely backward compatible: the behavior with the default strict=True is unchanged. ........ r86953 | r.david.murray | 2010-12-02 23:26:18 -0500 (Thu, 02 Dec 2010) | 2 lines Add missing versionchanged, correct 'throw' wording to 'raise'. ........ Modified: python/branches/release27-maint/ (props changed) From python-checkins at python.org Fri Dec 3 16:30:09 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 16:30:09 +0100 (CET) Subject: [Python-checkins] r86974 - python/branches/py3k/Doc/library/logging.rst Message-ID: <20101203153009.C032FEE986@mail.python.org> Author: georg.brandl Date: Fri Dec 3 16:30:09 2010 New Revision: 86974 Log: Markup consistency fixes. Modified: python/branches/py3k/Doc/library/logging.rst Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Fri Dec 3 16:30:09 2010 @@ -548,10 +548,7 @@ unit tests and deliver logs which suit their requirements. .. versionadded:: 3.1 - -The :class:`NullHandler` class was not present in previous versions, but is -now included, so that it need not be defined in library code. - + The :class:`NullHandler` class. Logging Levels @@ -688,12 +685,10 @@ more information. .. versionadded:: 3.1 - -The :class:`NullHandler` class was not present in previous versions. + The :class:`NullHandler` class. .. versionadded:: 3.2 - -The :class:`QueueHandler` class was not present in previous versions. + The :class:`QueueHandler` class. The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler` classes are defined in the core logging package. The other handlers are @@ -755,7 +750,6 @@ Return a callable which is used to create a :class:`LogRecord`. .. versionadded:: 3.2 - This function has been provided, along with :func:`setLogRecordFactory`, to allow developers more control over how the :class:`LogRecord` representing a logging event is constructed. @@ -986,6 +980,7 @@ function is typically called before any loggers are instantiated by applications which need to use custom logger behavior. + .. function:: setLogRecordFactory(factory) Set a callable which is used to create a :class:`LogRecord`. @@ -993,14 +988,13 @@ :param factory: The factory callable to be used to instantiate a log record. .. versionadded:: 3.2 + This function has been provided, along with :func:`getLogRecordFactory`, to + allow developers more control over how the :class:`LogRecord` representing + a logging event is constructed. - This function has been provided, along with :func:`getLogRecordFactory`, to - allow developers more control over how the :class:`LogRecord` representing - a logging event is constructed. + The factory has the following signature: - The factory has the following signature. - - factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, \*\*kwargs) + ``factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, \*\*kwargs)`` :name: The logger name. :level: The logging level (numeric). @@ -1015,6 +1009,7 @@ :func:`traceback.print_stack`, showing the call hierarchy. :kwargs: Additional keyword arguments. + .. seealso:: :pep:`282` - A Logging System @@ -1253,9 +1248,8 @@ False is found - that will be the last logger which is checked for the existence of handlers. -.. versionadded:: 3.2 + .. versionadded:: 3.2 -The :meth:`hasHandlers` method was not present in previous versions. .. _minimal-example: @@ -2239,6 +2233,7 @@ Outputs the record to the file. + .. _null-handler: NullHandler @@ -2250,12 +2245,10 @@ does not do any formatting or output. It is essentially a "no-op" handler for use by library developers. - .. class:: NullHandler() Returns a new instance of the :class:`NullHandler` class. - .. method:: emit(record) This method does nothing. @@ -2849,6 +2842,8 @@ QueueHandler ^^^^^^^^^^^^ +.. versionadded:: 3.2 + The :class:`QueueHandler` class, located in the :mod:`logging.handlers` module, supports sending logging messages to a queue, such as those implemented in the :mod:`queue` or :mod:`multiprocessing` modules. @@ -2892,15 +2887,14 @@ timeout, or a customised queue implementation. -.. versionadded:: 3.2 - -The :class:`QueueHandler` class was not present in previous versions. .. queue-listener: QueueListener ^^^^^^^^^^^^^ +.. versionadded:: 3.2 + The :class:`QueueListener` class, located in the :mod:`logging.handlers` module, supports receiving logging messages from a queue, such as those implemented in the :mod:`queue` or :mod:`multiprocessing` modules. The @@ -2961,9 +2955,6 @@ Note that if you don't call this before your application exits, there may be some records still left on the queue, which won't be processed. -.. versionadded:: 3.2 - -The :class:`QueueListener` class was not present in previous versions. .. _zeromq-handlers: @@ -3006,6 +2997,7 @@ def close(self): self.queue.close() + Subclassing QueueListener ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3023,6 +3015,7 @@ msg = self.queue.recv() return logging.makeLogRecord(json.loads(msg)) + .. _formatter-objects: Formatter Objects @@ -3291,22 +3284,23 @@ set using :func:`getLogRecordFactory` and :func:`setLogRecordFactory` (see this for the factory's signature). - This functionality can be used to inject your own values into a - LogRecord at creation time. You can use the following pattern:: + This functionality can be used to inject your own values into a + LogRecord at creation time. You can use the following pattern:: + + old_factory = logging.getLogRecordFactory() - old_factory = logging.getLogRecordFactory() + def record_factory(*args, **kwargs): + record = old_factory(*args, **kwargs) + record.custom_attribute = 0xdecafbad + return record + + logging.setLogRecordFactory(record_factory) + + With this pattern, multiple factories could be chained, and as long + as they don't overwrite each other's attributes or unintentionally + overwrite the standard attributes listed above, there should be no + surprises. - def record_factory(*args, **kwargs): - record = old_factory(*args, **kwargs) - record.custom_attribute = 0xdecafbad - return record - - logging.setLogRecordFactory(record_factory) - - With this pattern, multiple factories could be chained, and as long - as they don't overwrite each other's attributes or unintentionally - overwrite the standard attributes listed above, there should be no - surprises. .. _logger-adapter: @@ -3315,22 +3309,21 @@ :class:`LoggerAdapter` instances are used to conveniently pass contextual information into logging calls. For a usage example , see the section on -`adding contextual information to your logging output`__. +:ref:`adding contextual information to your logging output `. -__ context-info_ .. class:: LoggerAdapter(logger, extra) - Returns an instance of :class:`LoggerAdapter` initialized with an - underlying :class:`Logger` instance and a dict-like object. + Returns an instance of :class:`LoggerAdapter` initialized with an + underlying :class:`Logger` instance and a dict-like object. - .. method:: process(msg, kwargs) + .. method:: process(msg, kwargs) - Modifies the message and/or keyword arguments passed to a logging call in - order to insert contextual information. This implementation takes the object - passed as *extra* to the constructor and adds it to *kwargs* using key - 'extra'. The return value is a (*msg*, *kwargs*) tuple which has the - (possibly modified) versions of the arguments passed in. + Modifies the message and/or keyword arguments passed to a logging call in + order to insert contextual information. This implementation takes the object + passed as *extra* to the constructor and adds it to *kwargs* using key + 'extra'. The return value is a (*msg*, *kwargs*) tuple which has the + (possibly modified) versions of the arguments passed in. In addition to the above, :class:`LoggerAdapter` supports the following methods of :class:`Logger`, i.e. :meth:`debug`, :meth:`info`, :meth:`warning`, From python-checkins at python.org Fri Dec 3 17:08:46 2010 From: python-checkins at python.org (nick.coghlan) Date: Fri, 3 Dec 2010 17:08:46 +0100 (CET) Subject: [Python-checkins] r86975 - in python/branches/py3k/Lib: pydoc.py test/test_pydoc.py Message-ID: <20101203160846.84A98EE98D@mail.python.org> Author: nick.coghlan Date: Fri Dec 3 17:08:46 2010 New Revision: 86975 Log: Handle Windows paths and don't double up on HTML header sections in new pydoc URL handler Modified: python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/test/test_pydoc.py Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Dec 3 17:08:46 2010 @@ -2540,7 +2540,7 @@ '

pydoc by Ka-Ping Yee' '<ping at lfw.org>') - return html.page('Index of Modules', ''.join(contents)) + return 'Index of Modules', ''.join(contents) def html_search(key): """Search results page.""" @@ -2568,11 +2568,11 @@ results.append(bltinlink(name) + desc) contents = heading + html.bigsection( 'key = %s' % key, '#ffffff', '#ee77aa', '
'.join(results)) - return html.page('Search Results', contents) + return 'Search Results', contents def html_getfile(path): """Get and display a source file listing safely.""" - path = os.sep + path.replace('%20', ' ') + path = path.replace('%20', ' ') with open(path, 'r') as fp: lines = html.escape(fp.read()) body = '

%s
' % lines @@ -2581,7 +2581,7 @@ '#ffffff', '#7799ee') contents = heading + html.bigsection( 'File: %s' % path, '#ffffff', '#ee77aa', body) - return html.page('getfile %s' % path, contents) + return 'getfile %s' % path, contents def html_topics(): """Index of topic texts available.""" @@ -2597,7 +2597,7 @@ contents = html.multicolumn(names, bltinlink) contents = heading + html.bigsection( 'Topics', '#ffffff', '#ee77aa', contents) - return html.page('Topics', contents) + return 'Topics', contents def html_keywords(): """Index of keywords.""" @@ -2612,7 +2612,7 @@ contents = html.multicolumn(names, bltinlink) contents = heading + html.bigsection( 'Keywords', '#ffffff', '#ee77aa', contents) - return html.page('Keywords', contents) + return 'Keywords', contents def html_topicpage(topic): """Topic or keyword help page.""" @@ -2636,8 +2636,8 @@ xrefs = html.multicolumn(xrefs, bltinlink) xrefs = html.section('Related help topics: ', '#ffffff', '#ee77aa', xrefs) - return html.page('%s %s' % (title, topic), - ''.join((heading, contents, xrefs))) + return ('%s %s' % (title, topic), + ''.join((heading, contents, xrefs))) def html_error(url): heading = html.heading( @@ -2656,17 +2656,17 @@ title = url contents = '' if url in ("", ".", "index"): - contents = html_index() + title, contents = html_index() elif url == "topics": - contents = html_topics() + title, contents = html_topics() elif url == "keywords": - contents = html_keywords() + title, contents = html_keywords() elif url.startswith("search?key="): - contents = html_search(url[11:]) + title, contents = html_search(url[11:]) elif url.startswith("getfile?key="): url = url[12:] try: - contents = html_getfile(url) + title, contents = html_getfile(url) except IOError: contents = html_error('could not read file %r' % url) title = 'Read Error' @@ -2680,7 +2680,7 @@ title = describe(obj) contents = html.document(obj, url) elif url in Helper.keywords or url in Helper.topics: - contents = html_topicpage(url) + title, contents = html_topicpage(url) else: contents = html_error( 'no Python documentation found for %r' % url) Modified: python/branches/py3k/Lib/test/test_pydoc.py ============================================================================== --- python/branches/py3k/Lib/test/test_pydoc.py (original) +++ python/branches/py3k/Lib/test/test_pydoc.py Fri Dec 3 17:08:46 2010 @@ -237,8 +237,10 @@ print('\n' + ''.join(diffs)) def get_html_title(text): - _, _, text = text.rpartition("") - title, _, _ = text.rpartition("") + # Bit of hack, but good enough for test purposes + header, _, _ = text.partition("") + _, _, title = header.partition("") + title, _, _ = title.partition("") return title @@ -449,7 +451,7 @@ self.assertEqual(result, title) path = string.__file__ - title = "Python: getfile /" + path + title = "Python: getfile " + path url = "getfile?key=" + path text = pydoc._url_handler(url, "text/html") result = get_html_title(text) From python-checkins at python.org Fri Dec 3 17:28:00 2010 From: python-checkins at python.org (lukasz.langa) Date: Fri, 3 Dec 2010 17:28:00 +0100 (CET) Subject: [Python-checkins] r86976 - in python/branches/py3k: Doc/library/configparser.rst Doc/library/fileformats.rst Lib/configparser.py Lib/test/test_cfgparser.py Misc/NEWS Message-ID: <20101203162800.9A740EE9B9@mail.python.org> Author: lukasz.langa Date: Fri Dec 3 17:28:00 2010 New Revision: 86976 Log: Issue 10499: Modular interpolation in configparser Modified: python/branches/py3k/Doc/library/configparser.rst python/branches/py3k/Doc/library/fileformats.rst python/branches/py3k/Lib/configparser.py python/branches/py3k/Lib/test/test_cfgparser.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k/Doc/library/configparser.rst (original) +++ python/branches/py3k/Doc/library/configparser.rst Fri Dec 3 17:28:00 2010 @@ -17,11 +17,10 @@ single: ini file single: Windows ini file -This module provides the classes :class:`RawConfigParser` and -:class:`SafeConfigParser`. They implement a basic configuration -language which provides a structure similar to what's found in Microsoft -Windows INI files. You can use this to write Python programs which can be -customized by end users easily. +This module provides the :class:`SafeConfigParser` class which implements +a basic configuration language which provides a structure similar to what's +found in Microsoft Windows INI files. You can use this to write Python +programs which can be customized by end users easily. .. note:: @@ -34,6 +33,10 @@ Support for a creating Unix shell-like mini-languages which can be used as an alternate format for application configuration files. + Module :mod:`json` + The json module implements a subset of JavaScript syntax which can also + be used for this purpose. + Quick Start ----------- @@ -43,17 +46,17 @@ .. code-block:: ini [DEFAULT] - ServerAliveInterval = 45 - Compression = yes - CompressionLevel = 9 - ForwardX11 = yes + ServerAliveInterval = 45 + Compression = yes + CompressionLevel = 9 + ForwardX11 = yes [bitbucket.org] - User = hg + User = hg [topsecret.server.com] - Port = 50022 - ForwardX11 = no + Port = 50022 + ForwardX11 = no The structure of INI files is described `in the following section <#supported-ini-file-structure>`_. Essentially, the file @@ -64,7 +67,7 @@ .. doctest:: >>> import configparser - >>> config = configparser.RawConfigParser() + >>> config = configparser.SafeConfigParser() >>> config['DEFAULT'] = {'ServerAliveInterval': '45', ... 'Compression': 'yes', ... 'CompressionLevel': '9'} @@ -89,7 +92,7 @@ .. doctest:: >>> import configparser - >>> config = configparser.RawConfigParser() + >>> config = configparser.SafeConfigParser() >>> config.sections() [] >>> config.read('example.ini') @@ -233,23 +236,26 @@ compatibility, by default only ``;`` starts an inline comment, while ``#`` does not [1]_. -On top of the core functionality, :class:`SafeConfigParser` supports -interpolation. This means values can contain format strings which refer to -other values in the same section, or values in a special ``DEFAULT`` section -[1]_. Additional defaults can be provided on initialization. - For example: .. code-block:: ini - [Paths] - home_dir: /Users - my_dir: %(home_dir)s/lumberjack - my_pictures: %(my_dir)s/Pictures + [Simple Values] + key: value + spaces in keys: allowed + spaces in values: allowed as well + you can also use = to delimit keys from values + + [All Values Are Strings] + values like this: 1000000 + or this: 3.14159265359 + are they treated as numbers? : no + integers, floats and booleans are held as: strings + can use the API to get converted values directly: true [Multiline Values] chorus: I'm a lumberjack, and I'm okay - I sleep all night and I work all day + I sleep all night and I work all day [No Values] key_without_value @@ -262,28 +268,92 @@ multiline ;comment value! ;comment - [Sections Can Be Indented] - can_values_be_as_well = True - does_that_mean_anything_special = False - purpose = formatting for readability - multiline_values = are - handled just fine as - long as they are indented - deeper than the first line - of a value - # Did I mention we can indent comments, too? - -In the example above, :class:`SafeConfigParser` would resolve ``%(home_dir)s`` -to the value of ``home_dir`` (``/Users`` in this case). ``%(my_dir)s`` in -effect would resolve to ``/Users/lumberjack``. All interpolations are done on -demand so keys used in the chain of references do not have to be specified in -any specific order in the configuration file. - -:class:`RawConfigParser` would simply return ``%(my_dir)s/Pictures`` as the -value of ``my_pictures`` and ``%(home_dir)s/lumberjack`` as the value of -``my_dir``. Other features presented in the example are handled in the same -manner by both parsers. + [Sections Can Be Indented] + can_values_be_as_well = True + does_that_mean_anything_special = False + purpose = formatting for readability + multiline_values = are + handled just fine as + long as they are indented + deeper than the first line + of a value + # Did I mention we can indent comments, too? + + +Interpolation of values +----------------------- + +On top of the core functionality, :class:`SafeConfigParser` supports +interpolation. This means values can be preprocessed before returning them +from ``get()`` calls. + +.. class:: BasicInterpolation() + + The default implementation used by :class:`SafeConfigParser`. It enables + values to contain format strings which refer to other values in the same + section, or values in the special default section [1]_. Additional default + values can be provided on initialization. + + For example: + + .. code-block:: ini + + [Paths] + home_dir: /Users + my_dir: %(home_dir)s/lumberjack + my_pictures: %(my_dir)s/Pictures + + + In the example above, :class:`SafeConfigParser` with *interpolation* set to + ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of + ``home_dir`` (``/Users`` in this case). ``%(my_dir)s`` in effect would + resolve to ``/Users/lumberjack``. All interpolations are done on demand so + keys used in the chain of references do not have to be specified in any + specific order in the configuration file. + + With ``interpolation`` set to ``None``, the parser would simply return + ``%(my_dir)s/Pictures`` as the value of ``my_pictures`` and + ``%(home_dir)s/lumberjack`` as the value of ``my_dir``. + +.. class:: ExtendedInterpolation() + + An alternative handler for interpolation which implements a more advanced + syntax, used for instance in ``zc.buildout``. Extended interpolation is + using ``${section:option}`` to denote a value from a foreign section. + Interpolation can span multiple levels. For convenience, if the ``section:`` + part is omitted, interpolation defaults to the current section (and possibly + the default values from the special section). + + For example, the configuration specified above with basic interpolation, + would look like this with extended interpolation: + + .. code-block:: ini + + [Paths] + home_dir: /Users + my_dir: ${home_dir}/lumberjack + my_pictures: ${my_dir}/Pictures + + Values from other sections can be fetched as well: + .. code-block:: ini + + [Common] + home_dir: /Users + library_dir: /Library + system_dir: /System + macports_dir: /opt/local + + [Frameworks] + Python: 3.2 + path: ${Common:system_dir}/Library/Frameworks/ + + [Arthur] + nickname: Two Sheds + last_name: Jackson + my_dir: ${Common:home_dir}/twosheds + my_pictures: ${my_dir}/Pictures + python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python} Mapping Protocol Access ----------------------- @@ -350,9 +420,9 @@ * *defaults*, default value: ``None`` This option accepts a dictionary of key-value pairs which will be initially - put in the ``DEFAULTSECT``. This makes for an elegant way to support concise - configuration files that don't specify values which are the same as the - documented default. + put in the ``DEFAULT`` section. This makes for an elegant way to support + concise configuration files that don't specify values which are the same as + the documented default. Hint: if you want to specify default values for a specific section, use :meth:`read_dict` before you read the actual file. @@ -374,7 +444,7 @@ .. doctest:: - >>> parser = configparser.RawConfigParser() + >>> parser = configparser.SafeConfigParser() >>> parser.read_dict({'section1': {'key1': 'value1', ... 'key2': 'value2', ... 'key3': 'value3'}, @@ -395,7 +465,7 @@ .. doctest:: >>> from collections import OrderedDict - >>> parser = configparser.RawConfigParser() + >>> parser = configparser.SafeConfigParser() >>> parser.read_dict( ... OrderedDict(( ... ('s1', @@ -441,7 +511,7 @@ ... skip-bdb ... skip-innodb # we don't need ACID today ... """ - >>> config = configparser.RawConfigParser(allow_no_value=True) + >>> config = configparser.SafeConfigParser(allow_no_value=True) >>> config.read_string(sample_config) >>> # Settings with values are treated as before: @@ -464,7 +534,7 @@ This means values (but not keys) can contain the delimiters. See also the *space_around_delimiters* argument to - :meth:`RawConfigParser.write`. + :meth:`SafeConfigParser.write`. * *comment_prefixes*, default value: ``_COMPATIBLE`` (``'#'`` valid on empty lines, ``';'`` valid also on non-empty lines) @@ -512,6 +582,31 @@ will make empty lines split keys every time. In the example above, it would produce two keys, ``key`` and ``this``. +* *default_section*, default value: ``configparser.DEFAULTSECT`` (that is: + ``"DEFAULT"``) + + The convention of allowing a special section of default values for other + sections or interpolation purposes is a powerful concept of this library, + letting users create complex declarative configurations. This section is + normally called ``"DEFAULT"`` but this can be customized to point to any + other valid section name. Some typical values include: ``"general"`` or + ``"common"``. The name provided is used for recognizing default sections when + reading from any source and is used when writing configuration back to + a file. Its current value can be retrieved using the + ``parser_instance.default_section`` attribute and may be modified at runtime + (i.e. to convert files from one format to another). + +* *interpolation*, default value: ``configparser.BasicInterpolation`` + + Interpolation behaviour may be customized by providing a custom handler + through the *interpolation* argument. ``None`` can be used to turn off + interpolation completely, ``ExtendedInterpolation()`` provides a more + advanced variant inspired by ``zc.buildout``. More on the subject in the + `dedicated documentation section <#interpolation-of-values>`_. + + .. note:: :class:`RawConfigParser` is using ``None`` by default and + :class:`ConfigParser` is using ``configparser.BrokenInterpolation``. + More advanced customization may be achieved by overriding default values of these parser attributes. The defaults are defined on the classes, so they @@ -527,7 +622,7 @@ .. doctest:: - >>> custom = configparser.RawConfigParser() + >>> custom = configparser.SafeConfigParser() >>> custom['section1'] = {'funky': 'nope'} >>> custom['section1'].getboolean('funky') Traceback (most recent call last): @@ -557,7 +652,7 @@ ... [Section2] ... AnotherKey = Value ... """ - >>> typical = configparser.RawConfigParser() + >>> typical = configparser.SafeConfigParser() >>> typical.read_string(config) >>> list(typical['Section1'].keys()) ['key'] @@ -623,8 +718,7 @@ if config.getboolean('Section1', 'bool'): print(config.get('Section1', 'foo')) -To get interpolation, use :class:`SafeConfigParser` or, if -you absolutely have to, a :class:`ConfigParser`:: +To get interpolation, use :class:`SafeConfigParser`:: import configparser @@ -672,14 +766,14 @@ print(config.get('Section1', 'foo')) # -> "Life is hard!" -.. _rawconfigparser-objects: +.. _safeconfigparser-objects: -RawConfigParser Objects ------------------------ +SafeConfigParser Objects +------------------------ -.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True) +.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation()) - The basic configuration parser. When *defaults* is given, it is initialized + The main configuration parser. When *defaults* is given, it is initialized into the dictionary of intrinsic defaults. When *dict_type* is given, it will be used to create the dictionary objects for the list of sections, for the options within a section, and for the default values. @@ -698,16 +792,33 @@ (default: ``True``), each empty line marks the end of an option. Otherwise, internal empty lines of a multiline option are kept as part of the value. When *allow_no_value* is ``True`` (default: ``False``), options without - values are accepted; the value presented for these is ``None``. + values are accepted; the value held for these is ``None`` and they are + serialized without the trailing delimiter. + + When *default_section* is given, it specifies the name for the special + section holding default values for other sections and interpolation purposes + (normally named ``"DEFAULT"``). This value can be retrieved and changed on + runtime using the ``default_section`` instance attribute. + + Interpolation behaviour may be customized by providing a custom handler + through the *interpolation* argument. ``None`` can be used to turn off + interpolation completely, ``ExtendedInterpolation()`` provides a more + advanced variant inspired by ``zc.buildout``. More on the subject in the + `dedicated documentation section <#interpolation-of-values>`_. - This class does not support the magical interpolation behavior. + All option names used in interpolation will be passed through the + :meth:`optionxform` method just like any other option name reference. For + example, using the default implementation of :meth:`optionxform` (which + converts option names to lower case), the values ``foo %(bar)s`` and ``foo + %(BAR)s`` are equivalent. .. versionchanged:: 3.1 The default *dict_type* is :class:`collections.OrderedDict`. .. versionchanged:: 3.2 - *allow_no_value*, *delimiters*, *comment_prefixes*, *strict* and - *empty_lines_in_values* were added. + *allow_no_value*, *delimiters*, *comment_prefixes*, *strict*, + *empty_lines_in_values*, *default_section* and *interpolation* were + added. .. method:: defaults() @@ -717,22 +828,21 @@ .. method:: sections() - Return a list of the sections available; ``DEFAULT`` is not included in - the list. + Return a list of the sections available; the *default section* is not + included in the list. .. method:: add_section(section) Add a section named *section* to the instance. If a section by the given - name already exists, :exc:`DuplicateSectionError` is raised. If the name - ``DEFAULT`` (or any of it's case-insensitive variants) is passed, - :exc:`ValueError` is raised. + name already exists, :exc:`DuplicateSectionError` is raised. If the + *default section* name is passed, :exc:`ValueError` is raised. .. method:: has_section(section) - Indicates whether the named section is present in the configuration. The - ``DEFAULT`` section is not acknowledged. + Indicates whether the named *section* is present in the configuration. + The *default section* is not acknowledged. .. method:: options(section) @@ -742,7 +852,7 @@ .. method:: has_option(section, option) - If the given section exists, and contains the given option, return + If the given *section* exists, and contains the given *option*, return :const:`True`; otherwise return :const:`False`. @@ -750,19 +860,20 @@ Attempt to read and parse a list of filenames, returning a list of filenames which were successfully parsed. If *filenames* is a string, it - is treated as a single filename. If a file named in *filenames* cannot be - opened, that file will be ignored. This is designed so that you can - specify a list of potential configuration file locations (for example, the - current directory, the user's home directory, and some system-wide - directory), and all existing configuration files in the list will be read. - If none of the named files exist, the :class:`ConfigParser` instance will - contain an empty dataset. An application which requires initial values to - be loaded from a file should load the required file or files using - :meth:`read_file` before calling :meth:`read` for any optional files:: + is treated as a single filename. If a file named in *filenames* cannot + be opened, that file will be ignored. This is designed so that you can + specify a list of potential configuration file locations (for example, + the current directory, the user's home directory, and some system-wide + directory), and all existing configuration files in the list will be + read. If none of the named files exist, the :class:`ConfigParser` + instance will contain an empty dataset. An application which requires + initial values to be loaded from a file should load the required file or + files using :meth:`read_file` before calling :meth:`read` for any + optional files:: import configparser, os - config = configparser.ConfigParser() + config = configparser.SafeConfigParser() config.read_file(open('defaults.cfg')) config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')], encoding='cp1250') @@ -810,7 +921,8 @@ .. versionadded:: 3.2 - .. method:: get(section, option, [vars, fallback]) + + .. method:: get(section, option, raw=False, [vars, fallback]) Get an *option* value for the named *section*. If *vars* is provided, it must be a dictionary. The *option* is looked up in *vars* (if provided), @@ -818,58 +930,54 @@ and *fallback* is provided, it is used as a fallback value. ``None`` can be provided as a *fallback* value. + All the ``'%'`` interpolations are expanded in the return values, unless + the *raw* argument is true. Values for interpolation keys are looked up + in the same manner as the option. + .. versionchanged:: 3.2 - Arguments *vars* and *fallback* are keyword only to protect users from - trying to use the third argument as the *fallback* fallback (especially - when using the mapping protocol). + Arguments *raw*, *vars* and *fallback* are keyword only to protect + users from trying to use the third argument as the *fallback* fallback + (especially when using the mapping protocol). - .. method:: getint(section, option, [vars, fallback]) + .. method:: getint(section, option, raw=False, [vars, fallback]) A convenience method which coerces the *option* in the specified *section* - to an integer. See :meth:`get` for explanation of *vars* and *fallback*. + to an integer. See :meth:`get` for explanation of *raw*, *vars* and + *fallback*. - .. method:: getfloat(section, option, [vars, fallback]) + .. method:: getfloat(section, option, raw=False, [vars, fallback]) A convenience method which coerces the *option* in the specified *section* - to a floating point number. See :meth:`get` for explanation of *vars* and - *fallback*. + to a floating point number. See :meth:`get` for explanation of *raw*, + *vars* and *fallback*. - .. method:: getboolean(section, option, [vars, fallback]) + .. method:: getboolean(section, option, raw=False, [vars, fallback]) A convenience method which coerces the *option* in the specified *section* to a Boolean value. Note that the accepted values for the option are - ``"1"``, ``"yes"``, ``"true"``, and ``"on"``, which cause this method to - return ``True``, and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which + ``'1'``, ``'yes'``, ``'true'``, and ``'on'``, which cause this method to + return ``True``, and ``'0'``, ``'no'``, ``'false'``, and ``'off'``, which cause it to return ``False``. These string values are checked in a case-insensitive manner. Any other value will cause it to raise - :exc:`ValueError`. See :meth:`get` for explanation of *vars* and + :exc:`ValueError`. See :meth:`get` for explanation of *raw*, *vars* and *fallback*. - .. method:: items(section) + .. method:: items(section, raw=False, vars=None) - Return a list of *name*, *value* pairs for each option in the given - *section*. + Return a list of *name*, *value* pairs for the options in the given + *section*. Optional arguments have the same meaning as for the + :meth:`get` method. .. method:: set(section, option, value) If the given section exists, set the given option to the specified value; - otherwise raise :exc:`NoSectionError`. While it is possible to use - :class:`RawConfigParser` (or :class:`ConfigParser` with *raw* parameters - set to true) for *internal* storage of non-string values, full - functionality (including interpolation and output to files) can only be - achieved using string values. - - .. note:: - - This method lets users assign non-string values to keys internally. - This behaviour is unsupported and will cause errors when attempting to - write to a file or get it in non-raw mode. **Use the mapping protocol - API** which does not allow such assignments to take place. + otherwise raise :exc:`NoSectionError`. *value* must be a string; if not, + :exc:`TypeError` is raised. .. method:: write(fileobject, space_around_delimiters=True) @@ -921,134 +1029,61 @@ Use :meth:`read_file` instead. -.. _configparser-objects: - -ConfigParser Objects --------------------- - -.. warning:: - Whenever you can, consider using :class:`SafeConfigParser` which adds - validation and escaping for the interpolation. - -The :class:`ConfigParser` class extends some methods of the -:class:`RawConfigParser` interface, adding some optional arguments. - -.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True) - - Derived class of :class:`RawConfigParser` that implements the magical - interpolation feature and adds optional arguments to the :meth:`get` and - :meth:`items` methods. - - :class:`SafeConfigParser` is generally recommended over this class if you - need interpolation. - - The values in *defaults* must be appropriate for the ``%()s`` string - interpolation. - - All option names used in interpolation will be passed through the - :meth:`optionxform` method just like any other option name reference. For - example, using the default implementation of :meth:`optionxform` (which - converts option names to lower case), the values ``foo %(bar)s`` and ``foo - %(BAR)s`` are equivalent. - - .. versionchanged:: 3.1 - The default *dict_type* is :class:`collections.OrderedDict`. - - .. versionchanged:: 3.2 - *allow_no_value*, *delimiters*, *comment_prefixes*, - *strict* and *empty_lines_in_values* were added. - - - .. method:: get(section, option, raw=False, [vars, fallback]) - - Get an *option* value for the named *section*. If *vars* is provided, it - must be a dictionary. The *option* is looked up in *vars* (if provided), - *section*, and in *DEFAULTSECT* in that order. If the key is not found - and *fallback* is provided, it is used as a fallback value. ``None`` can - be provided as a *fallback* value. - - All the ``'%'`` interpolations are expanded in the return values, unless - the *raw* argument is true. Values for interpolation keys are looked up - in the same manner as the option. - - .. versionchanged:: 3.2 - Arguments *raw*, *vars* and *fallback* are keyword only to protect - users from trying to use the third argument as the *fallback* fallback - (especially when using the mapping protocol). - - - .. method:: getint(section, option, raw=False, [vars, fallback]) - - A convenience method which coerces the *option* in the specified *section* - to an integer. See :meth:`get` for explanation of *raw*, *vars* and - *fallback*. - - - .. method:: getfloat(section, option, raw=False, [vars, fallback]) - - A convenience method which coerces the *option* in the specified *section* - to a floating point number. See :meth:`get` for explanation of *raw*, - *vars* and *fallback*. - - - .. method:: getboolean(section, option, raw=False, [vars, fallback]) +.. data:: MAX_INTERPOLATION_DEPTH - A convenience method which coerces the *option* in the specified *section* - to a Boolean value. Note that the accepted values for the option are - ``'1'``, ``'yes'``, ``'true'``, and ``'on'``, which cause this method to - return ``True``, and ``'0'``, ``'no'``, ``'false'``, and ``'off'``, which - cause it to return ``False``. These string values are checked in a - case-insensitive manner. Any other value will cause it to raise - :exc:`ValueError`. See :meth:`get` for explanation of *raw*, *vars* and - *fallback*. + The maximum depth for recursive interpolation for :meth:`get` when the *raw* + parameter is false. This is relevant only when the default *interpolation* + is used. - .. method:: items(section, raw=False, vars=None) +.. _rawconfigparser-objects: - Return a list of *name*, *value* pairs for the options in the given - *section*. Optional arguments have the same meaning as for the - :meth:`get` method. +RawConfigParser Objects +----------------------- +.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True, default_section=configaparser.DEFAULTSECT, interpolation=None) -.. data:: MAX_INTERPOLATION_DEPTH + Legacy variant of the :class:`SafeConfigParser` with interpolation disabled + by default and an unsafe ``set`` method. - The maximum depth for recursive interpolation for :meth:`get` when the *raw* - parameter is false. This is relevant only for the :class:`ConfigParser` class. + .. note:: + Consider using :class:`SafeConfigParser` instead which checks types of + the values to be stored internally. If you don't want interpolation, you + can use ``SafeConfigParser(interpolation=None)``. -.. _safeconfigparser-objects: + .. method:: set(section, option, value) -SafeConfigParser Objects ------------------------- + If the given section exists, set the given option to the specified value; + otherwise raise :exc:`NoSectionError`. While it is possible to use + :class:`RawConfigParser` (or :class:`ConfigParser` with *raw* parameters + set to true) for *internal* storage of non-string values, full + functionality (including interpolation and output to files) can only be + achieved using string values. -.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True) + This method lets users assign non-string values to keys internally. This + behaviour is unsupported and will cause errors when attempting to write + to a file or get it in non-raw mode. **Use the mapping protocol API** + which does not allow such assignments to take place. - Derived class of :class:`ConfigParser` that implements a variant of the - magical interpolation feature. This implementation is more predictable as - it validates the interpolation syntax used within a configuration file. - This class also enables escaping the interpolation character (a key can have - ``%`` as part of the value by specifying ``%%`` in the file). - - Applications that don't require interpolation should use - :class:`RawConfigParser`, otherwise :class:`SafeConfigParser` is the best - option. - - .. versionchanged:: 3.1 - The default *dict_type* is :class:`collections.OrderedDict`. - - .. versionchanged:: 3.2 - *allow_no_value*, *delimiters*, *comment_prefixes*, *strict* and - *empty_lines_in_values* were added. +.. _configparser-objects: - The :class:`SafeConfigParser` class implements the same extended interface - as :class:`ConfigParser`, with the following addition: +ConfigParser Objects +-------------------- - .. method:: set(section, option, value) +.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BrokenInterpolation()) - If the given section exists, set the given option to the specified value; - otherwise raise :exc:`NoSectionError`. *value* must be a string; if not, - :exc:`TypeError` is raised. + .. deprecated:: 3.2 + Whenever you can, consider using :class:`SafeConfigParser`. The + :class:`ConfigParser` provides the same functionality but its + implementation is less predictable. It does not validate the + interpolation syntax used within a configuration file. It also does not + enable escaping the interpolation character (when using + :class:`SafeConfigParser`, a key can have ``%`` as part of the value by + specifying ``%%`` in the file). On top of that, this class doesn't ensure + whether values passed to the parser object are strings which may lead to + inconsistent internal state. Exceptions Modified: python/branches/py3k/Doc/library/fileformats.rst ============================================================================== --- python/branches/py3k/Doc/library/fileformats.rst (original) +++ python/branches/py3k/Doc/library/fileformats.rst Fri Dec 3 17:28:00 2010 @@ -5,7 +5,7 @@ ************ The modules described in this chapter parse various miscellaneous file formats -that aren't markup languages or are related to e-mail. +that aren't markup languages and are not related to e-mail. .. toctree:: Modified: python/branches/py3k/Lib/configparser.py ============================================================================== --- python/branches/py3k/Lib/configparser.py (original) +++ python/branches/py3k/Lib/configparser.py Fri Dec 3 17:28:00 2010 @@ -4,23 +4,13 @@ and followed by "name: value" entries, with continuations and such in the style of RFC 822. -The option values can contain format strings which refer to other values in -the same section, or values in a special [DEFAULT] section. - -For example: - - something: %(dir)s/whatever - -would resolve the "%(dir)s" to the value of dir. All reference -expansions are done late, on demand. - Intrinsic defaults can be specified by passing them into the -ConfigParser constructor as a dictionary. +SafeConfigParser constructor as a dictionary. class: -ConfigParser -- responsible for parsing a list of - configuration files, and managing the parsed database. +SafeConfigParser -- responsible for parsing a list of + configuration files, and managing the parsed database. methods: @@ -316,7 +306,7 @@ def filename(self): """Deprecated, use `source'.""" warnings.warn( - "This 'filename' attribute will be removed in future versions. " + "The 'filename' attribute will be removed in future versions. " "Use 'source' instead.", DeprecationWarning, stacklevel=2 ) @@ -362,6 +352,204 @@ _UNSET = object() +class Interpolation: + """Dummy interpolation that passes the value through with no changes.""" + + def before_get(self, parser, section, option, value, defaults): + return value + + def before_set(self, parser, section, option, value): + return value + + def before_read(self, parser, section, option, value): + return value + + def before_write(self, parser, section, option, value): + return value + + +class BasicInterpolation(Interpolation): + """Interpolation as implemented in the classic SafeConfigParser. + + The option values can contain format strings which refer to other values in + the same section, or values in the special default section. + + For example: + + something: %(dir)s/whatever + + would resolve the "%(dir)s" to the value of dir. All reference + expansions are done late, on demand. If a user needs to use a bare % in + a configuration file, she can escape it by writing %%. Other other % usage + is considered a user error and raises `InterpolationSyntaxError'.""" + + _KEYCRE = re.compile(r"%\(([^)]+)\)s") + + def before_get(self, parser, section, option, value, defaults): + L = [] + self._interpolate_some(parser, option, L, value, section, defaults, 1) + return ''.join(L) + + def before_set(self, parser, section, option, value): + tmp_value = value.replace('%%', '') # escaped percent signs + tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax + if '%' in tmp_value: + raise ValueError("invalid interpolation syntax in %r at " + "position %d" % (value, tmp_value.find('%'))) + return value + + def _interpolate_some(self, parser, option, accum, rest, section, map, + depth): + if depth > MAX_INTERPOLATION_DEPTH: + raise InterpolationDepthError(option, section, rest) + while rest: + p = rest.find("%") + if p < 0: + accum.append(rest) + return + if p > 0: + accum.append(rest[:p]) + rest = rest[p:] + # p is no longer used + c = rest[1:2] + if c == "%": + accum.append("%") + rest = rest[2:] + elif c == "(": + m = self._KEYCRE.match(rest) + if m is None: + raise InterpolationSyntaxError(option, section, + "bad interpolation variable reference %r" % rest) + var = parser.optionxform(m.group(1)) + rest = rest[m.end():] + try: + v = map[var] + except KeyError: + raise InterpolationMissingOptionError( + option, section, rest, var) + if "%" in v: + self._interpolate_some(parser, option, accum, v, + section, map, depth + 1) + else: + accum.append(v) + else: + raise InterpolationSyntaxError( + option, section, + "'%%' must be followed by '%%' or '(', " + "found: %r" % (rest,)) + + +class ExtendedInterpolation(Interpolation): + """Advanced variant of interpolation, supports the syntax used by + `zc.buildout'. Enables interpolation between sections.""" + + _KEYCRE = re.compile(r"\$\{([^}]+)\}") + + def before_get(self, parser, section, option, value, defaults): + L = [] + self._interpolate_some(parser, option, L, value, section, defaults, 1) + return ''.join(L) + + def before_set(self, parser, section, option, value): + tmp_value = value.replace('$$', '') # escaped dollar signs + tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax + if '$' in tmp_value: + raise ValueError("invalid interpolation syntax in %r at " + "position %d" % (value, tmp_value.find('%'))) + return value + + def _interpolate_some(self, parser, option, accum, rest, section, map, + depth): + if depth > MAX_INTERPOLATION_DEPTH: + raise InterpolationDepthError(option, section, rest) + while rest: + p = rest.find("$") + if p < 0: + accum.append(rest) + return + if p > 0: + accum.append(rest[:p]) + rest = rest[p:] + # p is no longer used + c = rest[1:2] + if c == "$": + accum.append("$") + rest = rest[2:] + elif c == "{": + m = self._KEYCRE.match(rest) + if m is None: + raise InterpolationSyntaxError(option, section, + "bad interpolation variable reference %r" % rest) + path = parser.optionxform(m.group(1)).split(':') + rest = rest[m.end():] + sect = section + opt = option + try: + if len(path) == 1: + opt = path[0] + v = map[opt] + elif len(path) == 2: + sect = path[0] + opt = path[1] + v = parser.get(sect, opt, raw=True) + else: + raise InterpolationSyntaxError( + option, section, + "More than one ':' found: %r" % (rest,)) + except KeyError: + raise InterpolationMissingOptionError( + option, section, rest, var) + if "$" in v: + self._interpolate_some(parser, opt, accum, v, sect, + dict(parser.items(sect, raw=True)), + depth + 1) + else: + accum.append(v) + else: + raise InterpolationSyntaxError( + option, section, + "'$' must be followed by '$' or '{', " + "found: %r" % (rest,)) + + +class BrokenInterpolation(Interpolation): + """Deprecated interpolation as implemented in the classic ConfigParser. + Use BasicInterpolation or ExtendedInterpolation instead.""" + + _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") + + def before_get(self, parser, section, option, value, vars): + rawval = value + depth = MAX_INTERPOLATION_DEPTH + while depth: # Loop through this until it's done + depth -= 1 + if value and "%(" in value: + replace = functools.partial(self._interpolation_replace, + parser=parser) + value = self._KEYCRE.sub(replace, value) + try: + value = value % vars + except KeyError as e: + raise InterpolationMissingOptionError( + option, section, rawval, e.args[0]) + else: + break + if value and "%(" in value: + raise InterpolationDepthError(option, section, rawval) + return value + + def before_set(self, parser, section, option, value): + return value + + @staticmethod + def _interpolation_replace(match, parser): + s = match.group(1) + if s is None: + return match.group() + else: + return "%%(%s)s" % parser.optionxform(s) + + class RawConfigParser(MutableMapping): """ConfigParser that does not do interpolation.""" @@ -388,7 +576,8 @@ # space/tab (?P.*))?$ # everything up to eol """ - + # Interpolation algorithm to be used if the user does not specify another + _DEFAULT_INTERPOLATION = Interpolation() # Compiled regular expression for matching sections SECTCRE = re.compile(_SECT_TMPL, re.VERBOSE) # Compiled regular expression for matching options with typical separators @@ -406,7 +595,15 @@ allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True, - default_section=DEFAULTSECT): + default_section=DEFAULTSECT, + interpolation=_UNSET): + + if self.__class__ is RawConfigParser: + warnings.warn( + "The RawConfigParser class will be removed in future versions." + " Use 'SafeConfigParser(interpolation=None)' instead.", + DeprecationWarning, stacklevel=2 + ) self._dict = dict_type self._sections = self._dict() self._defaults = self._dict() @@ -435,7 +632,11 @@ self._strict = strict self._allow_no_value = allow_no_value self._empty_lines_in_values = empty_lines_in_values - self._default_section=default_section + if interpolation is _UNSET: + self._interpolation = self._DEFAULT_INTERPOLATION + else: + self._interpolation = interpolation + self.default_section=default_section def defaults(self): return self._defaults @@ -451,7 +652,7 @@ Raise DuplicateSectionError if a section by the specified name already exists. Raise ValueError if name is DEFAULT. """ - if section == self._default_section: + if section == self.default_section: raise ValueError('Invalid section name: %s' % section) if section in self._sections: @@ -555,7 +756,7 @@ ) self.read_file(fp, source=filename) - def get(self, section, option, *, vars=None, fallback=_UNSET): + def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): """Get an option value for a given section. If `vars' is provided, it must be a dictionary. The option is looked up @@ -563,7 +764,12 @@ If the key is not found and `fallback' is provided, it is used as a fallback value. `None' can be provided as a `fallback' value. - Arguments `vars' and `fallback' are keyword only. + If interpolation is enabled and the optional argument `raw' is False, + all interpolations are expanded in the return values. + + Arguments `raw', `vars', and `fallback' are keyword only. + + The section DEFAULT is special. """ try: d = self._unify_values(section, vars) @@ -574,61 +780,90 @@ return fallback option = self.optionxform(option) try: - return d[option] + value = d[option] except KeyError: if fallback is _UNSET: raise NoOptionError(option, section) else: return fallback - def items(self, section): - try: - d2 = self._sections[section] - except KeyError: - if section != self._default_section: - raise NoSectionError(section) - d2 = self._dict() - d = self._defaults.copy() - d.update(d2) - return d.items() + if raw or value is None: + return value + else: + return self._interpolation.before_get(self, section, option, value, + d) def _get(self, section, conv, option, **kwargs): return conv(self.get(section, option, **kwargs)) - def getint(self, section, option, *, vars=None, fallback=_UNSET): + def getint(self, section, option, *, raw=False, vars=None, + fallback=_UNSET): try: - return self._get(section, int, option, vars=vars) + return self._get(section, int, option, raw=raw, vars=vars) except (NoSectionError, NoOptionError): if fallback is _UNSET: raise else: return fallback - def getfloat(self, section, option, *, vars=None, fallback=_UNSET): + def getfloat(self, section, option, *, raw=False, vars=None, + fallback=_UNSET): try: - return self._get(section, float, option, vars=vars) + return self._get(section, float, option, raw=raw, vars=vars) except (NoSectionError, NoOptionError): if fallback is _UNSET: raise else: return fallback - def getboolean(self, section, option, *, vars=None, fallback=_UNSET): + def getboolean(self, section, option, *, raw=False, vars=None, + fallback=_UNSET): try: return self._get(section, self._convert_to_boolean, option, - vars=vars) + raw=raw, vars=vars) except (NoSectionError, NoOptionError): if fallback is _UNSET: raise else: return fallback + def items(self, section, raw=False, vars=None): + """Return a list of (name, value) tuples for each option in a section. + + All % interpolations are expanded in the return values, based on the + defaults passed into the constructor, unless the optional argument + `raw' is true. Additional substitutions may be provided using the + `vars' argument, which must be a dictionary whose contents overrides + any pre-existing defaults. + + The section DEFAULT is special. + """ + d = self._defaults.copy() + try: + d.update(self._sections[section]) + except KeyError: + if section != self.default_section: + raise NoSectionError(section) + # Update with the entry specific variables + if vars: + for key, value in vars.items(): + d[self.optionxform(key)] = value + options = list(d.keys()) + if raw: + return [(option, d[option]) + for option in options] + else: + return [(option, self._interpolation.before_get(self, section, + option, d[option], + d)) + for option in options] + def optionxform(self, optionstr): return optionstr.lower() def has_option(self, section, option): """Check for the existence of a given option in a given section.""" - if not section or section == self._default_section: + if not section or section == self.default_section: option = self.optionxform(option) return option in self._defaults elif section not in self._sections: @@ -640,7 +875,10 @@ def set(self, section, option, value=None): """Set an option.""" - if not section or section == self._default_section: + if value: + value = self._interpolation.before_set(self, section, option, + value) + if not section or section == self.default_section: sectdict = self._defaults else: try: @@ -660,7 +898,7 @@ else: d = self._delimiters[0] if self._defaults: - self._write_section(fp, self._default_section, + self._write_section(fp, self.default_section, self._defaults.items(), d) for section in self._sections: self._write_section(fp, section, @@ -670,6 +908,8 @@ """Write a single section to the specified `fp'.""" fp.write("[{}]\n".format(section_name)) for key, value in section_items: + value = self._interpolation.before_write(self, section_name, key, + value) if value is not None or not self._allow_no_value: value = delimiter + str(value).replace('\n', '\n\t') else: @@ -679,7 +919,7 @@ def remove_option(self, section, option): """Remove an option.""" - if not section or section == self._default_section: + if not section or section == self.default_section: sectdict = self._defaults else: try: @@ -701,7 +941,7 @@ return existed def __getitem__(self, key): - if key != self._default_section and not self.has_section(key): + if key != self.default_section and not self.has_section(key): raise KeyError(key) return self._proxies[key] @@ -715,21 +955,21 @@ self.read_dict({key: value}) def __delitem__(self, key): - if key == self._default_section: + if key == self.default_section: raise ValueError("Cannot remove the default section.") if not self.has_section(key): raise KeyError(key) self.remove_section(key) def __contains__(self, key): - return key == self._default_section or self.has_section(key) + return key == self.default_section or self.has_section(key) def __len__(self): return len(self._sections) + 1 # the default section def __iter__(self): # XXX does it break when underlying container state changed? - return itertools.chain((self._default_section,), self._sections.keys()) + return itertools.chain((self.default_section,), self._sections.keys()) def _read(self, fp, fpname): """Parse a sectioned configuration file. @@ -801,7 +1041,7 @@ lineno) cursect = self._sections[sectname] elements_added.add(sectname) - elif sectname == self._default_section: + elif sectname == self.default_section: cursect = self._defaults else: cursect = self._dict() @@ -836,7 +1076,7 @@ cursect[optname] = [optval] else: # valueless option handling - cursect[optname] = optval + cursect[optname] = None else: # a non-fatal parsing error occurred. set up the # exception but keep going. the exception will be @@ -849,12 +1089,16 @@ self._join_multiline_values() def _join_multiline_values(self): - all_sections = itertools.chain((self._defaults,), - self._sections.values()) - for options in all_sections: + defaults = self.default_section, self._defaults + all_sections = itertools.chain((defaults,), + self._sections.items()) + for section, options in all_sections: for name, val in options.items(): if isinstance(val, list): - options[name] = '\n'.join(val).rstrip() + val = '\n'.join(val).rstrip() + options[name] = self._interpolation.before_read(self, + section, + name, val) def _handle_error(self, exc, fpname, lineno, line): if not exc: @@ -871,7 +1115,7 @@ try: d.update(self._sections[section]) except KeyError: - if section != self._default_section: + if section != self.default_section: raise NoSectionError(section) # Update with the entry specific variables if vars: @@ -906,197 +1150,31 @@ raise TypeError("option values must be strings") - class ConfigParser(RawConfigParser): """ConfigParser implementing interpolation.""" - def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): - """Get an option value for a given section. - - If `vars' is provided, it must be a dictionary. The option is looked up - in `vars' (if provided), `section', and in `DEFAULTSECT' in that order. - If the key is not found and `fallback' is provided, it is used as - a fallback value. `None' can be provided as a `fallback' value. - - All % interpolations are expanded in the return values, unless the - optional argument `raw' is true. Values for interpolation keys are - looked up in the same manner as the option. - - Arguments `raw', `vars', and `fallback' are keyword only. - - The section DEFAULT is special. - """ - try: - d = self._unify_values(section, vars) - except NoSectionError: - if fallback is _UNSET: - raise - else: - return fallback - option = self.optionxform(option) - try: - value = d[option] - except KeyError: - if fallback is _UNSET: - raise NoOptionError(option, section) - else: - return fallback - - if raw or value is None: - return value - else: - return self._interpolate(section, option, value, d) - - def getint(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, int, option, raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback - - def getfloat(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, float, option, raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback - - def getboolean(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, self._convert_to_boolean, option, - raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback - - def items(self, section, raw=False, vars=None): - """Return a list of (name, value) tuples for each option in a section. - - All % interpolations are expanded in the return values, based on the - defaults passed into the constructor, unless the optional argument - `raw' is true. Additional substitutions may be provided using the - `vars' argument, which must be a dictionary whose contents overrides - any pre-existing defaults. - - The section DEFAULT is special. - """ - d = self._defaults.copy() - try: - d.update(self._sections[section]) - except KeyError: - if section != self._default_section: - raise NoSectionError(section) - # Update with the entry specific variables - if vars: - for key, value in vars.items(): - d[self.optionxform(key)] = value - options = list(d.keys()) - if raw: - return [(option, d[option]) - for option in options] - else: - return [(option, self._interpolate(section, option, d[option], d)) - for option in options] - - def _interpolate(self, section, option, rawval, vars): - # do the string interpolation - value = rawval - depth = MAX_INTERPOLATION_DEPTH - while depth: # Loop through this until it's done - depth -= 1 - if value and "%(" in value: - value = self._KEYCRE.sub(self._interpolation_replace, value) - try: - value = value % vars - except KeyError as e: - raise InterpolationMissingOptionError( - option, section, rawval, e.args[0]) - else: - break - if value and "%(" in value: - raise InterpolationDepthError(option, section, rawval) - return value - - _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") + _DEFAULT_INTERPOLATION = BrokenInterpolation() - def _interpolation_replace(self, match): - s = match.group(1) - if s is None: - return match.group() - else: - return "%%(%s)s" % self.optionxform(s) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.__class__ is ConfigParser: + warnings.warn( + "The ConfigParser class will be removed in future versions." + " Use SafeConfigParser instead.", + DeprecationWarning, stacklevel=2 + ) class SafeConfigParser(ConfigParser): """ConfigParser implementing sane interpolation.""" - def _interpolate(self, section, option, rawval, vars): - # do the string interpolation - L = [] - self._interpolate_some(option, L, rawval, section, vars, 1) - return ''.join(L) - - _interpvar_re = re.compile(r"%\(([^)]+)\)s") - - def _interpolate_some(self, option, accum, rest, section, map, depth): - if depth > MAX_INTERPOLATION_DEPTH: - raise InterpolationDepthError(option, section, rest) - while rest: - p = rest.find("%") - if p < 0: - accum.append(rest) - return - if p > 0: - accum.append(rest[:p]) - rest = rest[p:] - # p is no longer used - c = rest[1:2] - if c == "%": - accum.append("%") - rest = rest[2:] - elif c == "(": - m = self._interpvar_re.match(rest) - if m is None: - raise InterpolationSyntaxError(option, section, - "bad interpolation variable reference %r" % rest) - var = self.optionxform(m.group(1)) - rest = rest[m.end():] - try: - v = map[var] - except KeyError: - raise InterpolationMissingOptionError( - option, section, rest, var) - if "%" in v: - self._interpolate_some(option, accum, v, - section, map, depth + 1) - else: - accum.append(v) - else: - raise InterpolationSyntaxError( - option, section, - "'%%' must be followed by '%%' or '(', " - "found: %r" % (rest,)) + _DEFAULT_INTERPOLATION = BasicInterpolation() def set(self, section, option, value=None): - """Set an option. Extend ConfigParser.set: check for string values.""" + """Set an option. Extends RawConfigParser.set by validating type and + interpolation syntax on the value.""" self._validate_value_type(value) - # check for bad percent signs - if value: - tmp_value = value.replace('%%', '') # escaped percent signs - tmp_value = self._interpvar_re.sub('', tmp_value) # valid syntax - if '%' in tmp_value: - raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, tmp_value.find('%'))) - ConfigParser.set(self, section, option, value) + super().set(section, option, value) class SectionProxy(MutableMapping): Modified: python/branches/py3k/Lib/test/test_cfgparser.py ============================================================================== --- python/branches/py3k/Lib/test/test_cfgparser.py (original) +++ python/branches/py3k/Lib/test/test_cfgparser.py Fri Dec 3 17:28:00 2010 @@ -4,6 +4,7 @@ import os import unittest import textwrap +import warnings from test import support @@ -32,6 +33,7 @@ dict_type = configparser._default_dict strict = False default_section = configparser.DEFAULTSECT + interpolation = configparser._UNSET def newconfig(self, defaults=None): arguments = dict( @@ -43,8 +45,12 @@ dict_type=self.dict_type, strict=self.strict, default_section=self.default_section, + interpolation=self.interpolation, ) - return self.config_class(**arguments) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + instance = self.config_class(**arguments) + return instance def fromstring(self, string, defaults=None): cf = self.newconfig(defaults) @@ -847,6 +853,70 @@ cf = self.newconfig() self.assertRaises(ValueError, cf.add_section, self.default_section) +class SafeConfigParserTestCaseExtendedInterpolation(BasicTestCase): + config_class = configparser.SafeConfigParser + interpolation = configparser.ExtendedInterpolation() + default_section = 'common' + + def test_extended_interpolation(self): + cf = self.fromstring(textwrap.dedent(""" + [common] + favourite Beatle = Paul + favourite color = green + + [tom] + favourite band = ${favourite color} day + favourite pope = John ${favourite Beatle} II + sequel = ${favourite pope}I + + [ambv] + favourite Beatle = George + son of Edward VII = ${favourite Beatle} V + son of George V = ${son of Edward VII}I + + [stanley] + favourite Beatle = ${ambv:favourite Beatle} + favourite pope = ${tom:favourite pope} + favourite color = black + favourite state of mind = paranoid + favourite movie = soylent ${common:favourite color} + favourite song = ${favourite color} sabbath - ${favourite state of mind} + """).strip()) + + eq = self.assertEqual + eq(cf['common']['favourite Beatle'], 'Paul') + eq(cf['common']['favourite color'], 'green') + eq(cf['tom']['favourite Beatle'], 'Paul') + eq(cf['tom']['favourite color'], 'green') + eq(cf['tom']['favourite band'], 'green day') + eq(cf['tom']['favourite pope'], 'John Paul II') + eq(cf['tom']['sequel'], 'John Paul III') + eq(cf['ambv']['favourite Beatle'], 'George') + eq(cf['ambv']['favourite color'], 'green') + eq(cf['ambv']['son of Edward VII'], 'George V') + eq(cf['ambv']['son of George V'], 'George VI') + eq(cf['stanley']['favourite Beatle'], 'George') + eq(cf['stanley']['favourite color'], 'black') + eq(cf['stanley']['favourite state of mind'], 'paranoid') + eq(cf['stanley']['favourite movie'], 'soylent green') + eq(cf['stanley']['favourite pope'], 'John Paul II') + eq(cf['stanley']['favourite song'], + 'black sabbath - paranoid') + + def test_endless_loop(self): + cf = self.fromstring(textwrap.dedent(""" + [one for you] + ping = ${one for me:pong} + + [one for me] + pong = ${one for you:ping} + """).strip()) + + with self.assertRaises(configparser.InterpolationDepthError): + cf['one for you']['ping'] + + + class SafeConfigParserTestCaseNonStandardDelimiters(SafeConfigParserTestCase): delimiters = (':=', '$') comment_prefixes = ('//', '"') @@ -910,7 +980,9 @@ def prepare(self, config_class): # This is the default, but that's the point. - cp = config_class(allow_no_value=False) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + cp = config_class(allow_no_value=False) cp.add_section("section") cp.set("section", "option", None) sio = io.StringIO() @@ -978,6 +1050,7 @@ RawConfigParserTestCaseNonStandardDelimiters, RawConfigParserTestSambaConf, SafeConfigParserTestCase, + SafeConfigParserTestCaseExtendedInterpolation, SafeConfigParserTestCaseNonStandardDelimiters, SafeConfigParserTestCaseNoValue, SafeConfigParserTestCaseTrickyFile, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 17:28:00 2010 @@ -149,6 +149,14 @@ - Issue #10467: Fix BytesIO.readinto() after seeking into a position after the end of the file. +- configparser: the ConfigParser class has been deprecated in favor of + SafeConfigParser. Usage of RawConfigParser is now discouraged for new + projects in favor of SafeConfigParser(interpolation=None). + +- Issue #10499: configparser supports pluggable interpolation handlers. New + interpolation handler added (ExtendedInterpolation) which supports the syntax + used by zc.buildout (e.g. interpolation between sections). + - Issue #1682942: configparser supports alternative option/value delimiters. - Issue #5412: configparser supports mapping protocol access. From python-checkins at python.org Fri Dec 3 17:51:33 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 3 Dec 2010 17:51:33 +0100 (CET) Subject: [Python-checkins] r86977 - python/branches/py3k/Objects/complexobject.c Message-ID: <20101203165133.C8314F414@mail.python.org> Author: victor.stinner Date: Fri Dec 3 17:51:33 2010 New Revision: 86977 Log: #6780: fix complex() constructor TypeError message Modified: python/branches/py3k/Objects/complexobject.c Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Fri Dec 3 17:51:33 2010 @@ -783,7 +783,7 @@ } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, - "complex() arg is not a string"); + "complex() argument must be a string or a number"); return NULL; } From python-checkins at python.org Fri Dec 3 18:00:40 2010 From: python-checkins at python.org (phillip.eby) Date: Fri, 3 Dec 2010 18:00:40 +0100 (CET) Subject: [Python-checkins] r86978 - python/branches/release27-maint/Lib/distutils/command/upload.py Message-ID: <20101203170040.4B43BEE9AB@mail.python.org> Author: phillip.eby Date: Fri Dec 3 18:00:40 2010 New Revision: 86978 Log: Fix for issue10367, courtesy of Daniel Tavares. Modified: python/branches/release27-maint/Lib/distutils/command/upload.py Modified: python/branches/release27-maint/Lib/distutils/command/upload.py ============================================================================== --- python/branches/release27-maint/Lib/distutils/command/upload.py (original) +++ python/branches/release27-maint/Lib/distutils/command/upload.py Fri Dec 3 18:00:40 2010 @@ -176,6 +176,9 @@ result = urlopen(request) status = result.getcode() reason = result.msg + if self.show_response: + msg = '\n'.join(('-' * 75, r.read(), '-' * 75)) + self.announce(msg, log.INFO) except socket.error, e: self.announce(str(e), log.ERROR) return @@ -189,6 +192,3 @@ else: self.announce('Upload failed (%s): %s' % (status, reason), log.ERROR) - if self.show_response: - msg = '\n'.join(('-' * 75, r.read(), '-' * 75)) - self.announce(msg, log.INFO) From python-checkins at python.org Fri Dec 3 18:06:43 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 3 Dec 2010 18:06:43 +0100 (CET) Subject: [Python-checkins] r86979 - python/branches/py3k/Python/import.c Message-ID: <20101203170643.D6A2CEE9B3@mail.python.org> Author: victor.stinner Date: Fri Dec 3 18:06:43 2010 New Revision: 86979 Log: import: use PyUnicode_FSConverter to support bytes path and PEP 383 (instead of PyArg_Parse*() with "es" format and Py_FileSystemDefaultEncoding) Modified: python/branches/py3k/Python/import.c Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Fri Dec 3 18:06:43 2010 @@ -3206,14 +3206,14 @@ static PyObject * imp_find_module(PyObject *self, PyObject *args) { - char *name; + PyObject *name; PyObject *ret, *path = NULL; - if (!PyArg_ParseTuple(args, "es|O:find_module", - Py_FileSystemDefaultEncoding, &name, + if (!PyArg_ParseTuple(args, "O&|O:find_module", + PyUnicode_FSConverter, &name, &path)) return NULL; - ret = call_find_module(name, path); - PyMem_Free(name); + ret = call_find_module(PyBytes_AS_STRING(name), path); + Py_DECREF(name); return ret; } @@ -3331,23 +3331,23 @@ imp_load_compiled(PyObject *self, PyObject *args) { char *name; - char *pathname; + PyObject *pathname; PyObject *fob = NULL; PyObject *m; FILE *fp; - if (!PyArg_ParseTuple(args, "ses|O:load_compiled", + if (!PyArg_ParseTuple(args, "sO&|O:load_compiled", &name, - Py_FileSystemDefaultEncoding, &pathname, + PyUnicode_FSConverter, &pathname, &fob)) return NULL; - fp = get_file(pathname, fob, "rb"); + fp = get_file(PyBytes_AS_STRING(pathname), fob, "rb"); if (fp == NULL) { - PyMem_Free(pathname); + Py_DECREF(pathname); return NULL; } - m = load_compiled_module(name, pathname, fp); + m = load_compiled_module(name, PyBytes_AS_STRING(pathname), fp); fclose(fp); - PyMem_Free(pathname); + Py_DECREF(pathname); return m; } @@ -3386,22 +3386,22 @@ imp_load_source(PyObject *self, PyObject *args) { char *name; - char *pathname; + PyObject *pathname; PyObject *fob = NULL; PyObject *m; FILE *fp; - if (!PyArg_ParseTuple(args, "ses|O:load_source", + if (!PyArg_ParseTuple(args, "sO&|O:load_source", &name, - Py_FileSystemDefaultEncoding, &pathname, + PyUnicode_FSConverter, &pathname, &fob)) return NULL; - fp = get_file(pathname, fob, "r"); + fp = get_file(PyBytes_AS_STRING(pathname), fob, "r"); if (fp == NULL) { - PyMem_Free(pathname); + Py_DECREF(pathname); return NULL; } - m = load_source_module(name, pathname, fp); - PyMem_Free(pathname); + m = load_source_module(name, PyBytes_AS_STRING(pathname), fp); + Py_DECREF(pathname); fclose(fp); return m; } @@ -3455,13 +3455,13 @@ imp_load_package(PyObject *self, PyObject *args) { char *name; - char *pathname; + PyObject *pathname; PyObject * ret; - if (!PyArg_ParseTuple(args, "ses:load_package", - &name, Py_FileSystemDefaultEncoding, &pathname)) + if (!PyArg_ParseTuple(args, "sO&:load_package", + &name, PyUnicode_FSConverter, &pathname)) return NULL; - ret = load_package(name, pathname); - PyMem_Free(pathname); + ret = load_package(name, PyBytes_AS_STRING(pathname)); + Py_DECREF(pathname); return ret; } @@ -3534,21 +3534,23 @@ { static char *kwlist[] = {"path", NULL}; + PyObject *pathname_obj; char *pathname; char buf[MAXPATHLEN+1]; if (!PyArg_ParseTupleAndKeywords( - args, kws, "es", kwlist, - Py_FileSystemDefaultEncoding, &pathname)) + args, kws, "O&", kwlist, + PyUnicode_FSConverter, &pathname_obj)) return NULL; + pathname = PyBytes_AS_STRING(pathname_obj); if (make_source_pathname(pathname, buf) == NULL) { PyErr_Format(PyExc_ValueError, "Not a PEP 3147 pyc path: %s", pathname); - PyMem_Free(pathname); + Py_DECREF(pathname_obj); return NULL; } - PyMem_Free(pathname); + Py_DECREF(pathname_obj); return PyUnicode_FromString(buf); } From python-checkins at python.org Fri Dec 3 18:19:28 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 18:19:28 +0100 (CET) Subject: [Python-checkins] r86980 - python/branches/py3k/Doc/library/functions.rst Message-ID: <20101203171928.267EAEE995@mail.python.org> Author: georg.brandl Date: Fri Dec 3 18:19:27 2010 New Revision: 86980 Log: Fix punctuation. Modified: python/branches/py3k/Doc/library/functions.rst Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Fri Dec 3 18:19:27 2010 @@ -1047,8 +1047,8 @@ but some features (such as :func:`len`) will raise :exc:`OverflowError`. .. versionchanged:: 3.2 - Implement the Sequence ABC - Support slicing and negative indices + Implement the Sequence ABC. + Support slicing and negative indices. Test integers for membership in constant time instead of iterating through all items. From merwok at netwok.org Fri Dec 3 19:35:26 2010 From: merwok at netwok.org (=?UTF-8?B?w4lyaWMgQXJhdWpv?=) Date: Fri, 03 Dec 2010 19:35:26 +0100 Subject: [Python-checkins] r86976 - in python/branches/py3k: Doc/library/configparser.rst Doc/library/fileformats.rst Lib/configparser.py Lib/test/test_cfgparser.py Misc/NEWS In-Reply-To: <20101203162800.9A740EE9B9@mail.python.org> References: <20101203162800.9A740EE9B9@mail.python.org> Message-ID: <4CF9386E.4000205@netwok.org> Hello, > Author: lukasz.langa > New Revision: 86976 > Log: Issue 10499: Modular interpolation in configparser > > Modified: python/branches/py3k/Doc/library/configparser.rst Is the module still backward compatible with the 3.1 version, modulo fixed bugs? I haven?t been able to follow closely all the great improvements you?ve been making, and there has been a lot of movement in the code, so I?m not sure. Thanks for taking up configparser. Maybe it will become so useful and extensible that you?ll have to release it on PyPI for older Pythons :) > Modified: python/branches/py3k/Doc/library/fileformats.rst This looks like unrelated changes that slipped in the commit. I use svn status and svn diff all the time (actually a shell function to get a colorized diff, not plain svn diff). To commit I use a script based on http://selenic.com/repo/hg/file/tip/hgeditor that opens up the commit message file and the commit diff in two Vim splits. It?s very handy. > Modified: python/branches/py3k/Lib/configparser.py > > Raise DuplicateSectionError if a section by the specified name > already exists. Raise ValueError if name is DEFAULT. > """ > - if section == self._default_section: > + if section == self.default_section: > raise ValueError('Invalid section name: %s' % section) I think it?s the only error message using %s instead of %r. The quotes added by %r typically help spot names with spaces (embedded or trailing) and the like. > + options = list(d.keys()) > + if raw: > + return [(option, d[option]) > + for option in options] > + else: > + return [(option, self._interpolation.before_get(self, section, > + option, d[option], > + d)) > + for option in options] The list call seems unneeded. Minor style point: I avoid such dangling arguments that don?t read great, I prefer to go to a newline after the opening paren: return [(option, self._interpolation.before_get( self, section, option, d[option], d)) for option in options] > class ConfigParser(RawConfigParser): > [snip] > + def __init__(self, *args, **kwargs): > + super().__init__(*args, **kwargs) > + if self.__class__ is ConfigParser: > + warnings.warn( > + "The ConfigParser class will be removed in future versions." > + " Use SafeConfigParser instead.", > + DeprecationWarning, stacklevel=2 > + ) Using __new__ may be clearer: no need to check for self.__class__, but still works. Would not help people that subclass a deprecated class, though. Cheers From python-checkins at python.org Fri Dec 3 19:41:39 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 3 Dec 2010 19:41:39 +0100 (CET) Subject: [Python-checkins] r86981 - in python/branches/py3k: Lib/test/test_io.py Misc/NEWS Modules/_io/bufferedio.c Message-ID: <20101203184139.F3D54EE982@mail.python.org> Author: antoine.pitrou Date: Fri Dec 3 19:41:39 2010 New Revision: 86981 Log: Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. Modified: python/branches/py3k/Lib/test/test_io.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_io/bufferedio.c Modified: python/branches/py3k/Lib/test/test_io.py ============================================================================== --- python/branches/py3k/Lib/test/test_io.py (original) +++ python/branches/py3k/Lib/test/test_io.py Fri Dec 3 19:41:39 2010 @@ -2653,12 +2653,50 @@ def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") + def check_reentrant_write(self, data, **fdopen_kwargs): + def on_alarm(*args): + # Will be called reentrantly from the same thread + wio.write(data) + 1/0 + signal.signal(signal.SIGALRM, on_alarm) + r, w = os.pipe() + wio = self.io.open(w, **fdopen_kwargs) + try: + signal.alarm(1) + # Either the reentrant call to wio.write() fails with RuntimeError, + # or the signal handler raises ZeroDivisionError. + with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm: + while 1: + for i in range(100): + wio.write(data) + wio.flush() + # Make sure the buffer doesn't fill up and block further writes + os.read(r, len(data) * 100) + exc = cm.exception + if isinstance(exc, RuntimeError): + self.assertTrue(str(exc).startswith("reentrant call"), str(exc)) + finally: + wio.close() + os.close(r) + + def test_reentrant_write_buffered(self): + self.check_reentrant_write(b"xy", mode="wb") + + def test_reentrant_write_text(self): + self.check_reentrant_write("xy", mode="w", encoding="ascii") + + class CSignalsTest(SignalsTest): io = io class PySignalsTest(SignalsTest): io = pyio + # Handling reentrancy issues would slow down _pyio even more, so the + # tests are disabled. + test_reentrant_write_buffered = None + test_reentrant_write_text = None + def test_main(): tests = (CIOTest, PyIOTest, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 19:41:39 2010 @@ -35,6 +35,10 @@ Library ------- +- Issue #10478: Reentrant calls inside buffered IO objects (for example by + way of a signal handler) now raise a RuntimeError instead of freezing the + current process. + - logging: Added getLogRecordFactory/setLogRecordFactory with docs and tests. - Issue #10549: Fix pydoc traceback when text-documenting certain classes. Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Fri Dec 3 19:41:39 2010 @@ -225,6 +225,7 @@ #ifdef WITH_THREAD PyThread_type_lock lock; + volatile long owner; #endif Py_ssize_t buffer_size; @@ -260,17 +261,34 @@ /* These macros protect the buffered object against concurrent operations. */ #ifdef WITH_THREAD -#define ENTER_BUFFERED(self) \ - if (!PyThread_acquire_lock(self->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS \ + +static int +_enter_buffered_busy(buffered *self) +{ + if (self->owner == PyThread_get_thread_ident()) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %R", self); + return 0; } + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + Py_END_ALLOW_THREADS + return 1; +} + +#define ENTER_BUFFERED(self) \ + ( (PyThread_acquire_lock(self->lock, 0) ? \ + 1 : _enter_buffered_busy(self)) \ + && (self->owner = PyThread_get_thread_ident(), 1) ) #define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); + do { \ + self->owner = 0; \ + PyThread_release_lock(self->lock); \ + } while(0); + #else -#define ENTER_BUFFERED(self) +#define ENTER_BUFFERED(self) 1 #define LEAVE_BUFFERED(self) #endif @@ -444,7 +462,8 @@ int r; CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; r = buffered_closed(self); if (r < 0) @@ -465,7 +484,8 @@ /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (res == NULL) { goto end; } @@ -679,6 +699,7 @@ PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } + self->owner = 0; #endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ @@ -705,7 +726,8 @@ CHECK_INITIALIZED(self) CHECK_CLOSED(self, "flush of closed file") - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); if (res != NULL && self->readable) { /* Rewind the raw stream so that its position corresponds to @@ -732,7 +754,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -767,7 +790,8 @@ if (n == -1) { /* The number of bytes is unspecified, read until the end of stream */ - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_all(self); LEAVE_BUFFERED(self) } @@ -775,7 +799,8 @@ res = _bufferedreader_read_fast(self, n); if (res == Py_None) { Py_DECREF(res); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_generic(self, n); LEAVE_BUFFERED(self) } @@ -803,7 +828,8 @@ if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -859,7 +885,8 @@ /* TODO: use raw.readinto() instead! */ if (self->writable) { - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); LEAVE_BUFFERED(self) if (res == NULL) @@ -903,7 +930,8 @@ goto end_unlocked; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + goto end_unlocked; /* Now we try to get some more from the raw stream */ if (self->writable) { @@ -1053,7 +1081,8 @@ } } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { @@ -1091,7 +1120,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 0); @@ -1748,7 +1778,10 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) { + PyBuffer_Release(&buf); + return NULL; + } /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { From python-checkins at python.org Fri Dec 3 19:57:42 2010 From: python-checkins at python.org (terry.reedy) Date: Fri, 3 Dec 2010 19:57:42 +0100 (CET) Subject: [Python-checkins] r86983 - in python/branches/py3k: Doc/library/difflib.rst Lib/difflib.py Message-ID: <20101203185742.4E2BCEE98E@mail.python.org> Author: terry.reedy Date: Fri Dec 3 19:57:42 2010 New Revision: 86983 Log: Modified: python/branches/py3k/Doc/library/difflib.rst python/branches/py3k/Lib/difflib.py Modified: python/branches/py3k/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k/Doc/library/difflib.rst (original) +++ python/branches/py3k/Doc/library/difflib.rst Fri Dec 3 19:57:42 2010 @@ -358,6 +358,16 @@ .. versionadded:: 3.2 The *autojunk* parameter. + SequenceMatcher objects get three data attributes: *bjunk* is the + set of elements of b for which *isjunk* is True; *bpopular* is the set of non- + junk elements considered popular by the heuristic (if it is not disabled); + *b2j* is a dict mapping the remaining elements of b to a list of positions where + they occur. All three are reset whenever *b* is reset with :meth:`set_seqs` + or :meth:`set_seq2`. + +.. versionadded:: 3.2 + The *bjunk* and *bpopular* attributes. + :class:`SequenceMatcher` objects have the following methods: @@ -538,7 +548,7 @@ SequenceMatcher Examples ------------------------ -This example compares two strings, considering blanks to be "junk:" +This example compares two strings, considering blanks to be "junk": >>> s = SequenceMatcher(lambda x: x == " ", ... "private Thread currentThread;", Modified: python/branches/py3k/Lib/difflib.py ============================================================================== --- python/branches/py3k/Lib/difflib.py (original) +++ python/branches/py3k/Lib/difflib.py Fri Dec 3 19:57:42 2010 @@ -213,6 +213,10 @@ # (at least 200 elements) and x accounts for more than 1 + 1% of # its elements (when autojunk is enabled). # DOES NOT WORK for x in a! + # bjunk + # the items in b for which isjunk is True. + # bpopular + # nonjunk items in b treated as junk by the heuristic (if used). self.isjunk = isjunk self.a = self.b = None @@ -321,7 +325,7 @@ indices.append(i) # Purge junk elements - junk = set() + self.bjunk = junk = set() isjunk = self.isjunk if isjunk: for elt in list(b2j.keys()): # using list() since b2j is modified @@ -330,7 +334,7 @@ del b2j[elt] # Purge popular elements that are not junk - popular = set() + self.bpopular = popular = set() n = len(b) if self.autojunk and n >= 200: ntest = n // 100 + 1 From python-checkins at python.org Fri Dec 3 20:14:17 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 3 Dec 2010 20:14:17 +0100 (CET) Subject: [Python-checkins] r86984 - python/branches/py3k/Doc/library/io.rst Message-ID: <20101203191417.ABF20EE986@mail.python.org> Author: antoine.pitrou Date: Fri Dec 3 20:14:17 2010 New Revision: 86984 Log: Add an "advanced topics" section to the io doc. Modified: python/branches/py3k/Doc/library/io.rst Modified: python/branches/py3k/Doc/library/io.rst ============================================================================== --- python/branches/py3k/Doc/library/io.rst (original) +++ python/branches/py3k/Doc/library/io.rst Fri Dec 3 20:14:17 2010 @@ -54,12 +54,6 @@ The text stream API is described in detail in the documentation for the :class:`TextIOBase`. -.. note:: - - Text I/O over a binary storage (such as a file) is significantly slower than - binary I/O over the same storage. This can become noticeable if you handle - huge amounts of text data (for example very large log files). - Binary I/O ^^^^^^^^^^ @@ -506,8 +500,8 @@ Buffered Streams ^^^^^^^^^^^^^^^^ -In many situations, buffered I/O streams will provide higher performance -(bandwidth and latency) than raw I/O streams. Their API is also more usable. +Buffered I/O streams provide a higher-level interface to an I/O device +than raw I/O does. .. class:: BytesIO([initial_bytes]) @@ -784,14 +778,72 @@ # .getvalue() will now raise an exception. output.close() - .. note:: - - :class:`StringIO` uses a native text storage and doesn't suffer from the - performance issues of other text streams, such as those based on - :class:`TextIOWrapper`. .. class:: IncrementalNewlineDecoder A helper codec that decodes newlines for universal newlines mode. It inherits :class:`codecs.IncrementalDecoder`. + +Advanced topics +--------------- + +Here we will discuss several advanced topics pertaining to the concrete +I/O implementations described above. + +Performance +^^^^^^^^^^^ + +Binary I/O +"""""""""" + +By reading and writing only large chunks of data even when the user asks +for a single byte, buffered I/O is designed to hide any inefficiency in +calling and executing the operating system's unbuffered I/O routines. The +gain will vary very much depending on the OS and the kind of I/O which is +performed (for example, on some contemporary OSes such as Linux, unbuffered +disk I/O can be as fast as buffered I/O). The bottom line, however, is +that buffered I/O will offer you predictable performance regardless of the +platform and the backing device. Therefore, it is most always preferable to +use buffered I/O rather than unbuffered I/O. + +Text I/O +"""""""" + +Text I/O over a binary storage (such as a file) is significantly slower than +binary I/O over the same storage, because it implies conversions from +unicode to binary data using a character codec. This can become noticeable +if you handle huge amounts of text data (for example very large log files). + +:class:`StringIO`, however, is a native in-memory unicode container and will +exhibit similar speed to :class:`BytesIO`. + +Multi-threading +^^^^^^^^^^^^^^^ + +:class:`FileIO` objects are thread-safe to the extent that the operating +system calls (such as ``read(2)`` under Unix) they are wrapping are thread-safe +too. + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +protect their internal structures using a lock; it is therefore safe to call +them from multiple threads at once. + +:class:`TextIOWrapper` objects are not thread-safe. + +Reentrancy +^^^^^^^^^^ + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +are not reentrant. While reentrant calls will not happen in normal situations, +they can arise if you are doing I/O in a :mod:`signal` handler. If it is +attempted to enter a buffered object again while already being accessed +*from the same thread*, then a :exc:`RuntimeError` is raised. + +The above implicitly extends to text files, since the :func:`open()` +function will wrap a buffered object inside a :class:`TextIOWrapper`. This +includes standard streams and therefore affects the built-in function +:func:`print()` as well. + From python-checkins at python.org Fri Dec 3 20:19:18 2010 From: python-checkins at python.org (eric.araujo) Date: Fri, 3 Dec 2010 20:19:18 +0100 (CET) Subject: [Python-checkins] r86985 - in python/branches/py3k: Lib/argparse.py Misc/NEWS Message-ID: <20101203191918.25026EE9C0@mail.python.org> Author: eric.araujo Date: Fri Dec 3 20:19:17 2010 New Revision: 86985 Log: Fix incorrect use of gettext in argparse (#10497). Steven, the maintainer of argparse, agreed to have this committed without tests for now, since the fix is obvious. See the bug log. Modified: python/branches/py3k/Lib/argparse.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/argparse.py ============================================================================== --- python/branches/py3k/Lib/argparse.py (original) +++ python/branches/py3k/Lib/argparse.py Fri Dec 3 20:19:17 2010 @@ -1080,7 +1080,7 @@ parser = self._name_parser_map[parser_name] except KeyError: tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)' % tup) + msg = _('unknown parser %r (choices: %s)') % tup raise ArgumentError(self, msg) # parse all the remaining options into the namespace @@ -1121,7 +1121,7 @@ elif 'w' in self._mode: return _sys.stdout else: - msg = _('argument "-" with mode %r' % self._mode) + msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) # all other arguments are used as file names Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 20:19:17 2010 @@ -35,6 +35,8 @@ Library ------- +- Issue #10497: Fix incorrect use of gettext in argparse. + - Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. From python-checkins at python.org Fri Dec 3 20:20:44 2010 From: python-checkins at python.org (michael.foord) Date: Fri, 3 Dec 2010 20:20:44 +0100 (CET) Subject: [Python-checkins] r86986 - python/branches/py3k/Lib/test/test_unittest.py Message-ID: <20101203192044.40724EE9D4@mail.python.org> Author: michael.foord Date: Fri Dec 3 20:20:44 2010 New Revision: 86986 Log: Fix so that test.test_unittest can be executed by unittest and not just regrtest Modified: python/branches/py3k/Lib/test/test_unittest.py Modified: python/branches/py3k/Lib/test/test_unittest.py ============================================================================== --- python/branches/py3k/Lib/test/test_unittest.py (original) +++ python/branches/py3k/Lib/test/test_unittest.py Fri Dec 3 20:20:44 2010 @@ -4,8 +4,13 @@ def test_main(): + # used by regrtest support.run_unittest(unittest.test.suite()) support.reap_children() +def load_tests(*_): + # used by unittest + return unittest.test.suite() + if __name__ == "__main__": test_main() From python-checkins at python.org Fri Dec 3 20:21:49 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 3 Dec 2010 20:21:49 +0100 (CET) Subject: [Python-checkins] r86987 - in python/branches/release31-maint: Doc/library/io.rst Lib/test/test_io.py Misc/NEWS Modules/_io/bufferedio.c Message-ID: <20101203192149.9D38DEE9C0@mail.python.org> Author: antoine.pitrou Date: Fri Dec 3 20:21:49 2010 New Revision: 86987 Log: Merged revisions 86981,86984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86981 | antoine.pitrou | 2010-12-03 19:41:39 +0100 (ven., 03 d?c. 2010) | 5 lines Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. ........ r86984 | antoine.pitrou | 2010-12-03 20:14:17 +0100 (ven., 03 d?c. 2010) | 3 lines Add an "advanced topics" section to the io doc. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/io.rst python/branches/release31-maint/Lib/test/test_io.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_io/bufferedio.c Modified: python/branches/release31-maint/Doc/library/io.rst ============================================================================== --- python/branches/release31-maint/Doc/library/io.rst (original) +++ python/branches/release31-maint/Doc/library/io.rst Fri Dec 3 20:21:49 2010 @@ -54,12 +54,6 @@ The text stream API is described in detail in the documentation for the :class:`TextIOBase`. -.. note:: - - Text I/O over a binary storage (such as a file) is significantly slower than - binary I/O over the same storage. This can become noticeable if you handle - huge amounts of text data (for example very large log files). - Binary I/O ^^^^^^^^^^ @@ -506,8 +500,8 @@ Buffered Streams ^^^^^^^^^^^^^^^^ -In many situations, buffered I/O streams will provide higher performance -(bandwidth and latency) than raw I/O streams. Their API is also more usable. +Buffered I/O streams provide a higher-level interface to an I/O device +than raw I/O does. .. class:: BytesIO([initial_bytes]) @@ -766,14 +760,72 @@ # .getvalue() will now raise an exception. output.close() - .. note:: - - :class:`StringIO` uses a native text storage and doesn't suffer from the - performance issues of other text streams, such as those based on - :class:`TextIOWrapper`. .. class:: IncrementalNewlineDecoder A helper codec that decodes newlines for universal newlines mode. It inherits :class:`codecs.IncrementalDecoder`. + +Advanced topics +--------------- + +Here we will discuss several advanced topics pertaining to the concrete +I/O implementations described above. + +Performance +^^^^^^^^^^^ + +Binary I/O +"""""""""" + +By reading and writing only large chunks of data even when the user asks +for a single byte, buffered I/O is designed to hide any inefficiency in +calling and executing the operating system's unbuffered I/O routines. The +gain will vary very much depending on the OS and the kind of I/O which is +performed (for example, on some contemporary OSes such as Linux, unbuffered +disk I/O can be as fast as buffered I/O). The bottom line, however, is +that buffered I/O will offer you predictable performance regardless of the +platform and the backing device. Therefore, it is most always preferable to +use buffered I/O rather than unbuffered I/O. + +Text I/O +"""""""" + +Text I/O over a binary storage (such as a file) is significantly slower than +binary I/O over the same storage, because it implies conversions from +unicode to binary data using a character codec. This can become noticeable +if you handle huge amounts of text data (for example very large log files). + +:class:`StringIO`, however, is a native in-memory unicode container and will +exhibit similar speed to :class:`BytesIO`. + +Multi-threading +^^^^^^^^^^^^^^^ + +:class:`FileIO` objects are thread-safe to the extent that the operating +system calls (such as ``read(2)`` under Unix) they are wrapping are thread-safe +too. + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +protect their internal structures using a lock; it is therefore safe to call +them from multiple threads at once. + +:class:`TextIOWrapper` objects are not thread-safe. + +Reentrancy +^^^^^^^^^^ + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +are not reentrant. While reentrant calls will not happen in normal situations, +they can arise if you are doing I/O in a :mod:`signal` handler. If it is +attempted to enter a buffered object again while already being accessed +*from the same thread*, then a :exc:`RuntimeError` is raised. + +The above implicitly extends to text files, since the :func:`open()` +function will wrap a buffered object inside a :class:`TextIOWrapper`. This +includes standard streams and therefore affects the built-in function +:func:`print()` as well. + Modified: python/branches/release31-maint/Lib/test/test_io.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_io.py (original) +++ python/branches/release31-maint/Lib/test/test_io.py Fri Dec 3 20:21:49 2010 @@ -2560,12 +2560,47 @@ def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") + def check_reentrant_write(self, data, **fdopen_kwargs): + def on_alarm(*args): + # Will be called reentrantly from the same thread + wio.write(data) + 1/0 + signal.signal(signal.SIGALRM, on_alarm) + r, w = os.pipe() + wio = self.io.open(w, **fdopen_kwargs) + try: + signal.alarm(1) + # Either the reentrant call to wio.write() fails with RuntimeError, + # or the signal handler raises ZeroDivisionError. + with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm: + while 1: + for i in range(100): + wio.write(data) + wio.flush() + # Make sure the buffer doesn't fill up and block further writes + os.read(r, len(data) * 100) + finally: + wio.close() + os.close(r) + + def test_reentrant_write_buffered(self): + self.check_reentrant_write(b"xy", mode="wb") + + def test_reentrant_write_text(self): + self.check_reentrant_write("xy", mode="w", encoding="ascii") + + class CSignalsTest(SignalsTest): io = io class PySignalsTest(SignalsTest): io = pyio + # Handling reentrancy issues would slow down _pyio even more, so the + # tests are disabled. + test_reentrant_write_buffered = None + test_reentrant_write_text = None + def test_main(): tests = (CIOTest, PyIOTest, Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Dec 3 20:21:49 2010 @@ -13,6 +13,10 @@ Library ------- +- Issue #10478: Reentrant calls inside buffered IO objects (for example by + way of a signal handler) now raise a RuntimeError instead of freezing the + current process. + - Issue #10464: netrc now correctly handles lines with embedded '#' characters. Modified: python/branches/release31-maint/Modules/_io/bufferedio.c ============================================================================== --- python/branches/release31-maint/Modules/_io/bufferedio.c (original) +++ python/branches/release31-maint/Modules/_io/bufferedio.c Fri Dec 3 20:21:49 2010 @@ -224,6 +224,7 @@ #ifdef WITH_THREAD PyThread_type_lock lock; + volatile long owner; #endif Py_ssize_t buffer_size; @@ -259,15 +260,33 @@ /* These macros protect the buffered object against concurrent operations. */ #ifdef WITH_THREAD -#define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ +static int +_enter_buffered_busy(buffered *self) +{ + if (self->owner == PyThread_get_thread_ident()) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %R", self); + return 0; + } + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); Py_END_ALLOW_THREADS + return 1; +} + +#define ENTER_BUFFERED(self) \ + ( (PyThread_acquire_lock(self->lock, 0) ? \ + 1 : _enter_buffered_busy(self)) \ + && (self->owner = PyThread_get_thread_ident(), 1) ) #define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); + do { \ + self->owner = 0; \ + PyThread_release_lock(self->lock); \ + } while(0); + #else -#define ENTER_BUFFERED(self) +#define ENTER_BUFFERED(self) 1 #define LEAVE_BUFFERED(self) #endif @@ -423,7 +442,8 @@ int r; CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; r = buffered_closed(self); if (r < 0) @@ -436,7 +456,8 @@ /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (res == NULL) { goto end; } @@ -639,6 +660,7 @@ PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } + self->owner = 0; #endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ @@ -665,7 +687,8 @@ CHECK_INITIALIZED(self) CHECK_CLOSED(self, "flush of closed file") - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); if (res != NULL && self->readable) { /* Rewind the raw stream so that its position corresponds to @@ -692,7 +715,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -727,7 +751,8 @@ if (n == -1) { /* The number of bytes is unspecified, read until the end of stream */ - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_all(self); LEAVE_BUFFERED(self) } @@ -735,7 +760,8 @@ res = _bufferedreader_read_fast(self, n); if (res == Py_None) { Py_DECREF(res); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_generic(self, n); LEAVE_BUFFERED(self) } @@ -763,7 +789,8 @@ if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -819,7 +846,8 @@ /* TODO: use raw.readinto() instead! */ if (self->writable) { - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); LEAVE_BUFFERED(self) if (res == NULL) @@ -863,7 +891,8 @@ goto end_unlocked; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + goto end_unlocked; /* Now we try to get some more from the raw stream */ if (self->writable) { @@ -1013,7 +1042,8 @@ } } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { @@ -1051,7 +1081,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 0); @@ -1705,7 +1736,10 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) { + PyBuffer_Release(&buf); + return NULL; + } /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { From python-checkins at python.org Fri Dec 3 20:22:35 2010 From: python-checkins at python.org (eric.araujo) Date: Fri, 3 Dec 2010 20:22:35 +0100 (CET) Subject: [Python-checkins] r86988 - python/branches/release31-maint Message-ID: <20101203192235.3B8B3ECD1@mail.python.org> Author: eric.araujo Date: Fri Dec 3 20:22:35 2010 New Revision: 86988 Log: Blocked revisions 86985 via svnmerge ........ r86985 | eric.araujo | 2010-12-03 20:19:17 +0100 (ven., 03 d?c. 2010) | 5 lines Fix incorrect use of gettext in argparse (#10497). Steven, the maintainer of argparse, agreed to have this committed without tests for now, since the fix is obvious. See the bug log. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Dec 3 20:24:39 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Dec 2010 20:24:39 +0100 (CET) Subject: [Python-checkins] r86989 - in python/branches/pep-0384: Include/structseq.h Include/unicodeobject.h Modules/_ctypes/cfield.c Modules/_testcapimodule.c Objects/rangeobject.c Objects/structseq.c Objects/unicodeobject.c Message-ID: <20101203192439.7AF7BEE9E5@mail.python.org> Author: martin.v.loewis Date: Fri Dec 3 20:24:39 2010 New Revision: 86989 Log: Fix merging glitches. Expose version of structseq under limited API. Modified: python/branches/pep-0384/Include/structseq.h python/branches/pep-0384/Include/unicodeobject.h python/branches/pep-0384/Modules/_ctypes/cfield.c python/branches/pep-0384/Modules/_testcapimodule.c python/branches/pep-0384/Objects/rangeobject.c python/branches/pep-0384/Objects/structseq.c python/branches/pep-0384/Objects/unicodeobject.c Modified: python/branches/pep-0384/Include/structseq.h ============================================================================== --- python/branches/pep-0384/Include/structseq.h (original) +++ python/branches/pep-0384/Include/structseq.h Fri Dec 3 20:24:39 2010 @@ -21,18 +21,25 @@ extern char* PyStructSequence_UnnamedField; +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc); +#endif +PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc); PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); +#ifndef Py_LIMITED_API typedef PyTupleObject PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ #define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) #define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#endif +PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); +PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t); #ifdef __cplusplus } Modified: python/branches/pep-0384/Include/unicodeobject.h ============================================================================== --- python/branches/pep-0384/Include/unicodeobject.h (original) +++ python/branches/pep-0384/Include/unicodeobject.h Fri Dec 3 20:24:39 2010 @@ -320,6 +320,7 @@ _Py_ascii_whitespace (see below) with an inlined check. */ +#ifndef Py_LIMITED_API #define Py_UNICODE_ISSPACE(ch) \ ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) @@ -1644,7 +1645,6 @@ const Py_UNICODE *s, Py_UNICODE c ); -#endif /* Py_LIMITED_API */ /* Create a copy of a unicode string ending with a nul character. Return NULL and raise a MemoryError exception on memory allocation failure, otherwise @@ -1653,6 +1653,7 @@ PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( PyObject *unicode ); +#endif /* Py_LIMITED_API */ #ifdef __cplusplus } Modified: python/branches/pep-0384/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/pep-0384/Modules/_ctypes/cfield.c (original) +++ python/branches/pep-0384/Modules/_ctypes/cfield.c Fri Dec 3 20:24:39 2010 @@ -1214,7 +1214,7 @@ } else Py_INCREF(value); - len = PyUnicode_AsWideChar((PyUnicodeObject *)value, chars, 2); + len = PyUnicode_AsWideChar(value, chars, 2); if (len != 1) { Py_DECREF(value); PyErr_SetString(PyExc_TypeError, Modified: python/branches/pep-0384/Modules/_testcapimodule.c ============================================================================== --- python/branches/pep-0384/Modules/_testcapimodule.c (original) +++ python/branches/pep-0384/Modules/_testcapimodule.c Fri Dec 3 20:24:39 2010 @@ -1398,7 +1398,7 @@ if (buffer == NULL) return PyErr_NoMemory(); - size = PyUnicode_AsWideChar((PyUnicodeObject*)unicode, buffer, buflen); + size = PyUnicode_AsWideChar(unicode, buffer, buflen); if (size == -1) { PyMem_Free(buffer); return NULL; Modified: python/branches/pep-0384/Objects/rangeobject.c ============================================================================== --- python/branches/pep-0384/Objects/rangeobject.c (original) +++ python/branches/pep-0384/Objects/rangeobject.c Fri Dec 3 20:24:39 2010 @@ -431,7 +431,6 @@ return range_item(self, i); } if (PySlice_Check(item)) { - PySliceObject *slice = (PySliceObject*)item; Py_ssize_t start, stop, step, len, rlen; rangeobject *result; PyObject *substart = NULL, *substep = NULL, *substop = NULL; @@ -441,7 +440,7 @@ return NULL; } - if (PySlice_GetIndicesEx(slice, rlen, + if (PySlice_GetIndicesEx(item, rlen, &start, &stop, &step, &len) < 0) { return NULL; } @@ -450,7 +449,7 @@ Py_INCREF(substep); } else { /* NB: slice step != Py_None here */ - substep = PyNumber_Multiply(self->step, slice->step); + substep = PyNumber_Multiply(self->step, ((PySliceObject*)item)->step); if (substep == NULL) goto fail; } Modified: python/branches/pep-0384/Objects/structseq.c ============================================================================== --- python/branches/pep-0384/Objects/structseq.c (original) +++ python/branches/pep-0384/Objects/structseq.c Fri Dec 3 20:24:39 2010 @@ -43,6 +43,18 @@ return (PyObject*)obj; } +void +PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v) +{ + PyStructSequence_SET_ITEM(op, i, v); +} + +PyObject* +PyStructSequence_GetItem(PyObject* op, Py_ssize_t i) +{ + return PyStructSequence_GET_ITEM(op, i); +} + static void structseq_dealloc(PyStructSequence *obj) { @@ -365,3 +377,11 @@ SET_DICT_FROM_INT(real_length_key, n_members); SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); } + +PyTypeObject* +PyStructSequence_NewType(PyStructSequence_Desc *desc) +{ + PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + PyStructSequence_InitType(result, desc); + return result; +} Modified: python/branches/pep-0384/Objects/unicodeobject.c ============================================================================== --- python/branches/pep-0384/Objects/unicodeobject.c (original) +++ python/branches/pep-0384/Objects/unicodeobject.c Fri Dec 3 20:24:39 2010 @@ -9222,7 +9222,7 @@ Py_UNICODE* result_buf; PyObject* result; - if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self), + if (PySlice_GetIndicesEx(item, PyUnicode_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } From python-checkins at python.org Fri Dec 3 20:24:49 2010 From: python-checkins at python.org (eric.araujo) Date: Fri, 3 Dec 2010 20:24:49 +0100 (CET) Subject: [Python-checkins] r86990 - in python/branches/release27-maint: Lib/argparse.py Misc/NEWS Message-ID: <20101203192449.F32A5EE9D0@mail.python.org> Author: eric.araujo Date: Fri Dec 3 20:24:49 2010 New Revision: 86990 Log: Merged revisions 86985 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86985 | eric.araujo | 2010-12-03 20:19:17 +0100 (ven., 03 d?c. 2010) | 5 lines Fix incorrect use of gettext in argparse (#10497). Steven, the maintainer of argparse, agreed to have this committed without tests for now, since the fix is obvious. See the bug log. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/argparse.py python/branches/release27-maint/Misc/NEWS Modified: python/branches/release27-maint/Lib/argparse.py ============================================================================== --- python/branches/release27-maint/Lib/argparse.py (original) +++ python/branches/release27-maint/Lib/argparse.py Fri Dec 3 20:24:49 2010 @@ -1080,7 +1080,7 @@ parser = self._name_parser_map[parser_name] except KeyError: tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)' % tup) + msg = _('unknown parser %r (choices: %s)') % tup raise ArgumentError(self, msg) # parse all the remaining options into the namespace @@ -1121,7 +1121,7 @@ elif 'w' in self._mode: return _sys.stdout else: - msg = _('argument "-" with mode %r' % self._mode) + msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) # all other arguments are used as file names Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Fri Dec 3 20:24:49 2010 @@ -1,4 +1,4 @@ -+++++++++++ +:xq Python News +++++++++++ @@ -13,6 +13,8 @@ Library ------- +- Issue #10497: Fix incorrect use of gettext in argparse. + - Issue #10464: netrc now correctly handles lines with embedded '#' characters. From python-checkins at python.org Fri Dec 3 20:31:20 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Dec 2010 20:31:20 +0100 (CET) Subject: [Python-checkins] r86991 - python/branches/pep-0384/PC/python3.def Message-ID: <20101203193120.37569EE9C3@mail.python.org> Author: martin.v.loewis Date: Fri Dec 3 20:31:20 2010 New Revision: 86991 Log: Export structseq functions. Modified: python/branches/pep-0384/PC/python3.def Modified: python/branches/pep-0384/PC/python3.def ============================================================================== --- python/branches/pep-0384/PC/python3.def (original) +++ python/branches/pep-0384/PC/python3.def Fri Dec 3 20:31:20 2010 @@ -481,6 +481,10 @@ PySlice_Type=python32.PySlice_Type DATA PySortWrapper_Type=python32.PySortWrapper_Type DATA PyState_FindModule=python32.PyState_FindModule + PyStructSequence_GetItem=python32.PyStructSequence_GetItem + PyStructSequence_New=python32.PyStructSequence_New + PyStructSequence_NewType=python32.PyStructSequence_NewType + PyStructSequence_SetItem=python32.PyStructSequence_SetItem PySuper_Type=python32.PySuper_Type DATA PySys_AddWarnOption=python32.PySys_AddWarnOption PySys_AddWarnOptionUnicode=python32.PySys_AddWarnOptionUnicode From python-checkins at python.org Fri Dec 3 20:31:52 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 3 Dec 2010 20:31:52 +0100 (CET) Subject: [Python-checkins] r86992 - in python/branches/release27-maint: Doc/library/io.rst Lib/test/test_io.py Misc/NEWS Modules/_io/bufferedio.c Message-ID: <20101203193152.AAB0FEE9D1@mail.python.org> Author: antoine.pitrou Date: Fri Dec 3 20:31:52 2010 New Revision: 86992 Log: Merged revisions 86981,86984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86981 | antoine.pitrou | 2010-12-03 19:41:39 +0100 (ven., 03 d?c. 2010) | 5 lines Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. ........ r86984 | antoine.pitrou | 2010-12-03 20:14:17 +0100 (ven., 03 d?c. 2010) | 3 lines Add an "advanced topics" section to the io doc. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Doc/library/io.rst python/branches/release27-maint/Lib/test/test_io.py python/branches/release27-maint/Misc/NEWS python/branches/release27-maint/Modules/_io/bufferedio.c Modified: python/branches/release27-maint/Doc/library/io.rst ============================================================================== --- python/branches/release27-maint/Doc/library/io.rst (original) +++ python/branches/release27-maint/Doc/library/io.rst Fri Dec 3 20:31:52 2010 @@ -515,8 +515,8 @@ Buffered Streams ---------------- -In many situations, buffered I/O streams will provide higher performance -(bandwidth and latency) than raw I/O streams. Their API is also more usable. +Buffered I/O streams provide a higher-level interface to an I/O device +than raw I/O does. .. class:: BytesIO([initial_bytes]) @@ -776,8 +776,72 @@ # .getvalue() will now raise an exception. output.close() + .. class:: IncrementalNewlineDecoder A helper codec that decodes newlines for universal newlines mode. It inherits :class:`codecs.IncrementalDecoder`. + +Advanced topics +--------------- + +Here we will discuss several advanced topics pertaining to the concrete +I/O implementations described above. + +Performance +^^^^^^^^^^^ + +Binary I/O +"""""""""" + +By reading and writing only large chunks of data even when the user asks +for a single byte, buffered I/O is designed to hide any inefficiency in +calling and executing the operating system's unbuffered I/O routines. The +gain will vary very much depending on the OS and the kind of I/O which is +performed (for example, on some contemporary OSes such as Linux, unbuffered +disk I/O can be as fast as buffered I/O). The bottom line, however, is +that buffered I/O will offer you predictable performance regardless of the +platform and the backing device. Therefore, it is most always preferable to +use buffered I/O rather than unbuffered I/O. + +Text I/O +"""""""" + +Text I/O over a binary storage (such as a file) is significantly slower than +binary I/O over the same storage, because it implies conversions from +unicode to binary data using a character codec. This can become noticeable +if you handle huge amounts of text data (for example very large log files). + +:class:`StringIO`, however, is a native in-memory unicode container and will +exhibit similar speed to :class:`BytesIO`. + +Multi-threading +^^^^^^^^^^^^^^^ + +:class:`FileIO` objects are thread-safe to the extent that the operating +system calls (such as ``read(2)`` under Unix) they are wrapping are thread-safe +too. + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +protect their internal structures using a lock; it is therefore safe to call +them from multiple threads at once. + +:class:`TextIOWrapper` objects are not thread-safe. + +Reentrancy +^^^^^^^^^^ + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +are not reentrant. While reentrant calls will not happen in normal situations, +they can arise if you are doing I/O in a :mod:`signal` handler. If it is +attempted to enter a buffered object again while already being accessed +*from the same thread*, then a :exc:`RuntimeError` is raised. + +The above implicitly extends to text files, since the :func:`open()` +function will wrap a buffered object inside a :class:`TextIOWrapper`. This +includes standard streams and therefore affects the built-in function +:func:`print()` as well. + Modified: python/branches/release27-maint/Lib/test/test_io.py ============================================================================== --- python/branches/release27-maint/Lib/test/test_io.py (original) +++ python/branches/release27-maint/Lib/test/test_io.py Fri Dec 3 20:31:52 2010 @@ -2561,12 +2561,50 @@ def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") + def check_reentrant_write(self, data, **fdopen_kwargs): + def on_alarm(*args): + # Will be called reentrantly from the same thread + wio.write(data) + 1/0 + signal.signal(signal.SIGALRM, on_alarm) + r, w = os.pipe() + wio = self.io.open(w, **fdopen_kwargs) + try: + signal.alarm(1) + # Either the reentrant call to wio.write() fails with RuntimeError, + # or the signal handler raises ZeroDivisionError. + with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm: + while 1: + for i in range(100): + wio.write(data) + wio.flush() + # Make sure the buffer doesn't fill up and block further writes + os.read(r, len(data) * 100) + exc = cm.exception + if isinstance(exc, RuntimeError): + self.assertTrue(str(exc).startswith("reentrant call"), str(exc)) + finally: + wio.close() + os.close(r) + + def test_reentrant_write_buffered(self): + self.check_reentrant_write(b"xy", mode="wb") + + def test_reentrant_write_text(self): + self.check_reentrant_write("xy", mode="w", encoding="ascii") + + class CSignalsTest(SignalsTest): io = io class PySignalsTest(SignalsTest): io = pyio + # Handling reentrancy issues would slow down _pyio even more, so the + # tests are disabled. + test_reentrant_write_buffered = None + test_reentrant_write_text = None + def test_main(): tests = (CIOTest, PyIOTest, Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Fri Dec 3 20:31:52 2010 @@ -1,4 +1,3 @@ -:xq Python News +++++++++++ @@ -13,6 +12,10 @@ Library ------- +- Issue #10478: Reentrant calls inside buffered IO objects (for example by + way of a signal handler) now raise a RuntimeError instead of freezing the + current process. + - Issue #10497: Fix incorrect use of gettext in argparse. - Issue #10464: netrc now correctly handles lines with embedded '#' characters. Modified: python/branches/release27-maint/Modules/_io/bufferedio.c ============================================================================== --- python/branches/release27-maint/Modules/_io/bufferedio.c (original) +++ python/branches/release27-maint/Modules/_io/bufferedio.c Fri Dec 3 20:31:52 2010 @@ -224,6 +224,7 @@ #ifdef WITH_THREAD PyThread_type_lock lock; + volatile long owner; #endif Py_ssize_t buffer_size; @@ -259,17 +260,39 @@ /* These macros protect the buffered object against concurrent operations. */ #ifdef WITH_THREAD -#define ENTER_BUFFERED(self) \ - if (!PyThread_acquire_lock(self->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS \ + +static int +_enter_buffered_busy(buffered *self) +{ + if (self->owner == PyThread_get_thread_ident()) { + PyObject *r = PyObject_Repr((PyObject *) self); + if (r != NULL) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s", + PyString_AS_STRING(r)); + Py_DECREF(r); + } + return 0; } + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + Py_END_ALLOW_THREADS + return 1; +} + +#define ENTER_BUFFERED(self) \ + ( (PyThread_acquire_lock(self->lock, 0) ? \ + 1 : _enter_buffered_busy(self)) \ + && (self->owner = PyThread_get_thread_ident(), 1) ) #define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); + do { \ + self->owner = 0; \ + PyThread_release_lock(self->lock); \ + } while(0); + #else -#define ENTER_BUFFERED(self) +#define ENTER_BUFFERED(self) 1 #define LEAVE_BUFFERED(self) #endif @@ -425,7 +448,8 @@ int r; CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; r = buffered_closed(self); if (r < 0) @@ -438,7 +462,8 @@ /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (res == NULL) { goto end; } @@ -643,6 +668,7 @@ PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } + self->owner = 0; #endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ @@ -669,7 +695,8 @@ CHECK_INITIALIZED(self) CHECK_CLOSED(self, "flush of closed file") - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); if (res != NULL && self->readable) { /* Rewind the raw stream so that its position corresponds to @@ -696,7 +723,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -731,7 +759,8 @@ if (n == -1) { /* The number of bytes is unspecified, read until the end of stream */ - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_all(self); LEAVE_BUFFERED(self) } @@ -739,7 +768,8 @@ res = _bufferedreader_read_fast(self, n); if (res == Py_None) { Py_DECREF(res); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_generic(self, n); LEAVE_BUFFERED(self) } @@ -767,7 +797,8 @@ if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -823,7 +854,8 @@ /* TODO: use raw.readinto() instead! */ if (self->writable) { - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); LEAVE_BUFFERED(self) if (res == NULL) @@ -867,7 +899,8 @@ goto end_unlocked; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + goto end_unlocked; /* Now we try to get some more from the raw stream */ if (self->writable) { @@ -1017,7 +1050,8 @@ } } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { @@ -1055,7 +1089,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 0); @@ -1715,7 +1750,10 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) { + PyBuffer_Release(&buf); + return NULL; + } /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { From python-checkins at python.org Fri Dec 3 20:41:00 2010 From: python-checkins at python.org (eric.araujo) Date: Fri, 3 Dec 2010 20:41:00 +0100 (CET) Subject: [Python-checkins] r86993 - in python/branches/py3k: Lib/argparse.py Misc/NEWS Message-ID: <20101203194100.954ACEE986@mail.python.org> Author: eric.araujo Date: Fri Dec 3 20:41:00 2010 New Revision: 86993 Log: Allow translators to reorder placeholders in localizable messages from argparse (#10528). There is no unit test; I checked with xgettext that no more warnings were emitted. Steven approved the change. Modified: python/branches/py3k/Lib/argparse.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/argparse.py ============================================================================== --- python/branches/py3k/Lib/argparse.py (original) +++ python/branches/py3k/Lib/argparse.py Fri Dec 3 20:41:00 2010 @@ -1079,8 +1079,9 @@ try: parser = self._name_parser_map[parser_name] except KeyError: - tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)') % tup + args = {'parser_name': parser_name, + 'choices': ', '.join(self._name_parser_map)} + msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) # parse all the remaining options into the namespace @@ -1380,10 +1381,11 @@ for option_string in args: # error on strings that don't start with an appropriate prefix if not option_string[0] in self.prefix_chars: - msg = _('invalid option string %r: ' - 'must start with a character %r') - tup = option_string, self.prefix_chars - raise ValueError(msg % tup) + args = {'option': option_string, + 'prefix_chars': self.prefix_chars} + msg = _('invalid option string %(option)r: ' + 'must start with a character %(prefix_chars)r') + raise ValueError(msg % args) # strings starting with two prefix characters are long options option_strings.append(option_string) @@ -2049,8 +2051,9 @@ if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, explicit_arg in option_tuples]) - tup = arg_string, options - self.error(_('ambiguous option: %s could match %s') % tup) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) # if exactly one action matched, this segmentation is good, # so return the parsed action @@ -2229,8 +2232,9 @@ # TypeErrors or ValueErrors also indicate errors except (TypeError, ValueError): name = getattr(action.type, '__name__', repr(action.type)) - msg = _('invalid %s value: %r') - raise ArgumentError(action, msg % (name, arg_string)) + args = {'type': name, 'value': arg_string} + msg = _('invalid %(type)s value: %(value)r') + raise ArgumentError(action, msg % args) # return the converted value return result @@ -2238,9 +2242,10 @@ def _check_value(self, action, value): # converted value must be one of the choices (if specified) if action.choices is not None and value not in action.choices: - tup = value, ', '.join(map(repr, action.choices)) - msg = _('invalid choice: %r (choose from %s)') % tup - raise ArgumentError(action, msg) + args = {'value': value, + 'choices': ', '.join(map(repr, action.choices))} + msg = _('invalid choice: %(value)r (choose from %(choices)s)') + raise ArgumentError(action, msg % args) # ======================= # Help-formatting methods @@ -2332,4 +2337,5 @@ should either exit or raise an exception. """ self.print_usage(_sys.stderr) - self.exit(2, _('%s: error: %s\n') % (self.prog, message)) + args = {'prog': self.prog, 'message': message} + self.exit(2, _('%(prog)s: error: %(message)s\n') % args) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 20:41:00 2010 @@ -35,6 +35,9 @@ Library ------- +- Issue #10528: Allow translators to reorder placeholders in localizable + messages from argparse. + - Issue #10497: Fix incorrect use of gettext in argparse. - Issue #10478: Reentrant calls inside buffered IO objects (for example by From python-checkins at python.org Fri Dec 3 20:53:40 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Dec 2010 20:53:40 +0100 (CET) Subject: [Python-checkins] r86994 - in python/branches/pep-0384: Include/modsupport.h Objects/moduleobject.c Python/dynload_shlib.c Message-ID: <20101203195340.D86C2EE98E@mail.python.org> Author: martin.v.loewis Date: Fri Dec 3 20:53:40 2010 New Revision: 86994 Log: Incorporate suggestions from PEP 3149: - define PYTHON_ABI_VERSION - recognize abi3 as a tag. Modified: python/branches/pep-0384/Include/modsupport.h python/branches/pep-0384/Objects/moduleobject.c python/branches/pep-0384/Python/dynload_shlib.c Modified: python/branches/pep-0384/Include/modsupport.h ============================================================================== --- python/branches/pep-0384/Include/modsupport.h (original) +++ python/branches/pep-0384/Include/modsupport.h Fri Dec 3 20:53:40 2010 @@ -94,6 +94,12 @@ 9-Jan-1995 GvR Initial version (incompatible with older API) */ +/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of + Python 3, it will stay at the value of 3; changes to the limited API + must be performed in a strictly backwards-compatible manner. */ +#define PYTHON_ABI_VERSION 3 +#define PYTHON_ABI_STRING "3" + #ifdef Py_TRACE_REFS /* When we are tracing reference counts, rename PyModule_Create2 so modules compiled with incompatible settings will generate a @@ -104,8 +110,13 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, int apiver); +#ifdef Py_LIMITED_API +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_ABI_VERSION) +#else #define PyModule_Create(module) \ PyModule_Create2(module, PYTHON_API_VERSION) +#endif #ifndef Py_LIMITED_API PyAPI_DATA(char *) _Py_PackageContext; Modified: python/branches/pep-0384/Objects/moduleobject.c ============================================================================== --- python/branches/pep-0384/Objects/moduleobject.c (original) +++ python/branches/pep-0384/Objects/moduleobject.c Fri Dec 3 20:53:40 2010 @@ -74,7 +74,7 @@ module->m_base.m_index = max_module_number; } name = module->m_name; - if (module_api_version != PYTHON_API_VERSION) { + if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { int err; err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "Python C API version mismatch for module %.100s: " Modified: python/branches/pep-0384/Python/dynload_shlib.c ============================================================================== --- python/branches/pep-0384/Python/dynload_shlib.c (original) +++ python/branches/pep-0384/Python/dynload_shlib.c Fri Dec 3 20:53:40 2010 @@ -53,6 +53,8 @@ #else /* !__VMS */ {"." SOABI ".so", "rb", C_EXTENSION}, {"module." SOABI ".so", "rb", C_EXTENSION}, + {".abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION}, + {"module.abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION}, {".so", "rb", C_EXTENSION}, {"module.so", "rb", C_EXTENSION}, #endif /* __VMS */ From python-checkins at python.org Fri Dec 3 20:54:31 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Dec 2010 20:54:31 +0100 (CET) Subject: [Python-checkins] r86995 - in python/branches/pep-0384: Doc/library/difflib.rst Doc/library/io.rst Lib/argparse.py Lib/difflib.py Lib/test/test_io.py Lib/test/test_unittest.py Misc/NEWS Modules/_io/bufferedio.c Message-ID: <20101203195431.1E880EE98E@mail.python.org> Author: martin.v.loewis Date: Fri Dec 3 20:54:30 2010 New Revision: 86995 Log: Merged revisions 86981,86983-86986,86993 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r86981 | antoine.pitrou | 2010-12-03 19:41:39 +0100 (Fr, 03 Dez 2010) | 5 lines Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. ........ r86983 | terry.reedy | 2010-12-03 19:57:42 +0100 (Fr, 03 Dez 2010) | 1 line ........ r86984 | antoine.pitrou | 2010-12-03 20:14:17 +0100 (Fr, 03 Dez 2010) | 3 lines Add an "advanced topics" section to the io doc. ........ r86985 | eric.araujo | 2010-12-03 20:19:17 +0100 (Fr, 03 Dez 2010) | 5 lines Fix incorrect use of gettext in argparse (#10497). Steven, the maintainer of argparse, agreed to have this committed without tests for now, since the fix is obvious. See the bug log. ........ r86986 | michael.foord | 2010-12-03 20:20:44 +0100 (Fr, 03 Dez 2010) | 1 line Fix so that test.test_unittest can be executed by unittest and not just regrtest ........ r86993 | eric.araujo | 2010-12-03 20:41:00 +0100 (Fr, 03 Dez 2010) | 7 lines Allow translators to reorder placeholders in localizable messages from argparse (#10528). There is no unit test; I checked with xgettext that no more warnings were emitted. Steven approved the change. ........ Modified: python/branches/pep-0384/ (props changed) python/branches/pep-0384/Doc/library/difflib.rst python/branches/pep-0384/Doc/library/io.rst python/branches/pep-0384/Lib/argparse.py python/branches/pep-0384/Lib/difflib.py python/branches/pep-0384/Lib/test/test_io.py python/branches/pep-0384/Lib/test/test_unittest.py python/branches/pep-0384/Misc/NEWS python/branches/pep-0384/Modules/_io/bufferedio.c Modified: python/branches/pep-0384/Doc/library/difflib.rst ============================================================================== --- python/branches/pep-0384/Doc/library/difflib.rst (original) +++ python/branches/pep-0384/Doc/library/difflib.rst Fri Dec 3 20:54:30 2010 @@ -358,6 +358,16 @@ .. versionadded:: 3.2 The *autojunk* parameter. + SequenceMatcher objects get three data attributes: *bjunk* is the + set of elements of b for which *isjunk* is True; *bpopular* is the set of non- + junk elements considered popular by the heuristic (if it is not disabled); + *b2j* is a dict mapping the remaining elements of b to a list of positions where + they occur. All three are reset whenever *b* is reset with :meth:`set_seqs` + or :meth:`set_seq2`. + +.. versionadded:: 3.2 + The *bjunk* and *bpopular* attributes. + :class:`SequenceMatcher` objects have the following methods: @@ -538,7 +548,7 @@ SequenceMatcher Examples ------------------------ -This example compares two strings, considering blanks to be "junk:" +This example compares two strings, considering blanks to be "junk": >>> s = SequenceMatcher(lambda x: x == " ", ... "private Thread currentThread;", Modified: python/branches/pep-0384/Doc/library/io.rst ============================================================================== --- python/branches/pep-0384/Doc/library/io.rst (original) +++ python/branches/pep-0384/Doc/library/io.rst Fri Dec 3 20:54:30 2010 @@ -54,12 +54,6 @@ The text stream API is described in detail in the documentation for the :class:`TextIOBase`. -.. note:: - - Text I/O over a binary storage (such as a file) is significantly slower than - binary I/O over the same storage. This can become noticeable if you handle - huge amounts of text data (for example very large log files). - Binary I/O ^^^^^^^^^^ @@ -506,8 +500,8 @@ Buffered Streams ^^^^^^^^^^^^^^^^ -In many situations, buffered I/O streams will provide higher performance -(bandwidth and latency) than raw I/O streams. Their API is also more usable. +Buffered I/O streams provide a higher-level interface to an I/O device +than raw I/O does. .. class:: BytesIO([initial_bytes]) @@ -784,14 +778,72 @@ # .getvalue() will now raise an exception. output.close() - .. note:: - - :class:`StringIO` uses a native text storage and doesn't suffer from the - performance issues of other text streams, such as those based on - :class:`TextIOWrapper`. .. class:: IncrementalNewlineDecoder A helper codec that decodes newlines for universal newlines mode. It inherits :class:`codecs.IncrementalDecoder`. + +Advanced topics +--------------- + +Here we will discuss several advanced topics pertaining to the concrete +I/O implementations described above. + +Performance +^^^^^^^^^^^ + +Binary I/O +"""""""""" + +By reading and writing only large chunks of data even when the user asks +for a single byte, buffered I/O is designed to hide any inefficiency in +calling and executing the operating system's unbuffered I/O routines. The +gain will vary very much depending on the OS and the kind of I/O which is +performed (for example, on some contemporary OSes such as Linux, unbuffered +disk I/O can be as fast as buffered I/O). The bottom line, however, is +that buffered I/O will offer you predictable performance regardless of the +platform and the backing device. Therefore, it is most always preferable to +use buffered I/O rather than unbuffered I/O. + +Text I/O +"""""""" + +Text I/O over a binary storage (such as a file) is significantly slower than +binary I/O over the same storage, because it implies conversions from +unicode to binary data using a character codec. This can become noticeable +if you handle huge amounts of text data (for example very large log files). + +:class:`StringIO`, however, is a native in-memory unicode container and will +exhibit similar speed to :class:`BytesIO`. + +Multi-threading +^^^^^^^^^^^^^^^ + +:class:`FileIO` objects are thread-safe to the extent that the operating +system calls (such as ``read(2)`` under Unix) they are wrapping are thread-safe +too. + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +protect their internal structures using a lock; it is therefore safe to call +them from multiple threads at once. + +:class:`TextIOWrapper` objects are not thread-safe. + +Reentrancy +^^^^^^^^^^ + +Binary buffered objects (instances of :class:`BufferedReader`, +:class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) +are not reentrant. While reentrant calls will not happen in normal situations, +they can arise if you are doing I/O in a :mod:`signal` handler. If it is +attempted to enter a buffered object again while already being accessed +*from the same thread*, then a :exc:`RuntimeError` is raised. + +The above implicitly extends to text files, since the :func:`open()` +function will wrap a buffered object inside a :class:`TextIOWrapper`. This +includes standard streams and therefore affects the built-in function +:func:`print()` as well. + Modified: python/branches/pep-0384/Lib/argparse.py ============================================================================== --- python/branches/pep-0384/Lib/argparse.py (original) +++ python/branches/pep-0384/Lib/argparse.py Fri Dec 3 20:54:30 2010 @@ -1079,8 +1079,9 @@ try: parser = self._name_parser_map[parser_name] except KeyError: - tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)' % tup) + args = {'parser_name': parser_name, + 'choices': ', '.join(self._name_parser_map)} + msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args raise ArgumentError(self, msg) # parse all the remaining options into the namespace @@ -1121,7 +1122,7 @@ elif 'w' in self._mode: return _sys.stdout else: - msg = _('argument "-" with mode %r' % self._mode) + msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) # all other arguments are used as file names @@ -1380,10 +1381,11 @@ for option_string in args: # error on strings that don't start with an appropriate prefix if not option_string[0] in self.prefix_chars: - msg = _('invalid option string %r: ' - 'must start with a character %r') - tup = option_string, self.prefix_chars - raise ValueError(msg % tup) + args = {'option': option_string, + 'prefix_chars': self.prefix_chars} + msg = _('invalid option string %(option)r: ' + 'must start with a character %(prefix_chars)r') + raise ValueError(msg % args) # strings starting with two prefix characters are long options option_strings.append(option_string) @@ -2049,8 +2051,9 @@ if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, explicit_arg in option_tuples]) - tup = arg_string, options - self.error(_('ambiguous option: %s could match %s') % tup) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) # if exactly one action matched, this segmentation is good, # so return the parsed action @@ -2229,8 +2232,9 @@ # TypeErrors or ValueErrors also indicate errors except (TypeError, ValueError): name = getattr(action.type, '__name__', repr(action.type)) - msg = _('invalid %s value: %r') - raise ArgumentError(action, msg % (name, arg_string)) + args = {'type': name, 'value': arg_string} + msg = _('invalid %(type)s value: %(value)r') + raise ArgumentError(action, msg % args) # return the converted value return result @@ -2238,9 +2242,10 @@ def _check_value(self, action, value): # converted value must be one of the choices (if specified) if action.choices is not None and value not in action.choices: - tup = value, ', '.join(map(repr, action.choices)) - msg = _('invalid choice: %r (choose from %s)') % tup - raise ArgumentError(action, msg) + args = {'value': value, + 'choices': ', '.join(map(repr, action.choices))} + msg = _('invalid choice: %(value)r (choose from %(choices)s)') + raise ArgumentError(action, msg % args) # ======================= # Help-formatting methods @@ -2332,4 +2337,5 @@ should either exit or raise an exception. """ self.print_usage(_sys.stderr) - self.exit(2, _('%s: error: %s\n') % (self.prog, message)) + args = {'prog': self.prog, 'message': message} + self.exit(2, _('%(prog)s: error: %(message)s\n') % args) Modified: python/branches/pep-0384/Lib/difflib.py ============================================================================== --- python/branches/pep-0384/Lib/difflib.py (original) +++ python/branches/pep-0384/Lib/difflib.py Fri Dec 3 20:54:30 2010 @@ -213,6 +213,10 @@ # (at least 200 elements) and x accounts for more than 1 + 1% of # its elements (when autojunk is enabled). # DOES NOT WORK for x in a! + # bjunk + # the items in b for which isjunk is True. + # bpopular + # nonjunk items in b treated as junk by the heuristic (if used). self.isjunk = isjunk self.a = self.b = None @@ -321,7 +325,7 @@ indices.append(i) # Purge junk elements - junk = set() + self.bjunk = junk = set() isjunk = self.isjunk if isjunk: for elt in list(b2j.keys()): # using list() since b2j is modified @@ -330,7 +334,7 @@ del b2j[elt] # Purge popular elements that are not junk - popular = set() + self.bpopular = popular = set() n = len(b) if self.autojunk and n >= 200: ntest = n // 100 + 1 Modified: python/branches/pep-0384/Lib/test/test_io.py ============================================================================== --- python/branches/pep-0384/Lib/test/test_io.py (original) +++ python/branches/pep-0384/Lib/test/test_io.py Fri Dec 3 20:54:30 2010 @@ -2653,12 +2653,50 @@ def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") + def check_reentrant_write(self, data, **fdopen_kwargs): + def on_alarm(*args): + # Will be called reentrantly from the same thread + wio.write(data) + 1/0 + signal.signal(signal.SIGALRM, on_alarm) + r, w = os.pipe() + wio = self.io.open(w, **fdopen_kwargs) + try: + signal.alarm(1) + # Either the reentrant call to wio.write() fails with RuntimeError, + # or the signal handler raises ZeroDivisionError. + with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm: + while 1: + for i in range(100): + wio.write(data) + wio.flush() + # Make sure the buffer doesn't fill up and block further writes + os.read(r, len(data) * 100) + exc = cm.exception + if isinstance(exc, RuntimeError): + self.assertTrue(str(exc).startswith("reentrant call"), str(exc)) + finally: + wio.close() + os.close(r) + + def test_reentrant_write_buffered(self): + self.check_reentrant_write(b"xy", mode="wb") + + def test_reentrant_write_text(self): + self.check_reentrant_write("xy", mode="w", encoding="ascii") + + class CSignalsTest(SignalsTest): io = io class PySignalsTest(SignalsTest): io = pyio + # Handling reentrancy issues would slow down _pyio even more, so the + # tests are disabled. + test_reentrant_write_buffered = None + test_reentrant_write_text = None + def test_main(): tests = (CIOTest, PyIOTest, Modified: python/branches/pep-0384/Lib/test/test_unittest.py ============================================================================== --- python/branches/pep-0384/Lib/test/test_unittest.py (original) +++ python/branches/pep-0384/Lib/test/test_unittest.py Fri Dec 3 20:54:30 2010 @@ -4,8 +4,13 @@ def test_main(): + # used by regrtest support.run_unittest(unittest.test.suite()) support.reap_children() +def load_tests(*_): + # used by unittest + return unittest.test.suite() + if __name__ == "__main__": test_main() Modified: python/branches/pep-0384/Misc/NEWS ============================================================================== --- python/branches/pep-0384/Misc/NEWS (original) +++ python/branches/pep-0384/Misc/NEWS Fri Dec 3 20:54:30 2010 @@ -35,6 +35,15 @@ Library ------- +- Issue #10528: Allow translators to reorder placeholders in localizable + messages from argparse. + +- Issue #10497: Fix incorrect use of gettext in argparse. + +- Issue #10478: Reentrant calls inside buffered IO objects (for example by + way of a signal handler) now raise a RuntimeError instead of freezing the + current process. + - logging: Added getLogRecordFactory/setLogRecordFactory with docs and tests. - Issue #10549: Fix pydoc traceback when text-documenting certain classes. Modified: python/branches/pep-0384/Modules/_io/bufferedio.c ============================================================================== --- python/branches/pep-0384/Modules/_io/bufferedio.c (original) +++ python/branches/pep-0384/Modules/_io/bufferedio.c Fri Dec 3 20:54:30 2010 @@ -225,6 +225,7 @@ #ifdef WITH_THREAD PyThread_type_lock lock; + volatile long owner; #endif Py_ssize_t buffer_size; @@ -260,17 +261,34 @@ /* These macros protect the buffered object against concurrent operations. */ #ifdef WITH_THREAD -#define ENTER_BUFFERED(self) \ - if (!PyThread_acquire_lock(self->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS \ + +static int +_enter_buffered_busy(buffered *self) +{ + if (self->owner == PyThread_get_thread_ident()) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %R", self); + return 0; } + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + Py_END_ALLOW_THREADS + return 1; +} + +#define ENTER_BUFFERED(self) \ + ( (PyThread_acquire_lock(self->lock, 0) ? \ + 1 : _enter_buffered_busy(self)) \ + && (self->owner = PyThread_get_thread_ident(), 1) ) #define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); + do { \ + self->owner = 0; \ + PyThread_release_lock(self->lock); \ + } while(0); + #else -#define ENTER_BUFFERED(self) +#define ENTER_BUFFERED(self) 1 #define LEAVE_BUFFERED(self) #endif @@ -444,7 +462,8 @@ int r; CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; r = buffered_closed(self); if (r < 0) @@ -465,7 +484,8 @@ /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (res == NULL) { goto end; } @@ -679,6 +699,7 @@ PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } + self->owner = 0; #endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ @@ -705,7 +726,8 @@ CHECK_INITIALIZED(self) CHECK_CLOSED(self, "flush of closed file") - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); if (res != NULL && self->readable) { /* Rewind the raw stream so that its position corresponds to @@ -732,7 +754,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -767,7 +790,8 @@ if (n == -1) { /* The number of bytes is unspecified, read until the end of stream */ - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_all(self); LEAVE_BUFFERED(self) } @@ -775,7 +799,8 @@ res = _bufferedreader_read_fast(self, n); if (res == Py_None) { Py_DECREF(res); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedreader_read_generic(self, n); LEAVE_BUFFERED(self) } @@ -803,7 +828,8 @@ if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); @@ -859,7 +885,8 @@ /* TODO: use raw.readinto() instead! */ if (self->writable) { - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; res = _bufferedwriter_flush_unlocked(self, 0); LEAVE_BUFFERED(self) if (res == NULL) @@ -903,7 +930,8 @@ goto end_unlocked; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + goto end_unlocked; /* Now we try to get some more from the raw stream */ if (self->writable) { @@ -1053,7 +1081,8 @@ } } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { @@ -1091,7 +1120,8 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) + return NULL; if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 0); @@ -1748,7 +1778,10 @@ return NULL; } - ENTER_BUFFERED(self) + if (!ENTER_BUFFERED(self)) { + PyBuffer_Release(&buf); + return NULL; + } /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { From python-checkins at python.org Fri Dec 3 20:56:42 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 3 Dec 2010 20:56:42 +0100 (CET) Subject: [Python-checkins] r86996 - python/branches/py3k/Doc/library/difflib.rst Message-ID: <20101203195642.316CCEE98E@mail.python.org> Author: georg.brandl Date: Fri Dec 3 20:56:42 2010 New Revision: 86996 Log: Fix indentation. Modified: python/branches/py3k/Doc/library/difflib.rst Modified: python/branches/py3k/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k/Doc/library/difflib.rst (original) +++ python/branches/py3k/Doc/library/difflib.rst Fri Dec 3 20:56:42 2010 @@ -365,12 +365,11 @@ they occur. All three are reset whenever *b* is reset with :meth:`set_seqs` or :meth:`set_seq2`. -.. versionadded:: 3.2 + .. versionadded:: 3.2 The *bjunk* and *bpopular* attributes. :class:`SequenceMatcher` objects have the following methods: - .. method:: set_seqs(a, b) Set the two sequences to be compared. From python-checkins at python.org Fri Dec 3 20:59:41 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 3 Dec 2010 20:59:41 +0100 (CET) Subject: [Python-checkins] r86997 - in python/branches/py3k: Lib/test/test_ssl.py Misc/NEWS Modules/_ssl.c Modules/socketmodule.c Modules/socketmodule.h Message-ID: <20101203195941.A9A1DEE98E@mail.python.org> Author: antoine.pitrou Date: Fri Dec 3 20:59:41 2010 New Revision: 86997 Log: Issue #10272: The ssl module now raises socket.timeout instead of a generic SSLError on socket timeouts. Modified: python/branches/py3k/Lib/test/test_ssl.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ssl.c python/branches/py3k/Modules/socketmodule.c python/branches/py3k/Modules/socketmodule.h Modified: python/branches/py3k/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ssl.py (original) +++ python/branches/py3k/Lib/test/test_ssl.py Fri Dec 3 20:59:41 2010 @@ -1499,7 +1499,7 @@ c.settimeout(0.2) c.connect((host, port)) # Will attempt handshake and time out - self.assertRaisesRegex(ssl.SSLError, "timed out", + self.assertRaisesRegex(socket.timeout, "timed out", ssl.wrap_socket, c) finally: c.close() @@ -1508,7 +1508,7 @@ c = ssl.wrap_socket(c) c.settimeout(0.2) # Will attempt handshake and time out - self.assertRaisesRegex(ssl.SSLError, "timed out", + self.assertRaisesRegex(socket.timeout, "timed out", c.connect, (host, port)) finally: c.close() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 20:59:41 2010 @@ -35,6 +35,9 @@ Library ------- +- Issue #10272: The ssl module now raises socket.timeout instead of a generic + SSLError on socket timeouts. + - Issue #10528: Allow translators to reorder placeholders in localizable messages from argparse. Modified: python/branches/py3k/Modules/_ssl.c ============================================================================== --- python/branches/py3k/Modules/_ssl.c (original) +++ python/branches/py3k/Modules/_ssl.c Fri Dec 3 20:59:41 2010 @@ -370,7 +370,7 @@ sockstate = SOCKET_OPERATION_OK; } if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, ERRSTR("The handshake operation timed out")); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { @@ -1075,7 +1075,7 @@ sockstate = check_socket_and_wait_for_timeout(sock, 1); if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { @@ -1104,7 +1104,7 @@ sockstate = SOCKET_OPERATION_OK; } if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { @@ -1211,7 +1211,7 @@ if (!count) { sockstate = check_socket_and_wait_for_timeout(sock, 0); if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The read operation timed out"); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { @@ -1245,7 +1245,7 @@ sockstate = SOCKET_OPERATION_OK; } if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The read operation timed out"); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -1340,10 +1340,10 @@ break; if (sockstate == SOCKET_HAS_TIMED_OUT) { if (ssl_err == SSL_ERROR_WANT_READ) - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The read operation timed out"); else - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(PySocketModule.timeout_error, "The write operation timed out"); goto error; } Modified: python/branches/py3k/Modules/socketmodule.c ============================================================================== --- python/branches/py3k/Modules/socketmodule.c (original) +++ python/branches/py3k/Modules/socketmodule.c Fri Dec 3 20:59:41 2010 @@ -4358,6 +4358,7 @@ PySocketModule_APIObject PySocketModuleAPI = { &sock_type, + NULL, NULL }; @@ -4425,6 +4426,7 @@ socket_error, NULL); if (socket_timeout == NULL) return NULL; + PySocketModuleAPI.timeout_error = socket_timeout; Py_INCREF(socket_timeout); PyModule_AddObject(m, "timeout", socket_timeout); Py_INCREF((PyObject *)&sock_type); Modified: python/branches/py3k/Modules/socketmodule.h ============================================================================== --- python/branches/py3k/Modules/socketmodule.h (original) +++ python/branches/py3k/Modules/socketmodule.h Fri Dec 3 20:59:41 2010 @@ -196,6 +196,7 @@ typedef struct { PyTypeObject *Sock_Type; PyObject *error; + PyObject *timeout_error; } PySocketModule_APIObject; #define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1) From python-checkins at python.org Fri Dec 3 21:14:32 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Dec 2010 21:14:32 +0100 (CET) Subject: [Python-checkins] r86998 - in python/branches/py3k: Doc/c-api/veryhigh.rst Doc/faq/extending.rst Doc/whatsnew/3.2.rst Include/Python.h Include/abstract.h Include/bytearrayobject.h Include/bytes_methods.h Include/bytesobject.h Include/cellobject.h Include/ceval.h Include/classobject.h Include/code.h Include/codecs.h Include/compile.h Include/complexobject.h Include/datetime.h Include/descrobject.h Include/dictobject.h Include/dtoa.h Include/eval.h Include/fileobject.h Include/floatobject.h Include/frameobject.h Include/funcobject.h Include/genobject.h Include/import.h Include/listobject.h Include/longintrepr.h Include/longobject.h Include/marshal.h Include/memoryobject.h Include/methodobject.h Include/modsupport.h Include/moduleobject.h Include/object.h Include/objimpl.h Include/parsetok.h Include/pyarena.h Include/pyatomic.h Include/pyctype.h Include/pydebug.h Include/pyerrors.h Include/pygetopt.h Include/pymath.h Include/pystate.h Include/pystrtod.h Include/pythonrun.h Include/pytime.h Include/setobject.h Include/sliceobject.h Include/structseq.h Include/symtable.h Include/sysmodule.h Include/timefuncs.h Include/token.h Include/traceback.h Include/tupleobject.h Include/typeslots.h Include/ucnhash.h Include/unicodeobject.h Include/warnings.h Include/weakrefobject.h Makefile.pre.in Misc/NEWS Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/_elementtree.c Modules/_testcapimodule.c Modules/arraymodule.c Modules/getpath.c Modules/mmapmodule.c Modules/xxlimited.c Objects/bytearrayobject.c Objects/bytesobject.c Objects/funcobject.c Objects/listobject.c Objects/memoryobject.c Objects/moduleobject.c Objects/object.c Objects/rangeobject.c Objects/sliceobject.c Objects/structseq.c Objects/tupleobject.c Objects/typeobject.c Objects/typeslots.inc Objects/typeslots.py Objects/unicodeobject.c PC/getpathp.c PC/pyconfig.h PC/python3.def PC/python3dll.c PCbuild/pcbuild.sln PCbuild/python3dll.vcproj PCbuild/xxlimited.vcproj Python/bltinmodule.c Python/ceval.c Python/dynload_shlib.c Python/dynload_win.c Python/import.c Python/pythonrun.c Tools/scripts/abitype.py setup.py Message-ID: <20101203201432.50B90EE9D7@mail.python.org> Author: martin.v.loewis Date: Fri Dec 3 21:14:31 2010 New Revision: 86998 Log: Merge branches/pep-0384. Added: python/branches/py3k/Include/typeslots.h python/branches/py3k/Modules/xxlimited.c python/branches/py3k/Objects/typeslots.inc python/branches/py3k/Objects/typeslots.py python/branches/py3k/PC/python3.def python/branches/py3k/PC/python3dll.c python/branches/py3k/PCbuild/python3dll.vcproj python/branches/py3k/PCbuild/xxlimited.vcproj python/branches/py3k/Tools/scripts/abitype.py Modified: python/branches/py3k/Doc/c-api/veryhigh.rst python/branches/py3k/Doc/faq/extending.rst python/branches/py3k/Doc/whatsnew/3.2.rst python/branches/py3k/Include/Python.h python/branches/py3k/Include/abstract.h python/branches/py3k/Include/bytearrayobject.h python/branches/py3k/Include/bytes_methods.h python/branches/py3k/Include/bytesobject.h python/branches/py3k/Include/cellobject.h python/branches/py3k/Include/ceval.h python/branches/py3k/Include/classobject.h python/branches/py3k/Include/code.h python/branches/py3k/Include/codecs.h python/branches/py3k/Include/compile.h python/branches/py3k/Include/complexobject.h python/branches/py3k/Include/datetime.h python/branches/py3k/Include/descrobject.h python/branches/py3k/Include/dictobject.h python/branches/py3k/Include/dtoa.h python/branches/py3k/Include/eval.h python/branches/py3k/Include/fileobject.h python/branches/py3k/Include/floatobject.h python/branches/py3k/Include/frameobject.h python/branches/py3k/Include/funcobject.h python/branches/py3k/Include/genobject.h python/branches/py3k/Include/import.h python/branches/py3k/Include/listobject.h python/branches/py3k/Include/longintrepr.h python/branches/py3k/Include/longobject.h python/branches/py3k/Include/marshal.h python/branches/py3k/Include/memoryobject.h python/branches/py3k/Include/methodobject.h python/branches/py3k/Include/modsupport.h python/branches/py3k/Include/moduleobject.h python/branches/py3k/Include/object.h python/branches/py3k/Include/objimpl.h python/branches/py3k/Include/parsetok.h python/branches/py3k/Include/pyarena.h python/branches/py3k/Include/pyatomic.h python/branches/py3k/Include/pyctype.h python/branches/py3k/Include/pydebug.h python/branches/py3k/Include/pyerrors.h python/branches/py3k/Include/pygetopt.h python/branches/py3k/Include/pymath.h python/branches/py3k/Include/pystate.h python/branches/py3k/Include/pystrtod.h python/branches/py3k/Include/pythonrun.h python/branches/py3k/Include/pytime.h python/branches/py3k/Include/setobject.h python/branches/py3k/Include/sliceobject.h python/branches/py3k/Include/structseq.h python/branches/py3k/Include/symtable.h python/branches/py3k/Include/sysmodule.h python/branches/py3k/Include/timefuncs.h python/branches/py3k/Include/token.h python/branches/py3k/Include/traceback.h python/branches/py3k/Include/tupleobject.h python/branches/py3k/Include/ucnhash.h python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Include/warnings.h python/branches/py3k/Include/weakrefobject.h python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/cfield.c python/branches/py3k/Modules/_elementtree.c python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Modules/arraymodule.c python/branches/py3k/Modules/getpath.c python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytesobject.c python/branches/py3k/Objects/funcobject.c python/branches/py3k/Objects/listobject.c python/branches/py3k/Objects/memoryobject.c python/branches/py3k/Objects/moduleobject.c python/branches/py3k/Objects/object.c python/branches/py3k/Objects/rangeobject.c python/branches/py3k/Objects/sliceobject.c python/branches/py3k/Objects/structseq.c python/branches/py3k/Objects/tupleobject.c python/branches/py3k/Objects/typeobject.c python/branches/py3k/Objects/unicodeobject.c python/branches/py3k/PC/getpathp.c python/branches/py3k/PC/pyconfig.h python/branches/py3k/PCbuild/pcbuild.sln python/branches/py3k/Python/bltinmodule.c python/branches/py3k/Python/ceval.c python/branches/py3k/Python/dynload_shlib.c python/branches/py3k/Python/dynload_win.c python/branches/py3k/Python/import.c python/branches/py3k/Python/pythonrun.c python/branches/py3k/setup.py Modified: python/branches/py3k/Doc/c-api/veryhigh.rst ============================================================================== --- python/branches/py3k/Doc/c-api/veryhigh.rst (original) +++ python/branches/py3k/Doc/c-api/veryhigh.rst Fri Dec 3 21:14:31 2010 @@ -239,14 +239,14 @@ be parsed or compiled. -.. c:function:: PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) +.. c:function:: PyObject* PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) This is a simplified interface to :c:func:`PyEval_EvalCodeEx`, with just the code object, and the dictionaries of global and local variables. The other arguments are set to *NULL*. -.. c:function:: PyObject* PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure) +.. c:function:: PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure) Evaluate a precompiled code object, given a particular environment for its evaluation. This environment consists of dictionaries of global and local Modified: python/branches/py3k/Doc/faq/extending.rst ============================================================================== --- python/branches/py3k/Doc/faq/extending.rst (original) +++ python/branches/py3k/Doc/faq/extending.rst Fri Dec 3 21:14:31 2010 @@ -379,7 +379,7 @@ if (ps1 == prompt || /* ">>> " or */ '\n' == code[i + j - 1]) /* "... " and double '\n' */ { /* so execute it */ - dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc); + dum = PyEval_EvalCode (src, glb, loc); Py_XDECREF (dum); Py_XDECREF (src); free (code); Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Fri Dec 3 21:14:31 2010 @@ -49,6 +49,24 @@ This article explains the new features in Python 3.2, compared to 3.1. +PEP 382: Defining a Stable ABI +============================== + +In the past, extension modules built for one Python version were often +not usable with other Python versions. Particularly on Windows, every +feature release of Python required rebuilding all extension modules that +one wanted to use. This requirement was the result of the free access to +Python interpreter internals that extension modules could use. + +With Python 3.2, an alternative approach becomes available: extension +modules with restrict themselves to a limited API (by defining +Py_LIMITED_API) cannot use many of the internals, but are constrained +to a set of API functions that are promised to be stable for several +releases. As a consequence, extension modules built for 3.2 in that +mode will also work with 3.3, 3.4, and so on. Extension modules that +make use of details of memory structures can still be built, but will +need to be recompiled for every feature release. + PEP 391: Dictionary Based Configuration for Logging ==================================================== Modified: python/branches/py3k/Include/Python.h ============================================================================== --- python/branches/py3k/Include/Python.h (original) +++ python/branches/py3k/Include/Python.h Fri Dec 3 21:14:31 2010 @@ -66,6 +66,7 @@ #include "object.h" #include "objimpl.h" +#include "typeslots.h" #include "pydebug.h" @@ -100,6 +101,7 @@ #include "weakrefobject.h" #include "structseq.h" + #include "codecs.h" #include "pyerrors.h" @@ -130,7 +132,9 @@ #endif /* _Py_Mangle is defined in compile.c */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/abstract.h ============================================================================== --- python/branches/py3k/Include/abstract.h (original) +++ python/branches/py3k/Include/abstract.h Fri Dec 3 21:14:31 2010 @@ -387,7 +387,9 @@ PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); #define PyObject_Length PyObject_Size +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o, Py_ssize_t); +#endif /* Guess the size of object o using len(o) or o.__length_hint__(). @@ -765,9 +767,11 @@ that can accept a char* naming integral's type. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyNumber_ConvertIntegralToInt( PyObject *integral, const char* error_format); +#endif /* Returns the object converted to Py_ssize_t by going through @@ -1057,11 +1061,13 @@ Use __contains__ if possible, else _PySequence_IterSearch(). */ +#ifndef Py_LIMITED_API #define PY_ITERSEARCH_COUNT 1 #define PY_ITERSEARCH_INDEX 2 #define PY_ITERSEARCH_CONTAINS 3 PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation); +#endif /* Iterate over seq. Result depends on the operation: PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if @@ -1228,6 +1234,7 @@ /* issubclass(object, typeorclass) */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); @@ -1235,6 +1242,7 @@ PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); +#endif /* For internal use by buffer API functions */ PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, Modified: python/branches/py3k/Include/bytearrayobject.h ============================================================================== --- python/branches/py3k/Include/bytearrayobject.h (original) +++ python/branches/py3k/Include/bytearrayobject.h Fri Dec 3 21:14:31 2010 @@ -19,6 +19,7 @@ */ /* Object layout */ +#ifndef Py_LIMITED_API typedef struct { PyObject_VAR_HEAD /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */ @@ -26,6 +27,7 @@ Py_ssize_t ob_alloc; /* How many bytes allocated */ char *ob_bytes; } PyByteArrayObject; +#endif /* Type object */ PyAPI_DATA(PyTypeObject) PyByteArray_Type; @@ -44,12 +46,14 @@ PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); /* Macros, trading safety for speed */ +#ifndef Py_LIMITED_API #define PyByteArray_AS_STRING(self) \ (assert(PyByteArray_Check(self)), \ Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_bytes : _PyByteArray_empty_string) #define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self)) PyAPI_DATA(char) _PyByteArray_empty_string[]; +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/bytes_methods.h ============================================================================== --- python/branches/py3k/Include/bytes_methods.h (original) +++ python/branches/py3k/Include/bytes_methods.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef Py_BYTES_CTYPE_H #define Py_BYTES_CTYPE_H @@ -42,3 +43,4 @@ #define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str) #endif /* !Py_BYTES_CTYPE_H */ +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/bytesobject.h ============================================================================== --- python/branches/py3k/Include/bytesobject.h (original) +++ python/branches/py3k/Include/bytesobject.h Fri Dec 3 21:14:31 2010 @@ -27,6 +27,7 @@ /* Caching the hash (ob_shash) saves recalculation of a string's hash value. This significantly speeds up dict lookups. */ +#ifndef Py_LIMITED_API typedef struct { PyObject_VAR_HEAD Py_hash_t ob_shash; @@ -38,6 +39,7 @@ * ob_shash is the hash of the string or -1 if not computed yet. */ } PyBytesObject; +#endif PyAPI_DATA(PyTypeObject) PyBytes_Type; PyAPI_DATA(PyTypeObject) PyBytesIter_Type; @@ -58,21 +60,27 @@ PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); PyAPI_FUNC(PyObject *) _PyBytes_FormatLong(PyObject*, int, int, int, char**, int*); +#endif PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, const char *); /* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API #define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ (((PyBytesObject *)(op))->ob_sval)) #define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) +#endif /* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, x must be an iterable object. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); +#endif /* Provides access to the internal data buffer and size of a string object or the default encoded version of an Unicode object. Passing @@ -90,7 +98,7 @@ /* Using the current locale, insert the thousands grouping into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ - +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer, Py_ssize_t n_buffer, char *digits, @@ -107,6 +115,7 @@ Py_ssize_t min_width, const char *grouping, const char *thousands_sep); +#endif /* Flags used by string formatting */ #define F_LJUST (1<<0) Modified: python/branches/py3k/Include/cellobject.h ============================================================================== --- python/branches/py3k/Include/cellobject.h (original) +++ python/branches/py3k/Include/cellobject.h Fri Dec 3 21:14:31 2010 @@ -1,5 +1,5 @@ /* Cell object interface */ - +#ifndef Py_LIMITED_API #ifndef Py_CELLOBJECT_H #define Py_CELLOBJECT_H #ifdef __cplusplus @@ -26,3 +26,4 @@ } #endif #endif /* !Py_TUPLEOBJECT_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/ceval.h ============================================================================== --- python/branches/py3k/Include/ceval.h (original) +++ python/branches/py3k/Include/ceval.h Fri Dec 3 21:14:31 2010 @@ -20,8 +20,10 @@ const char *methodname, const char *format, ...); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +#endif struct _frame; /* Avoid including frameobject.h */ @@ -33,7 +35,9 @@ /* Look at the current frame's (if any) code's co_flags, and turn on the corresponding compiler flags in cf->cf_flags. Return 1 if any flag was set, else return 0. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); +#endif PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); PyAPI_FUNC(int) Py_MakePendingCalls(void); @@ -167,8 +171,10 @@ PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReInitThreads(void); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); +#endif #define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ @@ -187,8 +193,10 @@ #endif /* !WITH_THREAD */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); +#endif #ifdef __cplusplus Modified: python/branches/py3k/Include/classobject.h ============================================================================== --- python/branches/py3k/Include/classobject.h (original) +++ python/branches/py3k/Include/classobject.h Fri Dec 3 21:14:31 2010 @@ -2,6 +2,7 @@ /* Revealing some structures (not for general use) */ +#ifndef Py_LIMITED_API #ifndef Py_CLASSOBJECT_H #define Py_CLASSOBJECT_H #ifdef __cplusplus @@ -54,3 +55,4 @@ } #endif #endif /* !Py_CLASSOBJECT_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/code.h ============================================================================== --- python/branches/py3k/Include/code.h (original) +++ python/branches/py3k/Include/code.h Fri Dec 3 21:14:31 2010 @@ -1,5 +1,6 @@ /* Definitions for bytecode */ +#ifndef Py_LIMITED_API #ifndef Py_CODE_H #define Py_CODE_H #ifdef __cplusplus @@ -93,8 +94,10 @@ /* Update *bounds to describe the first and one-past-the-last instructions in the same line as lasti. Return the number of that line. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds); +#endif PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, PyObject *lineno_obj); @@ -103,3 +106,4 @@ } #endif #endif /* !Py_CODE_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/codecs.h ============================================================================== --- python/branches/py3k/Include/codecs.h (original) +++ python/branches/py3k/Include/codecs.h Fri Dec 3 21:14:31 2010 @@ -45,9 +45,11 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyCodec_Lookup( const char *encoding ); +#endif /* Codec registry encoding check API. Modified: python/branches/py3k/Include/compile.h ============================================================================== --- python/branches/py3k/Include/compile.h (original) +++ python/branches/py3k/Include/compile.h Fri Dec 3 21:14:31 2010 @@ -1,4 +1,4 @@ - +#ifndef Py_LIMITED_API #ifndef Py_COMPILE_H #define Py_COMPILE_H @@ -38,3 +38,4 @@ } #endif #endif /* !Py_COMPILE_H */ +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/complexobject.h ============================================================================== --- python/branches/py3k/Include/complexobject.h (original) +++ python/branches/py3k/Include/complexobject.h Fri Dec 3 21:14:31 2010 @@ -6,6 +6,7 @@ extern "C" { #endif +#ifndef Py_LIMITED_API typedef struct { double real; double imag; @@ -28,7 +29,7 @@ PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex); PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex); PyAPI_FUNC(double) c_abs(Py_complex); - +#endif /* Complex object interface */ @@ -36,29 +37,36 @@ PyComplexObject represents a complex number with double-precision real and imaginary parts. */ - +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD Py_complex cval; -} PyComplexObject; +} PyComplexObject; +#endif PyAPI_DATA(PyTypeObject) PyComplex_Type; #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) #define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); +#endif PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); +#endif /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj, Py_UNICODE *format_spec, Py_ssize_t format_spec_len); +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/datetime.h ============================================================================== --- python/branches/py3k/Include/datetime.h (original) +++ python/branches/py3k/Include/datetime.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,6 @@ /* datetime.h */ - +#ifndef Py_LIMITED_API #ifndef DATETIME_H #define DATETIME_H #ifdef __cplusplus @@ -234,3 +234,4 @@ } #endif #endif +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/descrobject.h ============================================================================== --- python/branches/py3k/Include/descrobject.h (original) +++ python/branches/py3k/Include/descrobject.h Fri Dec 3 21:14:31 2010 @@ -16,6 +16,7 @@ void *closure; } PyGetSetDef; +#ifndef Py_LIMITED_API typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, void *wrapped); @@ -68,6 +69,7 @@ struct wrapperbase *d_base; void *d_wrapped; /* This can be any function pointer */ } PyWrapperDescrObject; +#endif /* Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; @@ -78,13 +80,16 @@ PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); +struct PyMemberDef; /* forward declaration for following prototype */ PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, struct PyMemberDef *); PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, struct PyGetSetDef *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); #define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) +#endif PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); Modified: python/branches/py3k/Include/dictobject.h ============================================================================== --- python/branches/py3k/Include/dictobject.h (original) +++ python/branches/py3k/Include/dictobject.h Fri Dec 3 21:14:31 2010 @@ -45,6 +45,7 @@ * majority of dicts (consisting mostly of usually-small instance dicts and * usually-small dicts created to pass keyword arguments). */ +#ifndef Py_LIMITED_API #define PyDict_MINSIZE 8 typedef struct { @@ -84,6 +85,7 @@ PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, Py_hash_t hash); PyDictEntry ma_smalltable[PyDict_MINSIZE]; }; +#endif /* Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PyDict_Type; PyAPI_DATA(PyTypeObject) PyDictIterKey_Type; @@ -112,18 +114,22 @@ PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); +#endif PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); +#endif /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); Modified: python/branches/py3k/Include/dtoa.h ============================================================================== --- python/branches/py3k/Include/dtoa.h (original) +++ python/branches/py3k/Include/dtoa.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef PY_NO_SHORT_FLOAT_REPR #ifdef __cplusplus extern "C" { @@ -13,3 +14,4 @@ } #endif #endif +#endif Modified: python/branches/py3k/Include/eval.h ============================================================================== --- python/branches/py3k/Include/eval.h (original) +++ python/branches/py3k/Include/eval.h Fri Dec 3 21:14:31 2010 @@ -7,9 +7,9 @@ extern "C" { #endif -PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co, +PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argc, @@ -17,7 +17,9 @@ PyObject **defs, int defc, PyObject *kwdefs, PyObject *closure); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/fileobject.h ============================================================================== --- python/branches/py3k/Include/fileobject.h (original) +++ python/branches/py3k/Include/fileobject.h Fri Dec 3 21:14:31 2010 @@ -14,7 +14,9 @@ PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +#endif /* The default encoding used by the platform file system APIs If non-NULL, this is different than the default encoding for strings @@ -26,6 +28,7 @@ The std printer acts as a preliminary sys.stderr until the new io infrastructure is in place. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; @@ -39,6 +42,7 @@ #else #define _PyVerify_fd(A) (1) /* dummy */ #endif +#endif /* Py_LIMITED_API */ #ifdef __cplusplus } Modified: python/branches/py3k/Include/floatobject.h ============================================================================== --- python/branches/py3k/Include/floatobject.h (original) +++ python/branches/py3k/Include/floatobject.h Fri Dec 3 21:14:31 2010 @@ -11,10 +11,12 @@ extern "C" { #endif +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD double ob_fval; } PyFloatObject; +#endif PyAPI_DATA(PyTypeObject) PyFloat_Type; @@ -45,8 +47,11 @@ /* Extract C double from Python float. The macro version trades safety for speed. */ PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); +#ifndef Py_LIMITED_API #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) +#endif +#ifndef Py_LIMITED_API /* _PyFloat_{Pack,Unpack}{4,8} * * The struct and pickle (at least) modules need an efficient platform- @@ -110,6 +115,7 @@ PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj, Py_UNICODE *format_spec, Py_ssize_t format_spec_len); +#endif /* Py_LIMITED_API */ #ifdef __cplusplus } Modified: python/branches/py3k/Include/frameobject.h ============================================================================== --- python/branches/py3k/Include/frameobject.h (original) +++ python/branches/py3k/Include/frameobject.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,7 @@ /* Frame object interface */ +#ifndef Py_LIMITED_API #ifndef Py_FRAMEOBJECT_H #define Py_FRAMEOBJECT_H #ifdef __cplusplus @@ -85,3 +86,4 @@ } #endif #endif /* !Py_FRAMEOBJECT_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/funcobject.h ============================================================================== --- python/branches/py3k/Include/funcobject.h (original) +++ python/branches/py3k/Include/funcobject.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,6 @@ /* Function object interface */ - +#ifndef Py_LIMITED_API #ifndef Py_FUNCOBJECT_H #define Py_FUNCOBJECT_H #ifdef __cplusplus @@ -84,3 +84,4 @@ } #endif #endif /* !Py_FUNCOBJECT_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/genobject.h ============================================================================== --- python/branches/py3k/Include/genobject.h (original) +++ python/branches/py3k/Include/genobject.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,7 @@ /* Generator object interface */ +#ifndef Py_LIMITED_API #ifndef Py_GENOBJECT_H #define Py_GENOBJECT_H #ifdef __cplusplus @@ -38,3 +39,4 @@ } #endif #endif /* !Py_GENOBJECT_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/import.h ============================================================================== --- python/branches/py3k/Include/import.h (original) +++ python/branches/py3k/Include/import.h Fri Dec 3 21:14:31 2010 @@ -30,6 +30,7 @@ PyAPI_FUNC(void) PyImport_Cleanup(void); PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *); +#ifndef Py_LIMITED_API #ifdef WITH_THREAD PyAPI_FUNC(void) _PyImport_AcquireLock(void); PyAPI_FUNC(int) _PyImport_ReleaseLock(void); @@ -49,13 +50,15 @@ char *name; PyObject* (*initfunc)(void); }; +PyAPI_DATA(struct _inittab *) PyImport_Inittab; +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); +#endif /* Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PyNullImporter_Type; -PyAPI_DATA(struct _inittab *) PyImport_Inittab; PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)); -PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); +#ifndef Py_LIMITED_API struct _frozen { char *name; unsigned char *code; @@ -66,6 +69,7 @@ collection of frozen modules: */ PyAPI_DATA(struct _frozen *) PyImport_FrozenModules; +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/listobject.h ============================================================================== --- python/branches/py3k/Include/listobject.h (original) +++ python/branches/py3k/Include/listobject.h Fri Dec 3 21:14:31 2010 @@ -19,6 +19,7 @@ extern "C" { #endif +#ifndef Py_LIMITED_API typedef struct { PyObject_VAR_HEAD /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ @@ -37,6 +38,7 @@ */ Py_ssize_t allocated; } PyListObject; +#endif PyAPI_DATA(PyTypeObject) PyList_Type; PyAPI_DATA(PyTypeObject) PyListIter_Type; @@ -58,12 +60,16 @@ PyAPI_FUNC(int) PyList_Sort(PyObject *); PyAPI_FUNC(int) PyList_Reverse(PyObject *); PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); +#endif /* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API #define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) #define PyList_GET_SIZE(op) Py_SIZE(op) +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/longintrepr.h ============================================================================== --- python/branches/py3k/Include/longintrepr.h (original) +++ python/branches/py3k/Include/longintrepr.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef Py_LONGINTREPR_H #define Py_LONGINTREPR_H #ifdef __cplusplus @@ -99,3 +100,4 @@ } #endif #endif /* !Py_LONGINTREPR_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/longobject.h ============================================================================== --- python/branches/py3k/Include/longobject.h (original) +++ python/branches/py3k/Include/longobject.h Fri Dec 3 21:14:31 2010 @@ -50,7 +50,9 @@ #endif /* SIZEOF_PID_T */ /* Used by Python/mystrtoul.c. */ +#ifndef Py_LIMITED_API PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; +#endif /* _PyLong_Frexp returns a double x and an exponent e such that the true value is approximately equal to x * 2**e. e is >= 0. x is @@ -58,7 +60,9 @@ zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is possible if the number of bits doesn't fit into a Py_ssize_t, sets OverflowError and returns -1.0 for x, 0 for e. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); +#endif PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); @@ -74,8 +78,11 @@ #endif /* HAVE_LONG_LONG */ PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +#endif +#ifndef Py_LIMITED_API /* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. v must not be NULL, and must be a normalized long. There are no error cases. @@ -150,6 +157,7 @@ PyAPI_FUNC(PyObject *) _PyLong_FormatAdvanced(PyObject *obj, Py_UNICODE *format_spec, Py_ssize_t format_spec_len); +#endif /* Py_LIMITED_API */ /* These aren't really part of the long object, but they're handy. The functions are in Python/mystrtoul.c. Modified: python/branches/py3k/Include/marshal.h ============================================================================== --- python/branches/py3k/Include/marshal.h (original) +++ python/branches/py3k/Include/marshal.h Fri Dec 3 21:14:31 2010 @@ -13,10 +13,12 @@ PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); +#ifndef Py_LIMITED_API PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); +#endif PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); #ifdef __cplusplus Modified: python/branches/py3k/Include/memoryobject.h ============================================================================== --- python/branches/py3k/Include/memoryobject.h (original) +++ python/branches/py3k/Include/memoryobject.h Fri Dec 3 21:14:31 2010 @@ -10,10 +10,12 @@ #define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) +#ifndef Py_LIMITED_API /* Get a pointer to the underlying Py_buffer of a memoryview object. */ #define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) /* Get a pointer to the PyObject from which originates a memoryview object. */ #define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) +#endif PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, @@ -61,11 +63,12 @@ /* The struct is declared here so that macros can work, but it shouldn't be considered public. Don't access those fields directly, use the macros and functions instead! */ +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD Py_buffer view; } PyMemoryViewObject; - +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/methodobject.h ============================================================================== --- python/branches/py3k/Include/methodobject.h (original) +++ python/branches/py3k/Include/methodobject.h Fri Dec 3 21:14:31 2010 @@ -26,12 +26,14 @@ /* Macros for direct access to these values. Type checks are *not* done, so use with care. */ +#ifndef Py_LIMITED_API #define PyCFunction_GET_FUNCTION(func) \ (((PyCFunctionObject *)func) -> m_ml -> ml_meth) #define PyCFunction_GET_SELF(func) \ (((PyCFunctionObject *)func) -> m_self) #define PyCFunction_GET_FLAGS(func) \ (((PyCFunctionObject *)func) -> m_ml -> ml_flags) +#endif PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); struct PyMethodDef { @@ -68,12 +70,14 @@ #define METH_COEXIST 0x0040 +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD PyMethodDef *m_ml; /* Description of the C function to call */ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_module; /* The __module__ attribute, can be anything */ } PyCFunctionObject; +#endif PyAPI_FUNC(int) PyCFunction_ClearFreeList(void); Modified: python/branches/py3k/Include/modsupport.h ============================================================================== --- python/branches/py3k/Include/modsupport.h (original) +++ python/branches/py3k/Include/modsupport.h Fri Dec 3 21:14:31 2010 @@ -31,7 +31,9 @@ PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw); +#endif PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, @@ -92,6 +94,12 @@ 9-Jan-1995 GvR Initial version (incompatible with older API) */ +/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of + Python 3, it will stay at the value of 3; changes to the limited API + must be performed in a strictly backwards-compatible manner. */ +#define PYTHON_ABI_VERSION 3 +#define PYTHON_ABI_STRING "3" + #ifdef Py_TRACE_REFS /* When we are tracing reference counts, rename PyModule_Create2 so modules compiled with incompatible settings will generate a @@ -102,10 +110,17 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, int apiver); +#ifdef Py_LIMITED_API +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_ABI_VERSION) +#else #define PyModule_Create(module) \ PyModule_Create2(module, PYTHON_API_VERSION) +#endif +#ifndef Py_LIMITED_API PyAPI_DATA(char *) _Py_PackageContext; +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/moduleobject.h ============================================================================== --- python/branches/py3k/Include/moduleobject.h (original) +++ python/branches/py3k/Include/moduleobject.h Fri Dec 3 21:14:31 2010 @@ -17,7 +17,9 @@ PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyModule_Clear(PyObject *); +#endif PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); PyAPI_FUNC(void*) PyModule_GetState(PyObject*); Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Fri Dec 3 21:14:31 2010 @@ -61,6 +61,10 @@ #define Py_REF_DEBUG #endif +#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG) +#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG +#endif + #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ #define _PyObject_HEAD_EXTRA \ @@ -196,6 +200,7 @@ typedef int (*visitproc)(PyObject *, void *); typedef int (*traverseproc)(PyObject *, visitproc, void *); +#ifndef Py_LIMITED_API typedef struct { /* Number implementations must check *both* arguments for proper type and implement the necessary conversions @@ -265,10 +270,17 @@ getbufferproc bf_getbuffer; releasebufferproc bf_releasebuffer; } PyBufferProcs; +#endif /* Py_LIMITED_API */ typedef void (*freefunc)(void *); typedef void (*destructor)(PyObject *); +#ifndef Py_LIMITED_API +/* We can't provide a full compile-time check that limited-API + users won't implement tp_print. However, not defining printfunc + and making tp_print of a different function pointer type + should at least cause a warning in most cases. */ typedef int (*printfunc)(PyObject *, FILE *, int); +#endif typedef PyObject *(*getattrfunc)(PyObject *, char *); typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); typedef int (*setattrfunc)(PyObject *, char *, PyObject *); @@ -284,6 +296,9 @@ typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); +#ifdef Py_LIMITED_API +typedef struct _typeobject PyTypeObject; /* opaque */ +#else typedef struct _typeobject { PyObject_VAR_HEAD const char *tp_name; /* For printing, in format "." */ @@ -371,8 +386,25 @@ struct _typeobject *tp_next; #endif } PyTypeObject; +#endif + +typedef struct{ + int slot; /* slot id, see below */ + void *pfunc; /* function pointer */ +} PyType_Slot; + +typedef struct{ + const char* name; + const char* doc; + int basicsize; + int itemsize; + int flags; + PyType_Slot *slots; /* terminated by slot==0. */ +} PyType_Spec; +PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); +#ifndef Py_LIMITED_API /* The *real* layout of a type object when allocated on the heap */ typedef struct _heaptypeobject { /* Note: there's a dependency on the order of these members @@ -393,7 +425,7 @@ /* access macro to the members which are floating "behind" the object */ #define PyHeapType_GET_MEMBERS(etype) \ ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) - +#endif /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); @@ -412,15 +444,19 @@ PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **); +#endif PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); /* Generic operations on objects */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +#endif PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *); @@ -433,9 +469,13 @@ PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +#endif PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); +#endif PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); @@ -469,8 +509,10 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject *); /* Helpers for hash functions */ +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*); +#endif /* Helper for passing objects to printf and the like */ #define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj)) @@ -649,9 +691,13 @@ #define _Py_ForgetReference(op) _Py_INC_TPFREES(op) +#ifdef Py_LIMITED_API +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +#else #define _Py_Dealloc(op) ( \ _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) +#endif #endif /* !Py_TRACE_REFS */ #define Py_INCREF(op) ( \ Modified: python/branches/py3k/Include/objimpl.h ============================================================================== --- python/branches/py3k/Include/objimpl.h (original) +++ python/branches/py3k/Include/objimpl.h Fri Dec 3 21:14:31 2010 @@ -246,6 +246,7 @@ #define _PyObject_GC_Del PyObject_GC_Del /* GC information is stored BEFORE the object structure. */ +#ifndef Py_LIMITED_API typedef union _gc_head { struct { union _gc_head *gc_next; @@ -298,7 +299,7 @@ #define _PyObject_GC_MAY_BE_TRACKED(obj) \ (PyObject_IS_GC(obj) && \ (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) - +#endif /* Py_LIMITED_API */ PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); Modified: python/branches/py3k/Include/parsetok.h ============================================================================== --- python/branches/py3k/Include/parsetok.h (original) +++ python/branches/py3k/Include/parsetok.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,6 @@ /* Parser-tokenizer link interface */ - +#ifndef Py_LIMITED_API #ifndef Py_PARSETOK_H #define Py_PARSETOK_H #ifdef __cplusplus @@ -64,3 +64,4 @@ } #endif #endif /* !Py_PARSETOK_H */ +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/pyarena.h ============================================================================== --- python/branches/py3k/Include/pyarena.h (original) +++ python/branches/py3k/Include/pyarena.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,7 @@ /* An arena-like memory interface for the compiler. */ +#ifndef Py_LIMITED_API #ifndef Py_PYARENA_H #define Py_PYARENA_H @@ -60,3 +61,4 @@ #endif #endif /* !Py_PYARENA_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/pyatomic.h ============================================================================== --- python/branches/py3k/Include/pyatomic.h (original) +++ python/branches/py3k/Include/pyatomic.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef Py_ATOMIC_H #define Py_ATOMIC_H /* XXX: When compilers start offering a stdatomic.h with lock-free @@ -177,3 +178,4 @@ #endif #endif /* Py_ATOMIC_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/pyctype.h ============================================================================== --- python/branches/py3k/Include/pyctype.h (original) +++ python/branches/py3k/Include/pyctype.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef PYCTYPE_H #define PYCTYPE_H @@ -29,3 +30,4 @@ #define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) #endif /* !PYCTYPE_H */ +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/pydebug.h ============================================================================== --- python/branches/py3k/Include/pydebug.h (original) +++ python/branches/py3k/Include/pydebug.h Fri Dec 3 21:14:31 2010 @@ -1,4 +1,4 @@ - +#ifndef Py_LIMITED_API #ifndef Py_PYDEBUG_H #define Py_PYDEBUG_H #ifdef __cplusplus @@ -31,3 +31,4 @@ } #endif #endif /* !Py_PYDEBUG_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/pyerrors.h ============================================================================== --- python/branches/py3k/Include/pyerrors.h (original) +++ python/branches/py3k/Include/pyerrors.h Fri Dec 3 21:14:31 2010 @@ -6,6 +6,7 @@ /* Error objects */ +#ifndef Py_LIMITED_API /* PyException_HEAD defines the initial segment of every exception class. */ #define PyException_HEAD PyObject_HEAD PyObject *dict;\ PyObject *args; PyObject *traceback;\ @@ -55,6 +56,7 @@ PyObject *winerror; } PyWindowsErrorObject; #endif +#endif /* Error handling definitions */ @@ -68,8 +70,9 @@ PyAPI_FUNC(void) PyErr_Clear(void); PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(void) Py_FatalError(const char *message); -#ifdef Py_DEBUG +#if defined(Py_DEBUG) || defined(Py_LIMITED_API) #define _PyErr_OCCURRED() PyErr_Occurred() #else #define _PyErr_OCCURRED() (_PyThreadState_Current->curexc_type) @@ -183,7 +186,7 @@ PyObject *exc, const char *filename /* decoded from the filesystem encoding */ ); -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) && !defined(Py_LIMITED_API) PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( PyObject *, const Py_UNICODE *); #endif /* MS_WINDOWS */ @@ -199,15 +202,20 @@ int, const char *); PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( int, const char *); +#ifndef Py_LIMITED_API +/* XXX redeclare to use WSTRING */ PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( int, const Py_UNICODE *); +#endif PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( PyObject *,int, PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( PyObject *,int, const char *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyObject *,int, const Py_UNICODE *); +#endif PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); #endif /* MS_WINDOWS */ @@ -230,7 +238,9 @@ PyAPI_FUNC(void) PyErr_SetInterrupt(void); /* In signalmodule.c */ +#ifndef Py_LIMITED_API int PySignal_SetWakeupFd(int fd); +#endif /* Support for adding program text to SyntaxErrors */ PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int); @@ -245,12 +255,16 @@ const char *, const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); /* create a UnicodeEncodeError object */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( const char *, const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); +#endif /* create a UnicodeTranslateError object */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); +#endif /* get the encoding attribute */ PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); Modified: python/branches/py3k/Include/pygetopt.h ============================================================================== --- python/branches/py3k/Include/pygetopt.h (original) +++ python/branches/py3k/Include/pygetopt.h Fri Dec 3 21:14:31 2010 @@ -5,9 +5,11 @@ extern "C" { #endif +#ifndef Py_LIMITED_API PyAPI_DATA(int) _PyOS_opterr; PyAPI_DATA(int) _PyOS_optind; PyAPI_DATA(wchar_t *) _PyOS_optarg; +#endif PyAPI_FUNC(int) _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring); Modified: python/branches/py3k/Include/pymath.h ============================================================================== --- python/branches/py3k/Include/pymath.h (original) +++ python/branches/py3k/Include/pymath.h Fri Dec 3 21:14:31 2010 @@ -67,6 +67,7 @@ nothing. */ /* we take double rounding as evidence of x87 usage */ +#ifndef Py_LIMITED_API #ifndef Py_FORCE_DOUBLE # ifdef X87_DOUBLE_ROUNDING PyAPI_FUNC(double) _Py_force_double(double); @@ -75,11 +76,14 @@ # define Py_FORCE_DOUBLE(X) (X) # endif #endif +#endif +#ifndef Py_LIMITED_API #ifdef HAVE_GCC_ASM_FOR_X87 PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); #endif +#endif /* Py_IS_NAN(X) * Return 1 if float or double arg is a NaN, else 0. Modified: python/branches/py3k/Include/pystate.h ============================================================================== --- python/branches/py3k/Include/pystate.h (original) +++ python/branches/py3k/Include/pystate.h Fri Dec 3 21:14:31 2010 @@ -13,6 +13,9 @@ struct _ts; /* Forward */ struct _is; /* Forward */ +#ifdef Py_LIMITED_API +typedef struct _is PyInterpreterState; +#else typedef struct _is { struct _is *next; @@ -37,12 +40,14 @@ #endif } PyInterpreterState; +#endif /* State unique per thread */ struct _frame; /* Avoid including frameobject.h */ +#ifndef Py_LIMITED_API /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); @@ -54,7 +59,11 @@ #define PyTrace_C_CALL 4 #define PyTrace_C_EXCEPTION 5 #define PyTrace_C_RETURN 6 +#endif +#ifdef Py_LIMITED_API +typedef struct _ts PyThreadState; +#else typedef struct _ts { /* See Python/ceval.c for comments explaining most fields */ @@ -106,6 +115,7 @@ /* XXX signal handlers should also be here */ } PyThreadState; +#endif PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); @@ -133,9 +143,11 @@ /* Assuming the current thread holds the GIL, this is the PyThreadState for the current thread. */ +#ifndef Py_LIMITED_API PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; +#endif -#ifdef Py_DEBUG +#if defined(Py_DEBUG) || defined(Py_LIMITED_API) #define PyThreadState_GET() PyThreadState_Get() #else #define PyThreadState_GET() \ @@ -190,19 +202,25 @@ /* The implementation of sys._current_frames() Returns a dict mapping thread id to that thread's current frame. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); +#endif /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); +#endif /* hook for PyEval_GetFrame(), requested for Psyco */ +#ifndef Py_LIMITED_API PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame; +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/pystrtod.h ============================================================================== --- python/branches/py3k/Include/pystrtod.h (original) +++ python/branches/py3k/Include/pystrtod.h Fri Dec 3 21:14:31 2010 @@ -18,7 +18,9 @@ int flags, int *type); +#ifndef Py_LIMITED_API PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); +#endif /* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ Modified: python/branches/py3k/Include/pythonrun.h ============================================================================== --- python/branches/py3k/Include/pythonrun.h (original) +++ python/branches/py3k/Include/pythonrun.h Fri Dec 3 21:14:31 2010 @@ -16,9 +16,11 @@ #define PyCF_ONLY_AST 0x0400 #define PyCF_IGNORE_COOKIE 0x0800 +#ifndef Py_LIMITED_API typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ } PyCompilerFlags; +#endif PyAPI_FUNC(void) Py_SetProgramName(wchar_t *); PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); @@ -33,9 +35,10 @@ PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_AnyFileExFlags(FILE *, const char *, int, PyCompilerFlags *); -PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *); @@ -48,25 +51,35 @@ char *, char *, PyCompilerFlags *, int *, PyArena *); +#endif + +#ifndef PyParser_SimpleParseString #define PyParser_SimpleParseString(S, B) \ PyParser_SimpleParseStringFlags(S, B, 0) #define PyParser_SimpleParseFile(FP, S, B) \ PyParser_SimpleParseFileFlags(FP, S, B, 0) +#endif PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, int); PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, int, int); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, PyObject *, PyCompilerFlags *); PyAPI_FUNC(PyObject *) PyRun_FileExFlags(FILE *, const char *, int, PyObject *, PyObject *, int, PyCompilerFlags *); +#endif +#ifdef Py_LIMITED_API +PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int); +#else #define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL) PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int, PyCompilerFlags *); +#endif PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int); PyAPI_FUNC(void) PyErr_Print(void); @@ -76,19 +89,24 @@ /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level * exit functions. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); +#endif PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); PyAPI_FUNC(void) Py_Exit(int); /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _Py_RestoreSignals(void); PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +#endif /* Bootstrap */ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); +#ifndef Py_LIMITED_API /* Use macros for a bunch of old variants */ #define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) #define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) @@ -107,6 +125,7 @@ PyRun_FileExFlags(fp, p, s, g, l, c, NULL) #define PyRun_FileFlags(fp, p, s, g, l, flags) \ PyRun_FileExFlags(fp, p, s, g, l, 0, flags) +#endif /* In getpath.c */ PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); @@ -114,6 +133,9 @@ PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); PyAPI_FUNC(wchar_t *) Py_GetPath(void); PyAPI_FUNC(void) Py_SetPath(const wchar_t *); +#ifdef MS_WINDOWS +int _Py_CheckPython3(); +#endif /* In their own files */ PyAPI_FUNC(const char *) Py_GetVersion(void); @@ -121,11 +143,14 @@ PyAPI_FUNC(const char *) Py_GetCopyright(void); PyAPI_FUNC(const char *) Py_GetCompiler(void); PyAPI_FUNC(const char *) Py_GetBuildInfo(void); +#ifndef Py_LIMITED_API PyAPI_FUNC(const char *) _Py_svnversion(void); PyAPI_FUNC(const char *) Py_SubversionRevision(void); PyAPI_FUNC(const char *) Py_SubversionShortBranch(void); +#endif /* Internal -- various one-time initializations */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); PyAPI_FUNC(PyObject *) _PySys_Init(void); PyAPI_FUNC(void) _PyImport_Init(void); @@ -134,8 +159,10 @@ PyAPI_FUNC(int) _PyFrame_Init(void); PyAPI_FUNC(void) _PyFloat_Init(void); PyAPI_FUNC(int) PyByteArray_Init(void); +#endif /* Various internal finalizers */ +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyExc_Fini(void); PyAPI_FUNC(void) _PyImport_Fini(void); PyAPI_FUNC(void) PyMethod_Fini(void); @@ -150,12 +177,17 @@ PyAPI_FUNC(void) PyFloat_Fini(void); PyAPI_FUNC(void) PyOS_FiniInterrupts(void); PyAPI_FUNC(void) _PyGC_Fini(void); +#endif /* Stuff with no proper home (yet) */ +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *); +#endif PyAPI_DATA(int) (*PyOS_InputHook)(void); PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *); +#ifndef Py_LIMITED_API PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +#endif /* Stack size, in "pointers" (so we get extra safety margins on 64-bit platforms). On a 32-bit platform, this translates Modified: python/branches/py3k/Include/pytime.h ============================================================================== --- python/branches/py3k/Include/pytime.h (original) +++ python/branches/py3k/Include/pytime.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef Py_PYTIME_H #define Py_PYTIME_H @@ -44,3 +45,4 @@ #endif #endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/setobject.h ============================================================================== --- python/branches/py3k/Include/setobject.h (original) +++ python/branches/py3k/Include/setobject.h Fri Dec 3 21:14:31 2010 @@ -18,7 +18,7 @@ hold a search finger. The hash field of Unused or Dummy slots has no meaning otherwise. */ - +#ifndef Py_LIMITED_API #define PySet_MINSIZE 8 typedef struct { @@ -56,6 +56,7 @@ Py_hash_t hash; /* only used by frozenset objects */ PyObject *weakreflist; /* List of weak references */ }; +#endif /* Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PySet_Type; PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; @@ -85,14 +86,20 @@ PyAPI_FUNC(PyObject *) PySet_New(PyObject *); PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); +#ifndef Py_LIMITED_API #define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) +#endif PyAPI_FUNC(int) PySet_Clear(PyObject *set); PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +#endif PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/sliceobject.h ============================================================================== --- python/branches/py3k/Include/sliceobject.h (original) +++ python/branches/py3k/Include/sliceobject.h Fri Dec 3 21:14:31 2010 @@ -18,11 +18,12 @@ names are from range). After much talk with Guido, it was decided to let these be any arbitrary python type. Py_None stands for omitted values. */ - +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD PyObject *start, *stop, *step; /* not NULL */ } PySliceObject; +#endif PyAPI_DATA(PyTypeObject) PySlice_Type; PyAPI_DATA(PyTypeObject) PyEllipsis_Type; @@ -31,10 +32,12 @@ PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); -PyAPI_FUNC(int) PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, +#endif +PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); -PyAPI_FUNC(int) PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, +PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); Modified: python/branches/py3k/Include/structseq.h ============================================================================== --- python/branches/py3k/Include/structseq.h (original) +++ python/branches/py3k/Include/structseq.h Fri Dec 3 21:14:31 2010 @@ -21,18 +21,25 @@ extern char* PyStructSequence_UnnamedField; +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc); +#endif +PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc); PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); +#ifndef Py_LIMITED_API typedef PyTupleObject PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ #define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) #define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#endif +PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); +PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t); #ifdef __cplusplus } Modified: python/branches/py3k/Include/symtable.h ============================================================================== --- python/branches/py3k/Include/symtable.h (original) +++ python/branches/py3k/Include/symtable.h Fri Dec 3 21:14:31 2010 @@ -1,3 +1,4 @@ +#ifndef Py_LIMITED_API #ifndef Py_SYMTABLE_H #define Py_SYMTABLE_H @@ -102,3 +103,4 @@ } #endif #endif /* !Py_SYMTABLE_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/sysmodule.h ============================================================================== --- python/branches/py3k/Include/sysmodule.h (original) +++ python/branches/py3k/Include/sysmodule.h Fri Dec 3 21:14:31 2010 @@ -20,7 +20,9 @@ PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...); PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...); +#ifndef Py_LIMITED_API PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; +#endif PyAPI_FUNC(void) PySys_ResetWarnOptions(void); PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); Modified: python/branches/py3k/Include/timefuncs.h ============================================================================== --- python/branches/py3k/Include/timefuncs.h (original) +++ python/branches/py3k/Include/timefuncs.h Fri Dec 3 21:14:31 2010 @@ -14,7 +14,9 @@ * to fit in a time_t. ValueError is set on return iff the return * value is (time_t)-1 and PyErr_Occurred(). */ +#ifndef Py_LIMITED_API PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x); +#endif #ifdef __cplusplus Modified: python/branches/py3k/Include/token.h ============================================================================== --- python/branches/py3k/Include/token.h (original) +++ python/branches/py3k/Include/token.h Fri Dec 3 21:14:31 2010 @@ -1,6 +1,6 @@ /* Token types */ - +#ifndef Py_LIMITED_API #ifndef Py_TOKEN_H #define Py_TOKEN_H #ifdef __cplusplus @@ -85,3 +85,4 @@ } #endif #endif /* !Py_TOKEN_H */ +#endif /* Py_LIMITED_API */ Modified: python/branches/py3k/Include/traceback.h ============================================================================== --- python/branches/py3k/Include/traceback.h (original) +++ python/branches/py3k/Include/traceback.h Fri Dec 3 21:14:31 2010 @@ -8,7 +8,7 @@ struct _frame; /* Traceback interface */ - +#ifndef Py_LIMITED_API typedef struct _traceback { PyObject_HEAD struct _traceback *tb_next; @@ -16,10 +16,13 @@ int tb_lasti; int tb_lineno; } PyTracebackObject; +#endif PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +#endif /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; Modified: python/branches/py3k/Include/tupleobject.h ============================================================================== --- python/branches/py3k/Include/tupleobject.h (original) +++ python/branches/py3k/Include/tupleobject.h Fri Dec 3 21:14:31 2010 @@ -21,6 +21,7 @@ returned item's reference count. */ +#ifndef Py_LIMITED_API typedef struct { PyObject_VAR_HEAD PyObject *ob_item[1]; @@ -30,6 +31,7 @@ * the tuple is not yet visible outside the function that builds it. */ } PyTupleObject; +#endif PyAPI_DATA(PyTypeObject) PyTuple_Type; PyAPI_DATA(PyTypeObject) PyTupleIter_Type; @@ -43,16 +45,22 @@ PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +#endif PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); +#endif /* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API #define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) #define PyTuple_GET_SIZE(op) Py_SIZE(op) /* Macro, *only* to be used to fill in brand new tuples */ #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) +#endif PyAPI_FUNC(int) PyTuple_ClearFreeList(void); Added: python/branches/py3k/Include/typeslots.h ============================================================================== --- (empty file) +++ python/branches/py3k/Include/typeslots.h Fri Dec 3 21:14:31 2010 @@ -0,0 +1,71 @@ +#define Py_bf_getbuffer 1 +#define Py_bf_releasebuffer 2 +#define Py_mp_ass_subscript 3 +#define Py_mp_length 4 +#define Py_mp_subscript 5 +#define Py_nb_absolute 6 +#define Py_nb_add 7 +#define Py_nb_and 8 +#define Py_nb_bool 9 +#define Py_nb_divmod 10 +#define Py_nb_float 11 +#define Py_nb_floor_divide 12 +#define Py_nb_index 13 +#define Py_nb_inplace_add 14 +#define Py_nb_inplace_and 15 +#define Py_nb_inplace_floor_divide 16 +#define Py_nb_inplace_lshift 17 +#define Py_nb_inplace_multiply 18 +#define Py_nb_inplace_or 19 +#define Py_nb_inplace_power 20 +#define Py_nb_inplace_remainder 21 +#define Py_nb_inplace_rshift 22 +#define Py_nb_inplace_subtract 23 +#define Py_nb_inplace_true_divide 24 +#define Py_nb_inplace_xor 25 +#define Py_nb_int 26 +#define Py_nb_invert 27 +#define Py_nb_lshift 28 +#define Py_nb_multiply 29 +#define Py_nb_negative 30 +#define Py_nb_or 31 +#define Py_nb_positive 32 +#define Py_nb_power 33 +#define Py_nb_remainder 34 +#define Py_nb_rshift 35 +#define Py_nb_subtract 36 +#define Py_nb_true_divide 37 +#define Py_nb_xor 38 +#define Py_sq_ass_item 39 +#define Py_sq_concat 40 +#define Py_sq_contains 41 +#define Py_sq_inplace_concat 42 +#define Py_sq_inplace_repeat 43 +#define Py_sq_item 44 +#define Py_sq_length 45 +#define Py_sq_repeat 46 +#define Py_tp_alloc 47 +#define Py_tp_base 48 +#define Py_tp_bases 49 +#define Py_tp_call 50 +#define Py_tp_clear 51 +#define Py_tp_dealloc 52 +#define Py_tp_del 53 +#define Py_tp_descr_get 54 +#define Py_tp_descr_set 55 +#define Py_tp_doc 56 +#define Py_tp_getattr 57 +#define Py_tp_getattro 58 +#define Py_tp_hash 59 +#define Py_tp_init 60 +#define Py_tp_is_gc 61 +#define Py_tp_iter 62 +#define Py_tp_iternext 63 +#define Py_tp_methods 64 +#define Py_tp_new 65 +#define Py_tp_repr 66 +#define Py_tp_richcompare 67 +#define Py_tp_setattr 68 +#define Py_tp_setattro 69 +#define Py_tp_str 70 +#define Py_tp_traverse 71 Modified: python/branches/py3k/Include/ucnhash.h ============================================================================== --- python/branches/py3k/Include/ucnhash.h (original) +++ python/branches/py3k/Include/ucnhash.h Fri Dec 3 21:14:31 2010 @@ -1,5 +1,5 @@ /* Unicode name database interface */ - +#ifndef Py_LIMITED_API #ifndef Py_UCNHASH_H #define Py_UCNHASH_H #ifdef __cplusplus @@ -31,3 +31,4 @@ } #endif #endif /* !Py_UCNHASH_H */ +#endif /* !Py_LIMITED_API */ Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Fri Dec 3 21:14:31 2010 @@ -131,7 +131,9 @@ Python and represents a single Unicode element in the Unicode type. */ +#ifndef Py_LIMITED_API typedef PY_UNICODE_TYPE Py_UNICODE; +#endif /* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */ @@ -318,6 +320,7 @@ _Py_ascii_whitespace (see below) with an inlined check. */ +#ifndef Py_LIMITED_API #define Py_UNICODE_ISSPACE(ch) \ ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) @@ -362,6 +365,7 @@ ((*((string)->str + (offset)) == *((substring)->str)) && \ ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \ !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE))) +#endif /* Py_LIMITED_API */ #ifdef __cplusplus extern "C" { @@ -369,6 +373,7 @@ /* --- Unicode Type ------------------------------------------------------- */ +#ifndef Py_LIMITED_API typedef struct { PyObject_HEAD Py_ssize_t length; /* Length of raw Unicode data in buffer */ @@ -381,6 +386,7 @@ string, or NULL; this is used for implementing the buffer protocol */ } PyUnicodeObject; +#endif PyAPI_DATA(PyTypeObject) PyUnicode_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; @@ -394,6 +400,7 @@ #define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) /* Fast access macros */ +#ifndef Py_LIMITED_API #define PyUnicode_GET_SIZE(op) \ (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length)) #define PyUnicode_GET_DATA_SIZE(op) \ @@ -402,6 +409,7 @@ (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->str)) #define PyUnicode_AS_DATA(op) \ (assert(PyUnicode_Check(op)),((const char *)((PyUnicodeObject *)(op))->str)) +#endif /* --- Constants ---------------------------------------------------------- */ @@ -426,10 +434,12 @@ The buffer is copied into the new object. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( const Py_UNICODE *u, /* Unicode buffer */ Py_ssize_t size /* size of buffer */ ); +#endif /* Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded bytes */ PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize( @@ -446,9 +456,11 @@ /* Return a read-only pointer to the Unicode object's internal Py_UNICODE buffer. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( PyObject *unicode /* Unicode object */ ); +#endif /* Get the length of the Unicode object. */ @@ -456,8 +468,10 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API /* Get the maximum ordinal for a Unicode character. */ PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); +#endif /* Resize an already allocated Unicode object to the new size length. @@ -527,16 +541,20 @@ ... ); +#ifndef Py_LIMITED_API /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ PyAPI_FUNC(PyObject *) _PyUnicode_FormatAdvanced(PyObject *obj, Py_UNICODE *format_spec, Py_ssize_t format_spec_len); +#endif PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); PyAPI_FUNC(PyObject *) PyUnicode_InternFromString(const char *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _Py_ReleaseInternedUnicodeStrings(void); +#endif /* Use only if you know it's a string */ #define PyUnicode_CHECK_INTERNED(op) (((PyUnicodeObject *)(op))->state) @@ -568,7 +586,7 @@ error. */ PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( - PyUnicodeObject *unicode, /* Unicode object */ + PyObject *unicode, /* Unicode object */ register wchar_t *w, /* wchar_t buffer */ Py_ssize_t size /* size of buffer */ ); @@ -646,9 +664,11 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString( PyObject *unicode, const char *errors); +#endif /* Returns a pointer to the default encoding (UTF-8) of the Unicode object unicode and the size of the encoded representation @@ -664,9 +684,11 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) _PyUnicode_AsStringAndSize( PyObject *unicode, Py_ssize_t *size); +#endif /* Returns a pointer to the default encoding (UTF-8) of the Unicode object unicode. @@ -682,7 +704,9 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) _PyUnicode_AsString(PyObject *unicode); +#endif /* Returns "utf-8". */ @@ -721,12 +745,14 @@ /* Encodes a Py_UNICODE buffer of the given size and returns a Python string object. */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_Encode( const Py_UNICODE *s, /* Unicode char buffer */ Py_ssize_t size, /* number of Py_UNICODE chars to encode */ const char *encoding, /* encoding */ const char *errors /* error handling */ ); +#endif /* Encodes a Unicode object and returns the result as Python object. */ @@ -776,6 +802,7 @@ Py_ssize_t *consumed /* bytes consumed */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ @@ -783,6 +810,7 @@ int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ const char *errors /* error handling */ ); +#endif /* --- UTF-8 Codecs ------------------------------------------------------- */ @@ -803,11 +831,13 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors /* error handling */ ); +#endif /* --- UTF-32 Codecs ------------------------------------------------------ */ @@ -876,12 +906,14 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors, /* error handling */ int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ ); +#endif /* --- UTF-16 Codecs ------------------------------------------------------ */ @@ -954,12 +986,14 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors, /* error handling */ int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ ); +#endif /* --- Unicode-Escape Codecs ---------------------------------------------- */ @@ -973,10 +1007,12 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length /* Number of Py_UNICODE chars to encode */ ); +#endif /* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ @@ -990,20 +1026,24 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length /* Number of Py_UNICODE chars to encode */ ); +#endif /* --- Unicode Internal Codec --------------------------------------------- Only for internal use in _codecsmodule.c */ +#ifndef Py_LIMITED_API PyObject *_PyUnicode_DecodeUnicodeInternal( const char *string, Py_ssize_t length, const char *errors ); +#endif /* --- Latin-1 Codecs ----------------------------------------------------- @@ -1021,11 +1061,13 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ const char *errors /* error handling */ ); +#endif /* --- ASCII Codecs ------------------------------------------------------- @@ -1043,11 +1085,13 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ const char *errors /* error handling */ ); +#endif /* --- Character Map Codecs ----------------------------------------------- @@ -1085,6 +1129,7 @@ (unicode ordinal -> char ordinal) */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ @@ -1092,6 +1137,7 @@ (unicode ordinal -> char ordinal) */ const char *errors /* error handling */ ); +#endif /* Translate a Py_UNICODE buffer of the given length by applying a character mapping table to it and return the resulting Unicode @@ -1106,12 +1152,14 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ PyObject *table, /* Translate table */ const char *errors /* error handling */ ); +#endif #ifdef MS_WIN32 @@ -1134,11 +1182,13 @@ PyObject *unicode /* Unicode object */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ const char *errors /* error handling */ ); +#endif #endif /* MS_WIN32 */ @@ -1166,12 +1216,14 @@ */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyUnicode_EncodeDecimal( Py_UNICODE *s, /* Unicode buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ char *output, /* Output buffer; must have size >= length */ const char *errors /* error handling */ ); +#endif /* --- File system encoding ---------------------------------------------- */ @@ -1438,26 +1490,31 @@ PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); +#ifndef Py_LIMITED_API /* Externally visible for str.strip(unicode) */ PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( PyUnicodeObject *self, int striptype, PyObject *sepobj ); +#endif /* Using the current locale, insert the thousands grouping into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer, Py_ssize_t n_buffer, Py_UNICODE *digits, Py_ssize_t n_digits, Py_ssize_t min_width); +#endif /* Using explicit passed-in values, insert the thousands grouping into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, Py_ssize_t n_buffer, Py_UNICODE *digits, @@ -1465,10 +1522,12 @@ Py_ssize_t min_width, const char *grouping, const char *thousands_sep); +#endif /* === Characters Type APIs =============================================== */ /* Helper array used by Py_UNICODE_ISSPACE(). */ +#ifndef Py_LIMITED_API PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; /* These should not be used directly. Use the Py_UNICODE_IS* and @@ -1594,6 +1653,7 @@ PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( PyObject *unicode ); +#endif /* Py_LIMITED_API */ #ifdef __cplusplus } Modified: python/branches/py3k/Include/warnings.h ============================================================================== --- python/branches/py3k/Include/warnings.h (original) +++ python/branches/py3k/Include/warnings.h Fri Dec 3 21:14:31 2010 @@ -4,7 +4,9 @@ extern "C" { #endif +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) _PyWarnings_Init(void); +#endif PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t); PyAPI_FUNC(int) PyErr_WarnFormat(PyObject *, Py_ssize_t, const char *, ...); @@ -12,7 +14,9 @@ const char *, PyObject *); /* DEPRECATED: Use PyErr_WarnEx() instead. */ +#ifndef Py_LIMITED_API #define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) +#endif #ifdef __cplusplus } Modified: python/branches/py3k/Include/weakrefobject.h ============================================================================== --- python/branches/py3k/Include/weakrefobject.h (original) +++ python/branches/py3k/Include/weakrefobject.h Fri Dec 3 21:14:31 2010 @@ -12,6 +12,7 @@ /* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, * and CallableProxyType. */ +#ifndef Py_LIMITED_API struct _PyWeakReference { PyObject_HEAD @@ -37,6 +38,7 @@ PyWeakReference *wr_prev; PyWeakReference *wr_next; }; +#endif PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; @@ -62,9 +64,11 @@ PyObject *callback); PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); +#ifndef Py_LIMITED_API PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); +#endif #define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object) Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Fri Dec 3 21:14:31 2010 @@ -641,6 +641,9 @@ $(BYTESTR_DEPS) \ $(srcdir)/Objects/stringlib/formatter.h +Objects/typeobject.o: $(srcdir)/Objects/typeslots.inc +$(srcdir)/Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py + $(PYTHON) $(srcdir)/Objects/typeslots.py < $(srcdir)/Include/typeslots.h > $(srcdir)/Objects/typeslots.inc ############################################################################ # Header files Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 21:14:31 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- PEP 384 (Defining a Stable ABI) is implemented. + - Issue #2690: Range objects support negative indices and slicing - Issue #9915: Speed up sorting with a key. Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Fri Dec 3 21:14:31 2010 @@ -1155,7 +1155,7 @@ result = -1; goto done; } - result = PyUnicode_AsWideChar((PyUnicodeObject *)value, + result = PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, self->b_size/sizeof(wchar_t)); if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) @@ -4174,7 +4174,7 @@ PyObject *np; Py_ssize_t start, stop, step, slicelen, cur, i; - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, self->b_length, &start, &stop, &step, &slicelen) < 0) { return NULL; @@ -4308,7 +4308,7 @@ else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen, otherlen, i, cur; - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, self->b_length, &start, &stop, &step, &slicelen) < 0) { return -1; Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Fri Dec 3 21:14:31 2010 @@ -1214,7 +1214,7 @@ } else Py_INCREF(value); - len = PyUnicode_AsWideChar((PyUnicodeObject *)value, chars, 2); + len = PyUnicode_AsWideChar(value, chars, 2); if (len != 1) { Py_DECREF(value); PyErr_SetString(PyExc_TypeError, @@ -1292,7 +1292,7 @@ } else if (size < length-1) /* copy terminating NUL character if there is space */ size += 1; - PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size); + PyUnicode_AsWideChar(value, (wchar_t *)ptr, size); return value; } Modified: python/branches/py3k/Modules/_elementtree.c ============================================================================== --- python/branches/py3k/Modules/_elementtree.c (original) +++ python/branches/py3k/Modules/_elementtree.c Fri Dec 3 21:14:31 2010 @@ -1272,7 +1272,7 @@ if (!self->extra) return PyList_New(0); - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, self->extra->length, &start, &stop, &step, &slicelen) < 0) { return NULL; @@ -1331,7 +1331,7 @@ if (!self->extra) element_new_extra(self, NULL); - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, self->extra->length, &start, &stop, &step, &slicelen) < 0) { return -1; Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Fri Dec 3 21:14:31 2010 @@ -1398,7 +1398,7 @@ if (buffer == NULL) return PyErr_NoMemory(); - size = PyUnicode_AsWideChar((PyUnicodeObject*)unicode, buffer, buflen); + size = PyUnicode_AsWideChar(unicode, buffer, buflen); if (size == -1) { PyMem_Free(buffer); return NULL; Modified: python/branches/py3k/Modules/arraymodule.c ============================================================================== --- python/branches/py3k/Modules/arraymodule.c (original) +++ python/branches/py3k/Modules/arraymodule.c Fri Dec 3 21:14:31 2010 @@ -2112,7 +2112,7 @@ arrayobject* ar; int itemsize = self->ob_descr->itemsize; - if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self), + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -2183,7 +2183,7 @@ return (*self->ob_descr->setitem)(self, i, value); } else if (PySlice_Check(item)) { - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return -1; Modified: python/branches/py3k/Modules/getpath.c ============================================================================== --- python/branches/py3k/Modules/getpath.c (original) +++ python/branches/py3k/Modules/getpath.c Fri Dec 3 21:14:31 2010 @@ -361,7 +361,7 @@ decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape"); if (decoded != NULL) { Py_ssize_t k; - k = PyUnicode_AsWideChar((PyUnicodeObject*)decoded, + k = PyUnicode_AsWideChar(decoded, rel_builddir_path, MAXPATHLEN); Py_DECREF(decoded); if (k >= 0) { Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Fri Dec 3 21:14:31 2010 @@ -762,7 +762,7 @@ else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx((PySliceObject *)item, self->size, + if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelen) < 0) { return NULL; } @@ -888,7 +888,7 @@ Py_ssize_t start, stop, step, slicelen; Py_buffer vbuf; - if (PySlice_GetIndicesEx((PySliceObject *)item, + if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelen) < 0) { return -1; Added: python/branches/py3k/Modules/xxlimited.c ============================================================================== --- (empty file) +++ python/branches/py3k/Modules/xxlimited.c Fri Dec 3 21:14:31 2010 @@ -0,0 +1,283 @@ + +/* Use this file as a template to start implementing a module that + also declares object types. All occurrences of 'Xxo' should be changed + to something reasonable for your objects. After that, all other + occurrences of 'xx' should be changed to something reasonable for your + module. If your module is named foo your sourcefile should be named + foomodule.c. + + You will probably want to delete all references to 'x_attr' and add + your own types of attributes instead. Maybe you want to name your + local variables other than 'self'. If your object type is needed in + other files, you'll have to create a file "foobarobject.h"; see + floatobject.h for an example. */ + +/* Xxo objects */ + +#include "Python.h" + +static PyObject *ErrorObject; + +typedef struct { + PyObject_HEAD + PyObject *x_attr; /* Attributes dictionary */ +} XxoObject; + +static PyObject *Xxo_Type; + +#define XxoObject_Check(v) (Py_TYPE(v) == Xxo_Type) + +static XxoObject * +newXxoObject(PyObject *arg) +{ + XxoObject *self; + self = PyObject_New(XxoObject, (PyTypeObject*)Xxo_Type); + if (self == NULL) + return NULL; + self->x_attr = NULL; + return self; +} + +/* Xxo methods */ + +static void +Xxo_dealloc(XxoObject *self) +{ + Py_XDECREF(self->x_attr); + PyObject_Del(self); +} + +static PyObject * +Xxo_demo(XxoObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":demo")) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef Xxo_methods[] = { + {"demo", (PyCFunction)Xxo_demo, METH_VARARGS, + PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +Xxo_getattro(XxoObject *self, PyObject *name) +{ + if (self->x_attr != NULL) { + PyObject *v = PyDict_GetItem(self->x_attr, name); + if (v != NULL) { + Py_INCREF(v); + return v; + } + } + return PyObject_GenericGetAttr((PyObject *)self, name); +} + +static int +Xxo_setattr(XxoObject *self, char *name, PyObject *v) +{ + if (self->x_attr == NULL) { + self->x_attr = PyDict_New(); + if (self->x_attr == NULL) + return -1; + } + if (v == NULL) { + int rv = PyDict_DelItemString(self->x_attr, name); + if (rv < 0) + PyErr_SetString(PyExc_AttributeError, + "delete non-existing Xxo attribute"); + return rv; + } + else + return PyDict_SetItemString(self->x_attr, name, v); +} + +static PyType_Slot Xxo_Type_slots[] = { + {Py_tp_dealloc, Xxo_dealloc}, + {Py_tp_getattro, Xxo_getattro}, + {Py_tp_setattr, Xxo_setattr}, + {Py_tp_methods, Xxo_methods}, + {0, 0}, +}; + +static PyType_Spec Xxo_Type_spec = { + "xxmodule.Xxo", + NULL, + sizeof(XxoObject), + 0, + Py_TPFLAGS_DEFAULT, + Xxo_Type_slots +}; + +/* --------------------------------------------------------------------- */ + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(xx_foo_doc, +"foo(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +xx_foo(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) + return NULL; + res = i+j; /* XXX Do something here */ + return PyLong_FromLong(res); +} + + +/* Function of no arguments returning new Xxo object */ + +static PyObject * +xx_new(PyObject *self, PyObject *args) +{ + XxoObject *rv; + + if (!PyArg_ParseTuple(args, ":new")) + return NULL; + rv = newXxoObject(args); + if (rv == NULL) + return NULL; + return (PyObject *)rv; +} + +/* Test bad format character */ + +static PyObject * +xx_roj(PyObject *self, PyObject *args) +{ + PyObject *a; + long b; + if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + + +/* ---------- */ + +static PyType_Slot Str_Type_slots[] = { + {Py_tp_base, NULL}, /* filled out in module init function */ + {0, 0}, +}; + +static PyType_Spec Str_Type_spec = { + "xxlimited.Str", + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Str_Type_slots +}; + +/* ---------- */ + +static PyObject * +null_richcompare(PyObject *self, PyObject *other, int op) +{ + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + +static PyType_Slot Null_Type_slots[] = { + {Py_tp_base, NULL}, /* filled out in module init */ + {Py_tp_new, NULL}, + {Py_tp_richcompare, null_richcompare}, + {0, 0} +}; + +static PyType_Spec Null_Type_spec = { + "xxlimited.Null", + NULL, /* doc */ + 0, /* basicsize */ + 0, /* itemsize */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Null_Type_slots +}; + +/* ---------- */ + +/* List of functions defined in the module */ + +static PyMethodDef xx_methods[] = { + {"roj", xx_roj, METH_VARARGS, + PyDoc_STR("roj(a,b) -> None")}, + {"foo", xx_foo, METH_VARARGS, + xx_foo_doc}, + {"new", xx_new, METH_VARARGS, + PyDoc_STR("new() -> new Xx object")}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"This is a template module just for instruction."); + +/* Initialization function for the module (*must* be called PyInit_xx) */ + + +static struct PyModuleDef xxmodule = { + PyModuleDef_HEAD_INIT, + "xx", + module_doc, + -1, + xx_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_xxlimited(void) +{ + PyObject *m = NULL; + PyObject *o; + + /* Due to cross platform compiler issues the slots must be filled + * here. It's required for portability to Windows without requiring + * C++. */ + Null_Type_slots[0].pfunc = &PyBaseObject_Type; + Null_Type_slots[1].pfunc = PyType_GenericNew; + Str_Type_slots[0].pfunc = &PyUnicode_Type; + + Xxo_Type = PyType_FromSpec(&Xxo_Type_spec); + if (Xxo_Type == NULL) + goto fail; + + /* Create the module and add the functions */ + m = PyModule_Create(&xxmodule); + if (m == NULL) + goto fail; + + /* Add some symbolic constants to the module */ + if (ErrorObject == NULL) { + ErrorObject = PyErr_NewException("xx.error", NULL, NULL); + if (ErrorObject == NULL) + goto fail; + } + Py_INCREF(ErrorObject); + PyModule_AddObject(m, "error", ErrorObject); + + /* Add Str */ + o = PyType_FromSpec(&Str_Type_spec); + if (o == NULL) + goto fail; + PyModule_AddObject(m, "Str", o); + + /* Add Null */ + o = PyType_FromSpec(&Null_Type_spec); + if (o == NULL) + goto fail; + PyModule_AddObject(m, "Null", o); + return m; + fail: + Py_XDECREF(m); + return NULL; +} Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Fri Dec 3 21:14:31 2010 @@ -389,7 +389,7 @@ } else if (PySlice_Check(index)) { Py_ssize_t start, stop, step, slicelength, cur, i; - if (PySlice_GetIndicesEx((PySliceObject *)index, + if (PySlice_GetIndicesEx(index, PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; @@ -573,7 +573,7 @@ } } else if (PySlice_Check(index)) { - if (PySlice_GetIndicesEx((PySliceObject *)index, + if (PySlice_GetIndicesEx(index, PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelen) < 0) { return -1; Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Fri Dec 3 21:14:31 2010 @@ -911,7 +911,7 @@ char* result_buf; PyObject* result; - if (PySlice_GetIndicesEx((PySliceObject*)item, + if (PySlice_GetIndicesEx(item, PyBytes_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; Modified: python/branches/py3k/Objects/funcobject.c ============================================================================== --- python/branches/py3k/Objects/funcobject.c (original) +++ python/branches/py3k/Objects/funcobject.c Fri Dec 3 21:14:31 2010 @@ -627,7 +627,7 @@ } result = PyEval_EvalCodeEx( - (PyCodeObject *)PyFunction_GET_CODE(func), + PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), (PyObject *)NULL, &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg), k, nk, d, nd, Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Fri Dec 3 21:14:31 2010 @@ -2397,7 +2397,7 @@ PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self), + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -2446,7 +2446,7 @@ else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self), + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return -1; } Modified: python/branches/py3k/Objects/memoryobject.c ============================================================================== --- python/branches/py3k/Objects/memoryobject.c (original) +++ python/branches/py3k/Objects/memoryobject.c Fri Dec 3 21:14:31 2010 @@ -599,7 +599,7 @@ else if (PySlice_Check(key)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + if (PySlice_GetIndicesEx(key, get_shape0(view), &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -678,7 +678,7 @@ else if (PySlice_Check(key)) { Py_ssize_t stop, step; - if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + if (PySlice_GetIndicesEx(key, get_shape0(view), &start, &stop, &step, &len) < 0) { return -1; } Modified: python/branches/py3k/Objects/moduleobject.c ============================================================================== --- python/branches/py3k/Objects/moduleobject.c (original) +++ python/branches/py3k/Objects/moduleobject.c Fri Dec 3 21:14:31 2010 @@ -74,7 +74,7 @@ module->m_base.m_index = max_module_number; } name = module->m_name; - if (module_api_version != PYTHON_API_VERSION) { + if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { int err; err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "Python C API version mismatch for module %.100s: " Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Fri Dec 3 21:14:31 2010 @@ -1755,7 +1755,6 @@ #endif - /* Hack to force loading of pycapsule.o */ PyTypeObject *_PyCapsule_hack = &PyCapsule_Type; @@ -1900,6 +1899,19 @@ } } +#ifndef Py_TRACE_REFS +/* For Py_LIMITED_API, we need an out-of-line version of _Py_Dealloc. + Define this here, so we can undefine the macro. */ +#undef _Py_Dealloc +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +void +_Py_Dealloc(PyObject *op) +{ + _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA + (*Py_TYPE(op)->tp_dealloc)(op); +} +#endif + #ifdef __cplusplus } #endif Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Fri Dec 3 21:14:31 2010 @@ -431,7 +431,6 @@ return range_item(self, i); } if (PySlice_Check(item)) { - PySliceObject *slice = (PySliceObject*)item; Py_ssize_t start, stop, step, len, rlen; rangeobject *result; PyObject *substart = NULL, *substep = NULL, *substop = NULL; @@ -441,7 +440,7 @@ return NULL; } - if (PySlice_GetIndicesEx(slice, rlen, + if (PySlice_GetIndicesEx(item, rlen, &start, &stop, &step, &len) < 0) { return NULL; } @@ -450,7 +449,7 @@ Py_INCREF(substep); } else { /* NB: slice step != Py_None here */ - substep = PyNumber_Multiply(self->step, slice->step); + substep = PyNumber_Multiply(self->step, ((PySliceObject*)item)->step); if (substep == NULL) goto fail; } Modified: python/branches/py3k/Objects/sliceobject.c ============================================================================== --- python/branches/py3k/Objects/sliceobject.c (original) +++ python/branches/py3k/Objects/sliceobject.c Fri Dec 3 21:14:31 2010 @@ -99,9 +99,10 @@ } int -PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, +PySlice_GetIndices(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { + PySliceObject *r = (PySliceObject*)_r; /* XXX support long ints */ if (r->step == Py_None) { *step = 1; @@ -130,10 +131,11 @@ } int -PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, +PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) { + PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ Py_ssize_t defstart, defstop; @@ -256,7 +258,7 @@ return NULL; } - if (PySlice_GetIndicesEx(self, ilen, &start, &stop, + if (PySlice_GetIndicesEx((PyObject*)self, ilen, &start, &stop, &step, &slicelength) < 0) { return NULL; } Modified: python/branches/py3k/Objects/structseq.c ============================================================================== --- python/branches/py3k/Objects/structseq.c (original) +++ python/branches/py3k/Objects/structseq.c Fri Dec 3 21:14:31 2010 @@ -43,6 +43,18 @@ return (PyObject*)obj; } +void +PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v) +{ + PyStructSequence_SET_ITEM(op, i, v); +} + +PyObject* +PyStructSequence_GetItem(PyObject* op, Py_ssize_t i) +{ + return PyStructSequence_GET_ITEM(op, i); +} + static void structseq_dealloc(PyStructSequence *obj) { @@ -365,3 +377,11 @@ SET_DICT_FROM_INT(real_length_key, n_members); SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); } + +PyTypeObject* +PyStructSequence_NewType(PyStructSequence_Desc *desc) +{ + PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + PyStructSequence_InitType(result, desc); + return result; +} Modified: python/branches/py3k/Objects/tupleobject.c ============================================================================== --- python/branches/py3k/Objects/tupleobject.c (original) +++ python/branches/py3k/Objects/tupleobject.c Fri Dec 3 21:14:31 2010 @@ -689,7 +689,7 @@ PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx((PySliceObject*)item, + if (PySlice_GetIndicesEx(item, PyTuple_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Fri Dec 3 21:14:31 2010 @@ -2304,6 +2304,44 @@ return (PyObject *)type; } +static short slotoffsets[] = { + -1, /* invalid slot */ +#include "typeslots.inc" +}; + +PyObject* PyType_FromSpec(PyType_Spec *spec) +{ + PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + char *res_start = (char*)res; + PyType_Slot *slot; + + res->ht_name = PyUnicode_FromString(spec->name); + if (!res->ht_name) + goto fail; + res->ht_type.tp_name = _PyUnicode_AsString(res->ht_name); + if (!res->ht_type.tp_name) + goto fail; + + res->ht_type.tp_basicsize = spec->basicsize; + res->ht_type.tp_itemsize = spec->itemsize; + res->ht_type.tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + + for (slot = spec->slots; slot->slot; slot++) { + if (slot->slot >= sizeof(slotoffsets)/sizeof(slotoffsets[0])) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto fail; + } + *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + } + + return (PyObject*)res; + + fail: + Py_DECREF(res); + return NULL; +} + + /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ PyObject * Added: python/branches/py3k/Objects/typeslots.inc ============================================================================== --- (empty file) +++ python/branches/py3k/Objects/typeslots.inc Fri Dec 3 21:14:31 2010 @@ -0,0 +1,71 @@ +offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), +offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), +offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), +offsetof(PyHeapTypeObject, as_mapping.mp_length), +offsetof(PyHeapTypeObject, as_mapping.mp_subscript), +offsetof(PyHeapTypeObject, as_number.nb_absolute), +offsetof(PyHeapTypeObject, as_number.nb_add), +offsetof(PyHeapTypeObject, as_number.nb_and), +offsetof(PyHeapTypeObject, as_number.nb_bool), +offsetof(PyHeapTypeObject, as_number.nb_divmod), +offsetof(PyHeapTypeObject, as_number.nb_float), +offsetof(PyHeapTypeObject, as_number.nb_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_index), +offsetof(PyHeapTypeObject, as_number.nb_inplace_add), +offsetof(PyHeapTypeObject, as_number.nb_inplace_and), +offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply), +offsetof(PyHeapTypeObject, as_number.nb_inplace_or), +offsetof(PyHeapTypeObject, as_number.nb_inplace_power), +offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder), +offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract), +offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_xor), +offsetof(PyHeapTypeObject, as_number.nb_int), +offsetof(PyHeapTypeObject, as_number.nb_invert), +offsetof(PyHeapTypeObject, as_number.nb_lshift), +offsetof(PyHeapTypeObject, as_number.nb_multiply), +offsetof(PyHeapTypeObject, as_number.nb_negative), +offsetof(PyHeapTypeObject, as_number.nb_or), +offsetof(PyHeapTypeObject, as_number.nb_positive), +offsetof(PyHeapTypeObject, as_number.nb_power), +offsetof(PyHeapTypeObject, as_number.nb_remainder), +offsetof(PyHeapTypeObject, as_number.nb_rshift), +offsetof(PyHeapTypeObject, as_number.nb_subtract), +offsetof(PyHeapTypeObject, as_number.nb_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_xor), +offsetof(PyHeapTypeObject, as_sequence.sq_ass_item), +offsetof(PyHeapTypeObject, as_sequence.sq_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_contains), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat), +offsetof(PyHeapTypeObject, as_sequence.sq_item), +offsetof(PyHeapTypeObject, as_sequence.sq_length), +offsetof(PyHeapTypeObject, as_sequence.sq_repeat), +offsetof(PyHeapTypeObject, ht_type.tp_alloc), +offsetof(PyHeapTypeObject, ht_type.tp_base), +offsetof(PyHeapTypeObject, ht_type.tp_bases), +offsetof(PyHeapTypeObject, ht_type.tp_call), +offsetof(PyHeapTypeObject, ht_type.tp_clear), +offsetof(PyHeapTypeObject, ht_type.tp_dealloc), +offsetof(PyHeapTypeObject, ht_type.tp_del), +offsetof(PyHeapTypeObject, ht_type.tp_descr_get), +offsetof(PyHeapTypeObject, ht_type.tp_descr_set), +offsetof(PyHeapTypeObject, ht_type.tp_doc), +offsetof(PyHeapTypeObject, ht_type.tp_getattr), +offsetof(PyHeapTypeObject, ht_type.tp_getattro), +offsetof(PyHeapTypeObject, ht_type.tp_hash), +offsetof(PyHeapTypeObject, ht_type.tp_init), +offsetof(PyHeapTypeObject, ht_type.tp_is_gc), +offsetof(PyHeapTypeObject, ht_type.tp_iter), +offsetof(PyHeapTypeObject, ht_type.tp_iternext), +offsetof(PyHeapTypeObject, ht_type.tp_methods), +offsetof(PyHeapTypeObject, ht_type.tp_new), +offsetof(PyHeapTypeObject, ht_type.tp_repr), +offsetof(PyHeapTypeObject, ht_type.tp_richcompare), +offsetof(PyHeapTypeObject, ht_type.tp_setattr), +offsetof(PyHeapTypeObject, ht_type.tp_setattro), +offsetof(PyHeapTypeObject, ht_type.tp_str), +offsetof(PyHeapTypeObject, ht_type.tp_traverse), Added: python/branches/py3k/Objects/typeslots.py ============================================================================== --- (empty file) +++ python/branches/py3k/Objects/typeslots.py Fri Dec 3 21:14:31 2010 @@ -0,0 +1,24 @@ +#!/usr/bin/python +# Usage: typeslots.py < Include/typeslots.h > typeslots.inc + +import sys, re + +res = {} +for line in sys.stdin: + m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) + member = m.group(1) + if member.startswith("tp_"): + member = "ht_type."+member + elif member.startswith("nb_"): + member = "as_number."+member + elif member.startswith("mp_"): + member = "as_mapping."+member + elif member.startswith("sq_"): + member = "as_sequence."+member + elif member.startswith("bf_"): + member = "as_buffer."+member + res[int(m.group(2))] = member + +M = max(res.keys())+1 +for i in range(1,M): + print "offsetof(PyHeapTypeObject, %s)," % res[i] Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Fri Dec 3 21:14:31 2010 @@ -1263,7 +1263,7 @@ } Py_ssize_t -PyUnicode_AsWideChar(PyUnicodeObject *unicode, +PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) { @@ -1271,7 +1271,7 @@ PyErr_BadInternalCall(); return -1; } - return unicode_aswidechar(unicode, w, size); + return unicode_aswidechar((PyUnicodeObject*)unicode, w, size); } wchar_t* @@ -9222,7 +9222,7 @@ Py_UNICODE* result_buf; PyObject* result; - if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self), + if (PySlice_GetIndicesEx(item, PyUnicode_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } Modified: python/branches/py3k/PC/getpathp.c ============================================================================== --- python/branches/py3k/PC/getpathp.c (original) +++ python/branches/py3k/PC/getpathp.c Fri Dec 3 21:14:31 2010 @@ -707,3 +707,38 @@ calculate_path(); return progpath; } + +/* Load python3.dll before loading any extension module that might refer + to it. That way, we can be sure that always the python3.dll corresponding + to this python DLL is loaded, not a python3.dll that might be on the path + by chance. + Return whether the DLL was found. +*/ +static int python3_checked = 0; +static HANDLE hPython3; +int +_Py_CheckPython3() +{ + wchar_t py3path[MAXPATHLEN+1]; + wchar_t *s; + if (python3_checked) + return hPython3 != NULL; + python3_checked = 1; + + /* If there is a python3.dll next to the python3y.dll, + assume this is a build tree; use that DLL */ + wcscpy(py3path, dllpath); + s = wcsrchr(py3path, L'\\'); + if (!s) + s = py3path; + wcscpy(s, L"\\python3.dll"); + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (hPython3 != NULL) + return 1; + + /* Check sys.prefix\DLLs\python3.dll */ + wcscpy(py3path, Py_GetPrefix()); + wcscat(py3path, L"\\DLLs\\python3.dll"); + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + return hPython3 != NULL; +} Modified: python/branches/py3k/PC/pyconfig.h ============================================================================== --- python/branches/py3k/PC/pyconfig.h (original) +++ python/branches/py3k/PC/pyconfig.h Fri Dec 3 21:14:31 2010 @@ -318,8 +318,10 @@ /* So MSVC users need not specify the .lib file in their Makefile (other compilers are generally taken care of by distutils.) */ -# ifdef _DEBUG +# if defined(_DEBUG) # pragma comment(lib,"python32_d.lib") +# elif defined(Py_LIMITED_API) +# pragma comment(lib,"python3.lib") # else # pragma comment(lib,"python32.lib") # endif /* _DEBUG */ Added: python/branches/py3k/PC/python3.def ============================================================================== --- (empty file) +++ python/branches/py3k/PC/python3.def Fri Dec 3 21:14:31 2010 @@ -0,0 +1,698 @@ +LIBRARY "python3" +EXPORTS + PyArg_Parse=python32.PyArg_Parse + PyArg_ParseTuple=python32.PyArg_ParseTuple + PyArg_ParseTupleAndKeywords=python32.PyArg_ParseTupleAndKeywords + PyArg_UnpackTuple=python32.PyArg_UnpackTuple + PyArg_VaParse=python32.PyArg_VaParse + PyArg_VaParseTupleAndKeywords=python32.PyArg_VaParseTupleAndKeywords + PyArg_ValidateKeywordArguments=python32.PyArg_ValidateKeywordArguments + PyBaseObject_Type=python32.PyBaseObject_Type DATA + PyBool_FromLong=python32.PyBool_FromLong + PyBool_Type=python32.PyBool_Type DATA + PyBuffer_FillContiguousStrides=python32.PyBuffer_FillContiguousStrides + PyBuffer_FillInfo=python32.PyBuffer_FillInfo + PyBuffer_FromContiguous=python32.PyBuffer_FromContiguous + PyBuffer_GetPointer=python32.PyBuffer_GetPointer + PyBuffer_IsContiguous=python32.PyBuffer_IsContiguous + PyBuffer_Release=python32.PyBuffer_Release + PyBuffer_ToContiguous=python32.PyBuffer_ToContiguous + PyByteArrayIter_Type=python32.PyByteArrayIter_Type DATA + PyByteArray_AsString=python32.PyByteArray_AsString + PyByteArray_Concat=python32.PyByteArray_Concat + PyByteArray_FromObject=python32.PyByteArray_FromObject + PyByteArray_FromStringAndSize=python32.PyByteArray_FromStringAndSize + PyByteArray_Resize=python32.PyByteArray_Resize + PyByteArray_Size=python32.PyByteArray_Size + PyByteArray_Type=python32.PyByteArray_Type DATA + PyBytesIter_Type=python32.PyBytesIter_Type DATA + PyBytes_AsString=python32.PyBytes_AsString + PyBytes_AsStringAndSize=python32.PyBytes_AsStringAndSize + PyBytes_Concat=python32.PyBytes_Concat + PyBytes_ConcatAndDel=python32.PyBytes_ConcatAndDel + PyBytes_DecodeEscape=python32.PyBytes_DecodeEscape + PyBytes_FromFormat=python32.PyBytes_FromFormat + PyBytes_FromFormatV=python32.PyBytes_FromFormatV + PyBytes_FromObject=python32.PyBytes_FromObject + PyBytes_FromString=python32.PyBytes_FromString + PyBytes_FromStringAndSize=python32.PyBytes_FromStringAndSize + PyBytes_Repr=python32.PyBytes_Repr + PyBytes_Size=python32.PyBytes_Size + PyBytes_Type=python32.PyBytes_Type DATA + PyCFunction_Call=python32.PyCFunction_Call + PyCFunction_ClearFreeList=python32.PyCFunction_ClearFreeList + PyCFunction_GetFlags=python32.PyCFunction_GetFlags + PyCFunction_GetFunction=python32.PyCFunction_GetFunction + PyCFunction_GetSelf=python32.PyCFunction_GetSelf + PyCFunction_NewEx=python32.PyCFunction_NewEx + PyCFunction_Type=python32.PyCFunction_Type DATA + PyCallIter_New=python32.PyCallIter_New + PyCallIter_Type=python32.PyCallIter_Type DATA + PyCallable_Check=python32.PyCallable_Check + PyCapsule_GetContext=python32.PyCapsule_GetContext + PyCapsule_GetDestructor=python32.PyCapsule_GetDestructor + PyCapsule_GetName=python32.PyCapsule_GetName + PyCapsule_GetPointer=python32.PyCapsule_GetPointer + PyCapsule_Import=python32.PyCapsule_Import + PyCapsule_IsValid=python32.PyCapsule_IsValid + PyCapsule_New=python32.PyCapsule_New + PyCapsule_SetContext=python32.PyCapsule_SetContext + PyCapsule_SetDestructor=python32.PyCapsule_SetDestructor + PyCapsule_SetName=python32.PyCapsule_SetName + PyCapsule_SetPointer=python32.PyCapsule_SetPointer + PyCapsule_Type=python32.PyCapsule_Type DATA + PyClassMethodDescr_Type=python32.PyClassMethodDescr_Type DATA + PyCodec_BackslashReplaceErrors=python32.PyCodec_BackslashReplaceErrors + PyCodec_Decode=python32.PyCodec_Decode + PyCodec_Decoder=python32.PyCodec_Decoder + PyCodec_Encode=python32.PyCodec_Encode + PyCodec_Encoder=python32.PyCodec_Encoder + PyCodec_IgnoreErrors=python32.PyCodec_IgnoreErrors + PyCodec_IncrementalDecoder=python32.PyCodec_IncrementalDecoder + PyCodec_IncrementalEncoder=python32.PyCodec_IncrementalEncoder + PyCodec_KnownEncoding=python32.PyCodec_KnownEncoding + PyCodec_LookupError=python32.PyCodec_LookupError + PyCodec_Register=python32.PyCodec_Register + PyCodec_RegisterError=python32.PyCodec_RegisterError + PyCodec_ReplaceErrors=python32.PyCodec_ReplaceErrors + PyCodec_StreamReader=python32.PyCodec_StreamReader + PyCodec_StreamWriter=python32.PyCodec_StreamWriter + PyCodec_StrictErrors=python32.PyCodec_StrictErrors + PyCodec_XMLCharRefReplaceErrors=python32.PyCodec_XMLCharRefReplaceErrors + PyComplex_FromDoubles=python32.PyComplex_FromDoubles + PyComplex_ImagAsDouble=python32.PyComplex_ImagAsDouble + PyComplex_RealAsDouble=python32.PyComplex_RealAsDouble + PyComplex_Type=python32.PyComplex_Type DATA + PyDescr_NewClassMethod=python32.PyDescr_NewClassMethod + PyDescr_NewGetSet=python32.PyDescr_NewGetSet + PyDescr_NewMember=python32.PyDescr_NewMember + PyDescr_NewMethod=python32.PyDescr_NewMethod + PyDictItems_Type=python32.PyDictItems_Type DATA + PyDictIterItem_Type=python32.PyDictIterItem_Type DATA + PyDictIterKey_Type=python32.PyDictIterKey_Type DATA + PyDictIterValue_Type=python32.PyDictIterValue_Type DATA + PyDictKeys_Type=python32.PyDictKeys_Type DATA + PyDictProxy_New=python32.PyDictProxy_New + PyDictProxy_Type=python32.PyDictProxy_Type DATA + PyDictValues_Type=python32.PyDictValues_Type DATA + PyDict_Clear=python32.PyDict_Clear + PyDict_Contains=python32.PyDict_Contains + PyDict_Copy=python32.PyDict_Copy + PyDict_DelItem=python32.PyDict_DelItem + PyDict_DelItemString=python32.PyDict_DelItemString + PyDict_GetItem=python32.PyDict_GetItem + PyDict_GetItemString=python32.PyDict_GetItemString + PyDict_GetItemWithError=python32.PyDict_GetItemWithError + PyDict_Items=python32.PyDict_Items + PyDict_Keys=python32.PyDict_Keys + PyDict_Merge=python32.PyDict_Merge + PyDict_MergeFromSeq2=python32.PyDict_MergeFromSeq2 + PyDict_New=python32.PyDict_New + PyDict_Next=python32.PyDict_Next + PyDict_SetItem=python32.PyDict_SetItem + PyDict_SetItemString=python32.PyDict_SetItemString + PyDict_Size=python32.PyDict_Size + PyDict_Type=python32.PyDict_Type DATA + PyDict_Update=python32.PyDict_Update + PyDict_Values=python32.PyDict_Values + PyEllipsis_Type=python32.PyEllipsis_Type DATA + PyEnum_Type=python32.PyEnum_Type DATA + PyErr_BadArgument=python32.PyErr_BadArgument + PyErr_BadInternalCall=python32.PyErr_BadInternalCall + PyErr_CheckSignals=python32.PyErr_CheckSignals + PyErr_Clear=python32.PyErr_Clear + PyErr_Display=python32.PyErr_Display + PyErr_ExceptionMatches=python32.PyErr_ExceptionMatches + PyErr_Fetch=python32.PyErr_Fetch + PyErr_Format=python32.PyErr_Format + PyErr_GivenExceptionMatches=python32.PyErr_GivenExceptionMatches + PyErr_NewException=python32.PyErr_NewException + PyErr_NewExceptionWithDoc=python32.PyErr_NewExceptionWithDoc + PyErr_NoMemory=python32.PyErr_NoMemory + PyErr_NormalizeException=python32.PyErr_NormalizeException + PyErr_Occurred=python32.PyErr_Occurred + PyErr_Print=python32.PyErr_Print + PyErr_PrintEx=python32.PyErr_PrintEx + PyErr_ProgramText=python32.PyErr_ProgramText + PyErr_Restore=python32.PyErr_Restore + PyErr_SetFromErrno=python32.PyErr_SetFromErrno + PyErr_SetFromErrnoWithFilename=python32.PyErr_SetFromErrnoWithFilename + PyErr_SetFromErrnoWithFilenameObject=python32.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetInterrupt=python32.PyErr_SetInterrupt + PyErr_SetNone=python32.PyErr_SetNone + PyErr_SetObject=python32.PyErr_SetObject + PyErr_SetString=python32.PyErr_SetString + PyErr_SyntaxLocation=python32.PyErr_SyntaxLocation + PyErr_WarnEx=python32.PyErr_WarnEx + PyErr_WarnExplicit=python32.PyErr_WarnExplicit + PyErr_WarnFormat=python32.PyErr_WarnFormat + PyErr_WriteUnraisable=python32.PyErr_WriteUnraisable + PyEval_AcquireLock=python32.PyEval_AcquireLock + PyEval_AcquireThread=python32.PyEval_AcquireThread + PyEval_CallFunction=python32.PyEval_CallFunction + PyEval_CallMethod=python32.PyEval_CallMethod + PyEval_CallObjectWithKeywords=python32.PyEval_CallObjectWithKeywords + PyEval_EvalCode=python32.PyEval_EvalCode + PyEval_EvalCodeEx=python32.PyEval_EvalCodeEx + PyEval_EvalFrame=python32.PyEval_EvalFrame + PyEval_EvalFrameEx=python32.PyEval_EvalFrameEx + PyEval_GetBuiltins=python32.PyEval_GetBuiltins + PyEval_GetCallStats=python32.PyEval_GetCallStats + PyEval_GetFrame=python32.PyEval_GetFrame + PyEval_GetFuncDesc=python32.PyEval_GetFuncDesc + PyEval_GetFuncName=python32.PyEval_GetFuncName + PyEval_GetGlobals=python32.PyEval_GetGlobals + PyEval_GetLocals=python32.PyEval_GetLocals + PyEval_InitThreads=python32.PyEval_InitThreads + PyEval_ReInitThreads=python32.PyEval_ReInitThreads + PyEval_ReleaseLock=python32.PyEval_ReleaseLock + PyEval_ReleaseThread=python32.PyEval_ReleaseThread + PyEval_RestoreThread=python32.PyEval_RestoreThread + PyEval_SaveThread=python32.PyEval_SaveThread + PyEval_ThreadsInitialized=python32.PyEval_ThreadsInitialized + PyExc_ArithmeticError=python32.PyExc_ArithmeticError DATA + PyExc_AssertionError=python32.PyExc_AssertionError DATA + PyExc_AttributeError=python32.PyExc_AttributeError DATA + PyExc_BaseException=python32.PyExc_BaseException DATA + PyExc_BufferError=python32.PyExc_BufferError DATA + PyExc_BytesWarning=python32.PyExc_BytesWarning DATA + PyExc_DeprecationWarning=python32.PyExc_DeprecationWarning DATA + PyExc_EOFError=python32.PyExc_EOFError DATA + PyExc_EnvironmentError=python32.PyExc_EnvironmentError DATA + PyExc_Exception=python32.PyExc_Exception DATA + PyExc_FloatingPointError=python32.PyExc_FloatingPointError DATA + PyExc_FutureWarning=python32.PyExc_FutureWarning DATA + PyExc_GeneratorExit=python32.PyExc_GeneratorExit DATA + PyExc_IOError=python32.PyExc_IOError DATA + PyExc_ImportError=python32.PyExc_ImportError DATA + PyExc_ImportWarning=python32.PyExc_ImportWarning DATA + PyExc_IndentationError=python32.PyExc_IndentationError DATA + PyExc_IndexError=python32.PyExc_IndexError DATA + PyExc_KeyError=python32.PyExc_KeyError DATA + PyExc_KeyboardInterrupt=python32.PyExc_KeyboardInterrupt DATA + PyExc_LookupError=python32.PyExc_LookupError DATA + PyExc_MemoryError=python32.PyExc_MemoryError DATA + PyExc_MemoryErrorInst=python32.PyExc_MemoryErrorInst DATA + PyExc_NameError=python32.PyExc_NameError DATA + PyExc_NotImplementedError=python32.PyExc_NotImplementedError DATA + PyExc_OSError=python32.PyExc_OSError DATA + PyExc_OverflowError=python32.PyExc_OverflowError DATA + PyExc_PendingDeprecationWarning=python32.PyExc_PendingDeprecationWarning DATA + PyExc_RecursionErrorInst=python32.PyExc_RecursionErrorInst DATA + PyExc_ReferenceError=python32.PyExc_ReferenceError DATA + PyExc_RuntimeError=python32.PyExc_RuntimeError DATA + PyExc_RuntimeWarning=python32.PyExc_RuntimeWarning DATA + PyExc_StopIteration=python32.PyExc_StopIteration DATA + PyExc_SyntaxError=python32.PyExc_SyntaxError DATA + PyExc_SyntaxWarning=python32.PyExc_SyntaxWarning DATA + PyExc_SystemError=python32.PyExc_SystemError DATA + PyExc_SystemExit=python32.PyExc_SystemExit DATA + PyExc_TabError=python32.PyExc_TabError DATA + PyExc_TypeError=python32.PyExc_TypeError DATA + PyExc_UnboundLocalError=python32.PyExc_UnboundLocalError DATA + PyExc_UnicodeDecodeError=python32.PyExc_UnicodeDecodeError DATA + PyExc_UnicodeEncodeError=python32.PyExc_UnicodeEncodeError DATA + PyExc_UnicodeError=python32.PyExc_UnicodeError DATA + PyExc_UnicodeTranslateError=python32.PyExc_UnicodeTranslateError DATA + PyExc_UnicodeWarning=python32.PyExc_UnicodeWarning DATA + PyExc_UserWarning=python32.PyExc_UserWarning DATA + PyExc_ValueError=python32.PyExc_ValueError DATA + PyExc_Warning=python32.PyExc_Warning DATA + PyExc_ZeroDivisionError=python32.PyExc_ZeroDivisionError DATA + PyException_GetCause=python32.PyException_GetCause + PyException_GetContext=python32.PyException_GetContext + PyException_GetTraceback=python32.PyException_GetTraceback + PyException_SetCause=python32.PyException_SetCause + PyException_SetContext=python32.PyException_SetContext + PyException_SetTraceback=python32.PyException_SetTraceback + PyFile_FromFd=python32.PyFile_FromFd + PyFile_GetLine=python32.PyFile_GetLine + PyFile_WriteObject=python32.PyFile_WriteObject + PyFile_WriteString=python32.PyFile_WriteString + PyFilter_Type=python32.PyFilter_Type DATA + PyFloat_AsDouble=python32.PyFloat_AsDouble + PyFloat_FromDouble=python32.PyFloat_FromDouble + PyFloat_FromString=python32.PyFloat_FromString + PyFloat_GetInfo=python32.PyFloat_GetInfo + PyFloat_GetMax=python32.PyFloat_GetMax + PyFloat_GetMin=python32.PyFloat_GetMin + PyFloat_Type=python32.PyFloat_Type DATA + PyFrozenSet_New=python32.PyFrozenSet_New + PyFrozenSet_Type=python32.PyFrozenSet_Type DATA + PyGC_Collect=python32.PyGC_Collect + PyGILState_Ensure=python32.PyGILState_Ensure + PyGILState_GetThisThreadState=python32.PyGILState_GetThisThreadState + PyGILState_Release=python32.PyGILState_Release + PyGetSetDescr_Type=python32.PyGetSetDescr_Type DATA + PyImport_AddModule=python32.PyImport_AddModule + PyImport_AppendInittab=python32.PyImport_AppendInittab + PyImport_Cleanup=python32.PyImport_Cleanup + PyImport_ExecCodeModule=python32.PyImport_ExecCodeModule + PyImport_ExecCodeModuleEx=python32.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleWithPathnames=python32.PyImport_ExecCodeModuleWithPathnames + PyImport_GetImporter=python32.PyImport_GetImporter + PyImport_GetMagicNumber=python32.PyImport_GetMagicNumber + PyImport_GetMagicTag=python32.PyImport_GetMagicTag + PyImport_GetModuleDict=python32.PyImport_GetModuleDict + PyImport_Import=python32.PyImport_Import + PyImport_ImportFrozenModule=python32.PyImport_ImportFrozenModule + PyImport_ImportModule=python32.PyImport_ImportModule + PyImport_ImportModuleLevel=python32.PyImport_ImportModuleLevel + PyImport_ImportModuleNoBlock=python32.PyImport_ImportModuleNoBlock + PyImport_ReloadModule=python32.PyImport_ReloadModule + PyInterpreterState_Clear=python32.PyInterpreterState_Clear + PyInterpreterState_Delete=python32.PyInterpreterState_Delete + PyInterpreterState_New=python32.PyInterpreterState_New + PyIter_Next=python32.PyIter_Next + PyListIter_Type=python32.PyListIter_Type DATA + PyListRevIter_Type=python32.PyListRevIter_Type DATA + PyList_Append=python32.PyList_Append + PyList_AsTuple=python32.PyList_AsTuple + PyList_GetItem=python32.PyList_GetItem + PyList_GetSlice=python32.PyList_GetSlice + PyList_Insert=python32.PyList_Insert + PyList_New=python32.PyList_New + PyList_Reverse=python32.PyList_Reverse + PyList_SetItem=python32.PyList_SetItem + PyList_SetSlice=python32.PyList_SetSlice + PyList_Size=python32.PyList_Size + PyList_Sort=python32.PyList_Sort + PyList_Type=python32.PyList_Type DATA + PyLongRangeIter_Type=python32.PyLongRangeIter_Type DATA + PyLong_AsDouble=python32.PyLong_AsDouble + PyLong_AsLong=python32.PyLong_AsLong + PyLong_AsLongAndOverflow=python32.PyLong_AsLongAndOverflow + PyLong_AsLongLong=python32.PyLong_AsLongLong + PyLong_AsLongLongAndOverflow=python32.PyLong_AsLongLongAndOverflow + PyLong_AsSize_t=python32.PyLong_AsSize_t + PyLong_AsSsize_t=python32.PyLong_AsSsize_t + PyLong_AsUnsignedLong=python32.PyLong_AsUnsignedLong + PyLong_AsUnsignedLongLong=python32.PyLong_AsUnsignedLongLong + PyLong_AsUnsignedLongLongMask=python32.PyLong_AsUnsignedLongLongMask + PyLong_AsUnsignedLongMask=python32.PyLong_AsUnsignedLongMask + PyLong_AsVoidPtr=python32.PyLong_AsVoidPtr + PyLong_FromDouble=python32.PyLong_FromDouble + PyLong_FromLong=python32.PyLong_FromLong + PyLong_FromLongLong=python32.PyLong_FromLongLong + PyLong_FromSize_t=python32.PyLong_FromSize_t + PyLong_FromSsize_t=python32.PyLong_FromSsize_t + PyLong_FromString=python32.PyLong_FromString + PyLong_FromUnsignedLong=python32.PyLong_FromUnsignedLong + PyLong_FromUnsignedLongLong=python32.PyLong_FromUnsignedLongLong + PyLong_FromVoidPtr=python32.PyLong_FromVoidPtr + PyLong_GetInfo=python32.PyLong_GetInfo + PyLong_Type=python32.PyLong_Type DATA + PyMap_Type=python32.PyMap_Type DATA + PyMapping_Check=python32.PyMapping_Check + PyMapping_GetItemString=python32.PyMapping_GetItemString + PyMapping_HasKey=python32.PyMapping_HasKey + PyMapping_HasKeyString=python32.PyMapping_HasKeyString + PyMapping_Items=python32.PyMapping_Items + PyMapping_Keys=python32.PyMapping_Keys + PyMapping_Length=python32.PyMapping_Length + PyMapping_SetItemString=python32.PyMapping_SetItemString + PyMapping_Size=python32.PyMapping_Size + PyMapping_Values=python32.PyMapping_Values + PyMem_Free=python32.PyMem_Free + PyMem_Malloc=python32.PyMem_Malloc + PyMem_Realloc=python32.PyMem_Realloc + PyMemberDescr_Type=python32.PyMemberDescr_Type DATA + PyMemoryView_FromBuffer=python32.PyMemoryView_FromBuffer + PyMemoryView_FromObject=python32.PyMemoryView_FromObject + PyMemoryView_GetContiguous=python32.PyMemoryView_GetContiguous + PyMemoryView_Type=python32.PyMemoryView_Type DATA + PyMethodDescr_Type=python32.PyMethodDescr_Type DATA + PyModule_AddIntConstant=python32.PyModule_AddIntConstant + PyModule_AddObject=python32.PyModule_AddObject + PyModule_AddStringConstant=python32.PyModule_AddStringConstant + PyModule_Create2=python32.PyModule_Create2 + PyModule_GetDef=python32.PyModule_GetDef + PyModule_GetDict=python32.PyModule_GetDict + PyModule_GetFilename=python32.PyModule_GetFilename + PyModule_GetFilenameObject=python32.PyModule_GetFilenameObject + PyModule_GetName=python32.PyModule_GetName + PyModule_GetState=python32.PyModule_GetState + PyModule_New=python32.PyModule_New + PyModule_Type=python32.PyModule_Type DATA + PyNullImporter_Type=python32.PyNullImporter_Type DATA + PyNumber_Absolute=python32.PyNumber_Absolute + PyNumber_Add=python32.PyNumber_Add + PyNumber_And=python32.PyNumber_And + PyNumber_AsSsize_t=python32.PyNumber_AsSsize_t + PyNumber_Check=python32.PyNumber_Check + PyNumber_Divmod=python32.PyNumber_Divmod + PyNumber_Float=python32.PyNumber_Float + PyNumber_FloorDivide=python32.PyNumber_FloorDivide + PyNumber_InPlaceAdd=python32.PyNumber_InPlaceAdd + PyNumber_InPlaceAnd=python32.PyNumber_InPlaceAnd + PyNumber_InPlaceFloorDivide=python32.PyNumber_InPlaceFloorDivide + PyNumber_InPlaceLshift=python32.PyNumber_InPlaceLshift + PyNumber_InPlaceMultiply=python32.PyNumber_InPlaceMultiply + PyNumber_InPlaceOr=python32.PyNumber_InPlaceOr + PyNumber_InPlacePower=python32.PyNumber_InPlacePower + PyNumber_InPlaceRemainder=python32.PyNumber_InPlaceRemainder + PyNumber_InPlaceRshift=python32.PyNumber_InPlaceRshift + PyNumber_InPlaceSubtract=python32.PyNumber_InPlaceSubtract + PyNumber_InPlaceTrueDivide=python32.PyNumber_InPlaceTrueDivide + PyNumber_InPlaceXor=python32.PyNumber_InPlaceXor + PyNumber_Index=python32.PyNumber_Index + PyNumber_Invert=python32.PyNumber_Invert + PyNumber_Long=python32.PyNumber_Long + PyNumber_Lshift=python32.PyNumber_Lshift + PyNumber_Multiply=python32.PyNumber_Multiply + PyNumber_Negative=python32.PyNumber_Negative + PyNumber_Or=python32.PyNumber_Or + PyNumber_Positive=python32.PyNumber_Positive + PyNumber_Power=python32.PyNumber_Power + PyNumber_Remainder=python32.PyNumber_Remainder + PyNumber_Rshift=python32.PyNumber_Rshift + PyNumber_Subtract=python32.PyNumber_Subtract + PyNumber_ToBase=python32.PyNumber_ToBase + PyNumber_TrueDivide=python32.PyNumber_TrueDivide + PyNumber_Xor=python32.PyNumber_Xor + PyOS_AfterFork=python32.PyOS_AfterFork + PyOS_InitInterrupts=python32.PyOS_InitInterrupts + PyOS_InputHook=python32.PyOS_InputHook DATA + PyOS_InterruptOccurred=python32.PyOS_InterruptOccurred + PyOS_ReadlineFunctionPointer=python32.PyOS_ReadlineFunctionPointer DATA + PyOS_double_to_string=python32.PyOS_double_to_string + PyOS_getsig=python32.PyOS_getsig + PyOS_mystricmp=python32.PyOS_mystricmp + PyOS_mystrnicmp=python32.PyOS_mystrnicmp + PyOS_setsig=python32.PyOS_setsig + PyOS_snprintf=python32.PyOS_snprintf + PyOS_string_to_double=python32.PyOS_string_to_double + PyOS_strtol=python32.PyOS_strtol + PyOS_strtoul=python32.PyOS_strtoul + PyOS_vsnprintf=python32.PyOS_vsnprintf + PyObject_ASCII=python32.PyObject_ASCII + PyObject_AsCharBuffer=python32.PyObject_AsCharBuffer + PyObject_AsFileDescriptor=python32.PyObject_AsFileDescriptor + PyObject_AsReadBuffer=python32.PyObject_AsReadBuffer + PyObject_AsWriteBuffer=python32.PyObject_AsWriteBuffer + PyObject_Bytes=python32.PyObject_Bytes + PyObject_Call=python32.PyObject_Call + PyObject_CallFunction=python32.PyObject_CallFunction + PyObject_CallFunctionObjArgs=python32.PyObject_CallFunctionObjArgs + PyObject_CallMethod=python32.PyObject_CallMethod + PyObject_CallMethodObjArgs=python32.PyObject_CallMethodObjArgs + PyObject_CallObject=python32.PyObject_CallObject + PyObject_CheckReadBuffer=python32.PyObject_CheckReadBuffer + PyObject_ClearWeakRefs=python32.PyObject_ClearWeakRefs + PyObject_CopyData=python32.PyObject_CopyData + PyObject_DelItem=python32.PyObject_DelItem + PyObject_DelItemString=python32.PyObject_DelItemString + PyObject_Dir=python32.PyObject_Dir + PyObject_Format=python32.PyObject_Format + PyObject_Free=python32.PyObject_Free + PyObject_GC_Del=python32.PyObject_GC_Del + PyObject_GC_Track=python32.PyObject_GC_Track + PyObject_GC_UnTrack=python32.PyObject_GC_UnTrack + PyObject_GenericGetAttr=python32.PyObject_GenericGetAttr + PyObject_GenericSetAttr=python32.PyObject_GenericSetAttr + PyObject_GetAttr=python32.PyObject_GetAttr + PyObject_GetAttrString=python32.PyObject_GetAttrString + PyObject_GetBuffer=python32.PyObject_GetBuffer + PyObject_GetItem=python32.PyObject_GetItem + PyObject_GetIter=python32.PyObject_GetIter + PyObject_HasAttr=python32.PyObject_HasAttr + PyObject_HasAttrString=python32.PyObject_HasAttrString + PyObject_Hash=python32.PyObject_Hash + PyObject_HashNotImplemented=python32.PyObject_HashNotImplemented + PyObject_Init=python32.PyObject_Init + PyObject_InitVar=python32.PyObject_InitVar + PyObject_IsInstance=python32.PyObject_IsInstance + PyObject_IsSubclass=python32.PyObject_IsSubclass + PyObject_IsTrue=python32.PyObject_IsTrue + PyObject_Length=python32.PyObject_Length + PyObject_Malloc=python32.PyObject_Malloc + PyObject_Not=python32.PyObject_Not + PyObject_Realloc=python32.PyObject_Realloc + PyObject_Repr=python32.PyObject_Repr + PyObject_RichCompare=python32.PyObject_RichCompare + PyObject_RichCompareBool=python32.PyObject_RichCompareBool + PyObject_SelfIter=python32.PyObject_SelfIter + PyObject_SetAttr=python32.PyObject_SetAttr + PyObject_SetAttrString=python32.PyObject_SetAttrString + PyObject_SetItem=python32.PyObject_SetItem + PyObject_Size=python32.PyObject_Size + PyObject_Str=python32.PyObject_Str + PyObject_Type=python32.PyObject_Type DATA + PyParser_SimpleParseFileFlags=python32.PyParser_SimpleParseFileFlags + PyParser_SimpleParseStringFlags=python32.PyParser_SimpleParseStringFlags + PyProperty_Type=python32.PyProperty_Type DATA + PyRangeIter_Type=python32.PyRangeIter_Type DATA + PyRange_Type=python32.PyRange_Type DATA + PyReversed_Type=python32.PyReversed_Type DATA + PySeqIter_New=python32.PySeqIter_New + PySeqIter_Type=python32.PySeqIter_Type DATA + PySequence_Check=python32.PySequence_Check + PySequence_Concat=python32.PySequence_Concat + PySequence_Contains=python32.PySequence_Contains + PySequence_Count=python32.PySequence_Count + PySequence_DelItem=python32.PySequence_DelItem + PySequence_DelSlice=python32.PySequence_DelSlice + PySequence_Fast=python32.PySequence_Fast + PySequence_GetItem=python32.PySequence_GetItem + PySequence_GetSlice=python32.PySequence_GetSlice + PySequence_In=python32.PySequence_In + PySequence_InPlaceConcat=python32.PySequence_InPlaceConcat + PySequence_InPlaceRepeat=python32.PySequence_InPlaceRepeat + PySequence_Index=python32.PySequence_Index + PySequence_Length=python32.PySequence_Length + PySequence_List=python32.PySequence_List + PySequence_Repeat=python32.PySequence_Repeat + PySequence_SetItem=python32.PySequence_SetItem + PySequence_SetSlice=python32.PySequence_SetSlice + PySequence_Size=python32.PySequence_Size + PySequence_Tuple=python32.PySequence_Tuple + PySetIter_Type=python32.PySetIter_Type DATA + PySet_Add=python32.PySet_Add + PySet_Clear=python32.PySet_Clear + PySet_Contains=python32.PySet_Contains + PySet_Discard=python32.PySet_Discard + PySet_New=python32.PySet_New + PySet_Pop=python32.PySet_Pop + PySet_Size=python32.PySet_Size + PySet_Type=python32.PySet_Type DATA + PySlice_GetIndices=python32.PySlice_GetIndices + PySlice_GetIndicesEx=python32.PySlice_GetIndicesEx + PySlice_New=python32.PySlice_New + PySlice_Type=python32.PySlice_Type DATA + PySortWrapper_Type=python32.PySortWrapper_Type DATA + PyState_FindModule=python32.PyState_FindModule + PyStructSequence_GetItem=python32.PyStructSequence_GetItem + PyStructSequence_New=python32.PyStructSequence_New + PyStructSequence_NewType=python32.PyStructSequence_NewType + PyStructSequence_SetItem=python32.PyStructSequence_SetItem + PySuper_Type=python32.PySuper_Type DATA + PySys_AddWarnOption=python32.PySys_AddWarnOption + PySys_AddWarnOptionUnicode=python32.PySys_AddWarnOptionUnicode + PySys_FormatStderr=python32.PySys_FormatStderr + PySys_FormatStdout=python32.PySys_FormatStdout + PySys_GetObject=python32.PySys_GetObject + PySys_HasWarnOptions=python32.PySys_HasWarnOptions + PySys_ResetWarnOptions=python32.PySys_ResetWarnOptions + PySys_SetArgv=python32.PySys_SetArgv + PySys_SetArgvEx=python32.PySys_SetArgvEx + PySys_SetObject=python32.PySys_SetObject + PySys_SetPath=python32.PySys_SetPath + PySys_WriteStderr=python32.PySys_WriteStderr + PySys_WriteStdout=python32.PySys_WriteStdout + PyThreadState_Clear=python32.PyThreadState_Clear + PyThreadState_Delete=python32.PyThreadState_Delete + PyThreadState_DeleteCurrent=python32.PyThreadState_DeleteCurrent + PyThreadState_Get=python32.PyThreadState_Get + PyThreadState_GetDict=python32.PyThreadState_GetDict + PyThreadState_New=python32.PyThreadState_New + PyThreadState_SetAsyncExc=python32.PyThreadState_SetAsyncExc + PyThreadState_Swap=python32.PyThreadState_Swap + PyTraceBack_Here=python32.PyTraceBack_Here + PyTraceBack_Print=python32.PyTraceBack_Print + PyTraceBack_Type=python32.PyTraceBack_Type DATA + PyTupleIter_Type=python32.PyTupleIter_Type DATA + PyTuple_ClearFreeList=python32.PyTuple_ClearFreeList + PyTuple_GetItem=python32.PyTuple_GetItem + PyTuple_GetSlice=python32.PyTuple_GetSlice + PyTuple_New=python32.PyTuple_New + PyTuple_Pack=python32.PyTuple_Pack + PyTuple_SetItem=python32.PyTuple_SetItem + PyTuple_Size=python32.PyTuple_Size + PyTuple_Type=python32.PyTuple_Type DATA + PyType_ClearCache=python32.PyType_ClearCache + PyType_FromSpec=python32.PyType_FromSpec + PyType_GenericAlloc=python32.PyType_GenericAlloc + PyType_GenericNew=python32.PyType_GenericNew + PyType_IsSubtype=python32.PyType_IsSubtype + PyType_Modified=python32.PyType_Modified + PyType_Ready=python32.PyType_Ready + PyType_Type=python32.PyType_Type DATA + PyUnicodeDecodeError_Create=python32.PyUnicodeDecodeError_Create + PyUnicodeDecodeError_GetEncoding=python32.PyUnicodeDecodeError_GetEncoding + PyUnicodeDecodeError_GetEnd=python32.PyUnicodeDecodeError_GetEnd + PyUnicodeDecodeError_GetObject=python32.PyUnicodeDecodeError_GetObject + PyUnicodeDecodeError_GetReason=python32.PyUnicodeDecodeError_GetReason + PyUnicodeDecodeError_GetStart=python32.PyUnicodeDecodeError_GetStart + PyUnicodeDecodeError_SetEnd=python32.PyUnicodeDecodeError_SetEnd + PyUnicodeDecodeError_SetReason=python32.PyUnicodeDecodeError_SetReason + PyUnicodeDecodeError_SetStart=python32.PyUnicodeDecodeError_SetStart + PyUnicodeEncodeError_GetEncoding=python32.PyUnicodeEncodeError_GetEncoding + PyUnicodeEncodeError_GetEnd=python32.PyUnicodeEncodeError_GetEnd + PyUnicodeEncodeError_GetObject=python32.PyUnicodeEncodeError_GetObject + PyUnicodeEncodeError_GetReason=python32.PyUnicodeEncodeError_GetReason + PyUnicodeEncodeError_GetStart=python32.PyUnicodeEncodeError_GetStart + PyUnicodeEncodeError_SetEnd=python32.PyUnicodeEncodeError_SetEnd + PyUnicodeEncodeError_SetReason=python32.PyUnicodeEncodeError_SetReason + PyUnicodeEncodeError_SetStart=python32.PyUnicodeEncodeError_SetStart + PyUnicodeIter_Type=python32.PyUnicodeIter_Type DATA + PyUnicodeTranslateError_GetEnd=python32.PyUnicodeTranslateError_GetEnd + PyUnicodeTranslateError_GetObject=python32.PyUnicodeTranslateError_GetObject + PyUnicodeTranslateError_GetReason=python32.PyUnicodeTranslateError_GetReason + PyUnicodeTranslateError_GetStart=python32.PyUnicodeTranslateError_GetStart + PyUnicodeTranslateError_SetEnd=python32.PyUnicodeTranslateError_SetEnd + PyUnicodeTranslateError_SetReason=python32.PyUnicodeTranslateError_SetReason + PyUnicodeTranslateError_SetStart=python32.PyUnicodeTranslateError_SetStart + PyUnicode_Append=python32.PyUnicodeUCS2_Append + PyUnicode_AppendAndDel=python32.PyUnicodeUCS2_AppendAndDel + PyUnicode_AsASCIIString=python32.PyUnicodeUCS2_AsASCIIString + PyUnicode_AsCharmapString=python32.PyUnicodeUCS2_AsCharmapString + PyUnicode_AsDecodedObject=python32.PyUnicodeUCS2_AsDecodedObject + PyUnicode_AsDecodedUnicode=python32.PyUnicodeUCS2_AsDecodedUnicode + PyUnicode_AsEncodedObject=python32.PyUnicodeUCS2_AsEncodedObject + PyUnicode_AsEncodedString=python32.PyUnicodeUCS2_AsEncodedString + PyUnicode_AsEncodedUnicode=python32.PyUnicodeUCS2_AsEncodedUnicode + PyUnicode_AsLatin1String=python32.PyUnicodeUCS2_AsLatin1String + PyUnicode_AsRawUnicodeEscapeString=python32.PyUnicodeUCS2_AsRawUnicodeEscapeString + PyUnicode_AsUTF16String=python32.PyUnicodeUCS2_AsUTF16String + PyUnicode_AsUTF32String=python32.PyUnicodeUCS2_AsUTF32String + PyUnicode_AsUTF8String=python32.PyUnicodeUCS2_AsUTF8String + PyUnicode_AsUnicodeEscapeString=python32.PyUnicodeUCS2_AsUnicodeEscapeString + PyUnicode_AsWideChar=python32.PyUnicodeUCS2_AsWideChar + PyUnicode_ClearFreelist=python32.PyUnicodeUCS2_ClearFreelist + PyUnicode_Compare=python32.PyUnicodeUCS2_Compare + PyUnicode_Concat=python32.PyUnicodeUCS2_Concat + PyUnicode_Contains=python32.PyUnicodeUCS2_Contains + PyUnicode_Count=python32.PyUnicodeUCS2_Count + PyUnicode_Decode=python32.PyUnicodeUCS2_Decode + PyUnicode_DecodeASCII=python32.PyUnicodeUCS2_DecodeASCII + PyUnicode_DecodeCharmap=python32.PyUnicodeUCS2_DecodeCharmap + PyUnicode_DecodeFSDefault=python32.PyUnicodeUCS2_DecodeFSDefault + PyUnicode_DecodeFSDefaultAndSize=python32.PyUnicodeUCS2_DecodeFSDefaultAndSize + PyUnicode_DecodeLatin1=python32.PyUnicodeUCS2_DecodeLatin1 + PyUnicode_DecodeRawUnicodeEscape=python32.PyUnicodeUCS2_DecodeRawUnicodeEscape + PyUnicode_DecodeUTF16=python32.PyUnicodeUCS2_DecodeUTF16 + PyUnicode_DecodeUTF16Stateful=python32.PyUnicodeUCS2_DecodeUTF16Stateful + PyUnicode_DecodeUTF32=python32.PyUnicodeUCS2_DecodeUTF32 + PyUnicode_DecodeUTF32Stateful=python32.PyUnicodeUCS2_DecodeUTF32Stateful + PyUnicode_DecodeUTF8=python32.PyUnicodeUCS2_DecodeUTF8 + PyUnicode_DecodeUTF8Stateful=python32.PyUnicodeUCS2_DecodeUTF8Stateful + PyUnicode_DecodeUnicodeEscape=python32.PyUnicodeUCS2_DecodeUnicodeEscape + PyUnicode_FSConverter=python32.PyUnicodeUCS2_FSConverter + PyUnicode_FSDecoder=python32.PyUnicodeUCS2_FSDecoder + PyUnicode_Find=python32.PyUnicodeUCS2_Find + PyUnicode_Format=python32.PyUnicodeUCS2_Format + PyUnicode_FromEncodedObject=python32.PyUnicodeUCS2_FromEncodedObject + PyUnicode_FromFormat=python32.PyUnicodeUCS2_FromFormat + PyUnicode_FromFormatV=python32.PyUnicodeUCS2_FromFormatV + PyUnicode_FromObject=python32.PyUnicodeUCS2_FromObject + PyUnicode_FromOrdinal=python32.PyUnicodeUCS2_FromOrdinal + PyUnicode_FromString=python32.PyUnicodeUCS2_FromString + PyUnicode_FromStringAndSize=python32.PyUnicodeUCS2_FromStringAndSize + PyUnicode_FromWideChar=python32.PyUnicodeUCS2_FromWideChar + PyUnicode_GetDefaultEncoding=python32.PyUnicodeUCS2_GetDefaultEncoding + PyUnicode_GetSize=python32.PyUnicodeUCS2_GetSize + PyUnicode_IsIdentifier=python32.PyUnicodeUCS2_IsIdentifier + PyUnicode_Join=python32.PyUnicodeUCS2_Join + PyUnicode_Partition=python32.PyUnicodeUCS2_Partition + PyUnicode_RPartition=python32.PyUnicodeUCS2_RPartition + PyUnicode_RSplit=python32.PyUnicodeUCS2_RSplit + PyUnicode_Replace=python32.PyUnicodeUCS2_Replace + PyUnicode_Resize=python32.PyUnicodeUCS2_Resize + PyUnicode_RichCompare=python32.PyUnicodeUCS2_RichCompare + PyUnicode_SetDefaultEncoding=python32.PyUnicodeUCS2_SetDefaultEncoding + PyUnicode_Split=python32.PyUnicodeUCS2_Split + PyUnicode_Splitlines=python32.PyUnicodeUCS2_Splitlines + PyUnicode_Tailmatch=python32.PyUnicodeUCS2_Tailmatch + PyUnicode_Translate=python32.PyUnicodeUCS2_Translate + PyUnicode_BuildEncodingMap=python32.PyUnicode_BuildEncodingMap + PyUnicode_CompareWithASCIIString=python32.PyUnicode_CompareWithASCIIString + PyUnicode_DecodeUTF7=python32.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python32.PyUnicode_DecodeUTF7Stateful + PyUnicode_EncodeFSDefault=python32.PyUnicode_EncodeFSDefault + PyUnicode_InternFromString=python32.PyUnicode_InternFromString + PyUnicode_InternImmortal=python32.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python32.PyUnicode_InternInPlace + PyUnicode_Type=python32.PyUnicode_Type DATA + PyWeakref_GetObject=python32.PyWeakref_GetObject DATA + PyWeakref_NewProxy=python32.PyWeakref_NewProxy + PyWeakref_NewRef=python32.PyWeakref_NewRef + PyWrapperDescr_Type=python32.PyWrapperDescr_Type DATA + PyWrapper_New=python32.PyWrapper_New + PyZip_Type=python32.PyZip_Type DATA + Py_AddPendingCall=python32.Py_AddPendingCall + Py_AtExit=python32.Py_AtExit + Py_BuildValue=python32.Py_BuildValue + Py_CompileStringFlags=python32.Py_CompileStringFlags + Py_DecRef=python32.Py_DecRef + Py_EndInterpreter=python32.Py_EndInterpreter + Py_Exit=python32.Py_Exit + Py_FatalError=python32.Py_FatalError + Py_FileSystemDefaultEncoding=python32.Py_FileSystemDefaultEncoding DATA + Py_Finalize=python32.Py_Finalize + Py_GetBuildInfo=python32.Py_GetBuildInfo + Py_GetCompiler=python32.Py_GetCompiler + Py_GetCopyright=python32.Py_GetCopyright + Py_GetExecPrefix=python32.Py_GetExecPrefix + Py_GetPath=python32.Py_GetPath + Py_GetPlatform=python32.Py_GetPlatform + Py_GetPrefix=python32.Py_GetPrefix + Py_GetProgramFullPath=python32.Py_GetProgramFullPath + Py_GetProgramName=python32.Py_GetProgramName + Py_GetPythonHome=python32.Py_GetPythonHome + Py_GetRecursionLimit=python32.Py_GetRecursionLimit + Py_GetVersion=python32.Py_GetVersion + Py_HasFileSystemDefaultEncoding=python32.Py_HasFileSystemDefaultEncoding DATA + Py_IncRef=python32.Py_IncRef + Py_Initialize=python32.Py_Initialize + Py_InitializeEx=python32.Py_InitializeEx + Py_IsInitialized=python32.Py_IsInitialized + Py_Main=python32.Py_Main + Py_MakePendingCalls=python32.Py_MakePendingCalls + Py_NewInterpreter=python32.Py_NewInterpreter + Py_ReprEnter=python32.Py_ReprEnter + Py_ReprLeave=python32.Py_ReprLeave + Py_SetProgramName=python32.Py_SetProgramName + Py_SetPythonHome=python32.Py_SetPythonHome + Py_SetRecursionLimit=python32.Py_SetRecursionLimit + Py_SymtableString=python32.Py_SymtableString + Py_VaBuildValue=python32.Py_VaBuildValue + _PyErr_BadInternalCall=python32._PyErr_BadInternalCall + _PyObject_CallFunction_SizeT=python32._PyObject_CallFunction_SizeT + _PyObject_CallMethod_SizeT=python32._PyObject_CallMethod_SizeT + _PyObject_GC_Malloc=python32._PyObject_GC_Malloc + _PyObject_GC_New=python32._PyObject_GC_New + _PyObject_GC_NewVar=python32._PyObject_GC_NewVar + _PyObject_GC_Resize=python32._PyObject_GC_Resize + _PyObject_New=python32._PyObject_New + _PyObject_NewVar=python32._PyObject_NewVar + _PyState_AddModule=python32._PyState_AddModule + _PyThreadState_Init=python32._PyThreadState_Init + _PyThreadState_Prealloc=python32._PyThreadState_Prealloc + _PyTrash_delete_later=python32._PyTrash_delete_later DATA + _PyTrash_delete_nesting=python32._PyTrash_delete_nesting DATA + _PyTrash_deposit_object=python32._PyTrash_deposit_object + _PyTrash_destroy_chain=python32._PyTrash_destroy_chain + _PyWeakref_CallableProxyType=python32._PyWeakref_CallableProxyType DATA + _PyWeakref_ProxyType=python32._PyWeakref_ProxyType DATA + _PyWeakref_RefType=python32._PyWeakref_RefType DATA + _Py_BuildValue_SizeT=python32._Py_BuildValue_SizeT + _Py_CheckRecursionLimit=python32._Py_CheckRecursionLimit DATA + _Py_CheckRecursiveCall=python32._Py_CheckRecursiveCall + _Py_Dealloc=python32._Py_Dealloc + _Py_EllipsisObject=python32._Py_EllipsisObject DATA + _Py_FalseStruct=python32._Py_FalseStruct DATA + _Py_NoneStruct=python32.Py_GetCopyright + _Py_NotImplementedStruct=python32._Py_NotImplementedStruct DATA + _Py_SwappedOp=python32._Py_SwappedOp DATA + _Py_TrueStruct=python32._Py_TrueStruct DATA + _Py_VaBuildValue_SizeT=python32._Py_VaBuildValue_SizeT Added: python/branches/py3k/PC/python3dll.c ============================================================================== --- (empty file) +++ python/branches/py3k/PC/python3dll.c Fri Dec 3 21:14:31 2010 @@ -0,0 +1,9 @@ +#include + +BOOL WINAPI +DllMain(HINSTANCE hInstDLL, + DWORD fdwReason, + LPVOID lpReserved) +{ + return TRUE; +} \ No newline at end of file Modified: python/branches/py3k/PCbuild/pcbuild.sln ============================================================================== --- python/branches/py3k/PCbuild/pcbuild.sln (original) +++ python/branches/py3k/PCbuild/pcbuild.sln Fri Dec 3 21:14:31 2010 @@ -133,6 +133,13 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" + ProjectSection(ProjectDependencies) = postProject + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -553,6 +560,32 @@ {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32 {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64 {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGUpdate|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = PGUpdate|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = PGUpdate|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.Build.0 = PGUpdate|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE Added: python/branches/py3k/PCbuild/python3dll.vcproj ============================================================================== --- (empty file) +++ python/branches/py3k/PCbuild/python3dll.vcproj Fri Dec 3 21:14:31 2010 @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: python/branches/py3k/PCbuild/xxlimited.vcproj ============================================================================== --- (empty file) +++ python/branches/py3k/PCbuild/xxlimited.vcproj Fri Dec 3 21:14:31 2010 @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Fri Dec 3 21:14:31 2010 @@ -727,7 +727,7 @@ "code object passed to eval() may not contain free variables"); return NULL; } - return PyEval_EvalCode((PyCodeObject *) cmd, globals, locals); + return PyEval_EvalCode(cmd, globals, locals); } cf.cf_flags = PyCF_SOURCE_IS_UTF8; @@ -803,7 +803,7 @@ "contain free variables"); return NULL; } - v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals); + v = PyEval_EvalCode(prog, globals, locals); } else { char *str; Modified: python/branches/py3k/Python/ceval.c ============================================================================== --- python/branches/py3k/Python/ceval.c (original) +++ python/branches/py3k/Python/ceval.c Fri Dec 3 21:14:31 2010 @@ -755,7 +755,7 @@ PyObject * -PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) +PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { return PyEval_EvalCodeEx(co, globals, locals, @@ -3059,10 +3059,11 @@ the test in the if statements in Misc/gdbinit (pystack and pystackv). */ PyObject * -PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, +PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) { + PyCodeObject* co = (PyCodeObject*)_co; register PyFrameObject *f; register PyObject *retval = NULL; register PyObject **fastlocals, **freevars; @@ -3968,7 +3969,7 @@ d = &PyTuple_GET_ITEM(argdefs, 0); nd = Py_SIZE(argdefs); } - return PyEval_EvalCodeEx(co, globals, + return PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, (*pp_stack)-n, na, (*pp_stack)-2*nk, nk, d, nd, kwdefs, PyFunction_GET_CLOSURE(func)); Modified: python/branches/py3k/Python/dynload_shlib.c ============================================================================== --- python/branches/py3k/Python/dynload_shlib.c (original) +++ python/branches/py3k/Python/dynload_shlib.c Fri Dec 3 21:14:31 2010 @@ -53,6 +53,8 @@ #else /* !__VMS */ {"." SOABI ".so", "rb", C_EXTENSION}, {"module." SOABI ".so", "rb", C_EXTENSION}, + {".abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION}, + {"module.abi" PYTHON_ABI_STRING ".so", "rb", C_EXTENSION}, {".so", "rb", C_EXTENSION}, {"module.so", "rb", C_EXTENSION}, #endif /* __VMS */ Modified: python/branches/py3k/Python/dynload_win.c ============================================================================== --- python/branches/py3k/Python/dynload_win.c (original) +++ python/branches/py3k/Python/dynload_win.c Fri Dec 3 21:14:31 2010 @@ -134,6 +134,15 @@ !strncmp(import_name,"python",6)) { char *pch; +#ifndef _DEBUG + /* In a release version, don't claim that python3.dll is + a Python DLL. */ + if (strcmp(import_name, "python3.dll") == 0) { + import_data += 20; + continue; + } +#endif + /* Ensure python prefix is followed only by numbers to the end of the basename */ pch = import_name + 6; @@ -162,13 +171,16 @@ return NULL; } - dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, const char *pathname, FILE *fp) { dl_funcptr p; char funcname[258], *import_python; +#ifndef _DEBUG + _Py_CheckPython3(); +#endif + PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname); { Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Fri Dec 3 21:14:31 2010 @@ -806,7 +806,7 @@ PyErr_Clear(); /* Not important enough to report */ Py_DECREF(v); - v = PyEval_EvalCode((PyCodeObject *)co, d, d); + v = PyEval_EvalCode(co, d, d); if (v == NULL) goto error; Py_DECREF(v); Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Fri Dec 3 21:14:31 2010 @@ -1755,7 +1755,7 @@ co = PyAST_Compile(mod, filename, flags, arena); if (co == NULL) return NULL; - v = PyEval_EvalCode(co, globals, locals); + v = PyEval_EvalCode((PyObject*)co, globals, locals); Py_DECREF(co); return v; } @@ -1785,7 +1785,7 @@ return NULL; } co = (PyCodeObject *)v; - v = PyEval_EvalCode(co, globals, locals); + v = PyEval_EvalCode((PyObject*)co, globals, locals); if (v && flags) flags->cf_flags |= (co->co_flags & PyCF_MASK); Py_DECREF(co); @@ -1817,6 +1817,14 @@ return (PyObject *)co; } +/* For use in Py_LIMITED_API */ +#undef Py_CompileString +PyObject * +PyCompileString(const char *str, const char *filename, int start) +{ + return Py_CompileStringFlags(str, filename, start, NULL); +} + struct symtable * Py_SymtableString(const char *str, const char *filename, int start) { Added: python/branches/py3k/Tools/scripts/abitype.py ============================================================================== --- (empty file) +++ python/branches/py3k/Tools/scripts/abitype.py Fri Dec 3 21:14:31 2010 @@ -0,0 +1,200 @@ +# This script converts a C file to use the PEP 384 type definition API +# Usage: abitype.py < old_code > new_code +import re, sys + +############ Simplistic C scanner ################################## +tokenizer = re.compile( + r"(?P#.*\n)" + r"|(?P/\*.*?\*/)" + r"|(?P[a-zA-Z_][a-zA-Z0-9_]*)" + r"|(?P[ \t\n]+)" + r"|(?P.)", + re.MULTILINE) + +tokens = [] +source = sys.stdin.read() +pos = 0 +while pos != len(source): + m = tokenizer.match(source, pos) + tokens.append([m.lastgroup, m.group()]) + pos += len(tokens[-1][1]) + if tokens[-1][0] == 'preproc': + # continuation lines are considered + # only in preprocess statements + while tokens[-1][1].endswith('\\\n'): + nl = source.find('\n', pos) + if nl == -1: + line = source[pos:] + else: + line = source[pos:nl+1] + tokens[-1][1] += line + pos += len(line) + +###### Replacement of PyTypeObject static instances ############## + +# classify each token, giving it a one-letter code: +# S: static +# T: PyTypeObject +# I: ident +# W: whitespace +# =, {, }, ; : themselves +def classify(): + res = [] + for t,v in tokens: + if t == 'other' and v in "={};": + res.append(v) + elif t == 'ident': + if v == 'PyTypeObject': + res.append('T') + elif v == 'static': + res.append('S') + else: + res.append('I') + elif t == 'ws': + res.append('W') + else: + res.append('.') + return ''.join(res) + +# Obtain a list of fields of a PyTypeObject, in declaration order, +# skipping ob_base +# All comments are dropped from the variable (which are typically +# just the slot names, anyway), and information is discarded whether +# the original type was static. +def get_fields(start, real_end): + pos = start + # static? + if tokens[pos][1] == 'static': + pos += 2 + # PyTypeObject + pos += 2 + # name + name = tokens[pos][1] + pos += 1 + while tokens[pos][1] != '{': + pos += 1 + pos += 1 + # PyVarObject_HEAD_INIT + while tokens[pos][0] in ('ws', 'comment'): + pos += 1 + if tokens[pos][1] != 'PyVarObject_HEAD_INIT': + raise Exception, '%s has no PyVarObject_HEAD_INIT' % name + while tokens[pos][1] != ')': + pos += 1 + pos += 1 + # field definitions: various tokens, comma-separated + fields = [] + while True: + while tokens[pos][0] in ('ws', 'comment'): + pos += 1 + end = pos + while tokens[end][1] not in ',}': + if tokens[end][1] == '(': + nesting = 1 + while nesting: + end += 1 + if tokens[end][1] == '(': nesting+=1 + if tokens[end][1] == ')': nesting-=1 + end += 1 + assert end < real_end + # join field, excluding separator and trailing ws + end1 = end-1 + while tokens[end1][0] in ('ws', 'comment'): + end1 -= 1 + fields.append(''.join(t[1] for t in tokens[pos:end1+1])) + if tokens[end][1] == '}': + break + pos = end+1 + return name, fields + +# List of type slots as of Python 3.2, omitting ob_base +typeslots = [ + 'tp_name', + 'tp_basicsize', + 'tp_itemsize', + 'tp_dealloc', + 'tp_print', + 'tp_getattr', + 'tp_setattr', + 'tp_reserved', + 'tp_repr', + 'tp_as_number', + 'tp_as_sequence', + 'tp_as_mapping', + 'tp_hash', + 'tp_call', + 'tp_str', + 'tp_getattro', + 'tp_setattro', + 'tp_as_buffer', + 'tp_flags', + 'tp_doc', + 'tp_traverse', + 'tp_clear', + 'tp_richcompare', + 'tp_weaklistoffset', + 'tp_iter', + 'iternextfunc', + 'tp_methods', + 'tp_members', + 'tp_getset', + 'tp_base', + 'tp_dict', + 'tp_descr_get', + 'tp_descr_set', + 'tp_dictoffset', + 'tp_init', + 'tp_alloc', + 'tp_new', + 'tp_free', + 'tp_is_gc', + 'tp_bases', + 'tp_mro', + 'tp_cache', + 'tp_subclasses', + 'tp_weaklist', + 'tp_del' + 'tp_version_tag' +] + +# Generate a PyType_Spec definition +def make_slots(name, fields): + res = [] + res.append('static PyType_Slot %s_slots[] = {' % name) + # defaults for spec + spec = { 'tp_doc':'NULL', 'tp_itemsize':'0' } + for i, val in enumerate(fields): + if val.endswith('0'): + continue + if typeslots[i] in ('tp_name', 'tp_doc', 'tp_basicsize', + 'tp_itemsize', 'tp_flags'): + spec[typeslots[i]] = val + continue + res.append(' {Py_%s, %s},' % (typeslots[i], val)) + res.append('};') + res.append('static PyType_Spec %s_spec = {' % name) + res.append(' %s,' % spec['tp_name']) + res.append(' %s,' % spec['tp_doc']) + res.append(' %s,' % spec['tp_basicsize']) + res.append(' %s,' % spec['tp_itemsize']) + res.append(' %s,' % spec['tp_flags']) + res.append(' %s_slots,' % name) + res.append('};\n') + return '\n'.join(res) + + +# Main loop: replace all static PyTypeObjects until +# there are none left. +while 1: + c = classify() + m = re.search('(SW)?TWIW?=W?{.*?};', c) + if not m: + break + start = m.start() + end = m.end() + name, fields = get_fields(start, m) + tokens[start:end] = [('',make_slots(name, fields))] + +# Output result to stdout +for t, v in tokens: + sys.stdout.write(v) Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Fri Dec 3 21:14:31 2010 @@ -1579,6 +1579,9 @@ ## # Uncomment these lines if you want to play with xxmodule.c ## ext = Extension('xx', ['xxmodule.c']) ## self.extensions.append(ext) + ext = Extension('xxlimited', ['xxlimited.c'], + define_macros=[('Py_LIMITED_API', 1)]) + self.extensions.append(ext) # XXX handle these, but how to detect? # *** Uncomment and edit for PIL (TkImaging) extension only: From python-checkins at python.org Fri Dec 3 23:15:19 2010 From: python-checkins at python.org (lukasz.langa) Date: Fri, 3 Dec 2010 23:15:19 +0100 (CET) Subject: [Python-checkins] r86999 - python/branches/py3k/Lib/configparser.py Message-ID: <20101203221519.D4F3AEE986@mail.python.org> Author: lukasz.langa Date: Fri Dec 3 23:15:19 2010 New Revision: 86999 Log: %s -> %r correction after review by ?ric Araujo Modified: python/branches/py3k/Lib/configparser.py Modified: python/branches/py3k/Lib/configparser.py ============================================================================== --- python/branches/py3k/Lib/configparser.py (original) +++ python/branches/py3k/Lib/configparser.py Fri Dec 3 23:15:19 2010 @@ -653,7 +653,7 @@ already exists. Raise ValueError if name is DEFAULT. """ if section == self.default_section: - raise ValueError('Invalid section name: %s' % section) + raise ValueError('Invalid section name: %r' % section) if section in self._sections: raise DuplicateSectionError(section) From python-checkins at python.org Fri Dec 3 23:29:40 2010 From: python-checkins at python.org (terry.reedy) Date: Fri, 3 Dec 2010 23:29:40 +0100 (CET) Subject: [Python-checkins] r87000 - python/branches/py3k/Lib/difflib.py Message-ID: <20101203222940.B0016EE985@mail.python.org> Author: terry.reedy Date: Fri Dec 3 23:29:40 2010 New Revision: 87000 Log: Issue 10534 deprecate isbjunk and isbpopular methods. Will add gone in 3.3 test later. Modified: python/branches/py3k/Lib/difflib.py Modified: python/branches/py3k/Lib/difflib.py ============================================================================== --- python/branches/py3k/Lib/difflib.py (original) +++ python/branches/py3k/Lib/difflib.py Fri Dec 3 23:29:40 2010 @@ -32,6 +32,7 @@ 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', 'unified_diff', 'HtmlDiff', 'Match'] +import warnings import heapq from collections import namedtuple as _namedtuple @@ -182,7 +183,7 @@ # we need to do to 'a' to change it into 'b'?" # b2j # for x in b, b2j[x] is a list of the indices (into b) - # at which x appears; junk elements do not appear + # at which x appears; junk and popular elements do not appear # fullbcount # for x in b, fullbcount[x] == the number of times x # appears in b; only materialized if really needed (used @@ -204,15 +205,6 @@ # subtle but helpful effects on the algorithm, which I'll # get around to writing up someday <0.9 wink>. # DON'T USE! Only __chain_b uses this. Use isbjunk. - # isbjunk - # for x in b, isbjunk(x) == isjunk(x) but much faster; - # it's really the __contains__ method of a hidden dict. - # DOES NOT WORK for x in a! - # isbpopular - # for x in b, isbpopular(x) is true iff b is reasonably long - # (at least 200 elements) and x accounts for more than 1 + 1% of - # its elements (when autojunk is enabled). - # DOES NOT WORK for x in a! # bjunk # the items in b for which isjunk is True. # bpopular @@ -343,12 +335,19 @@ popular.add(elt) del b2j[elt] - # Now for x in b, isjunk(x) == x in junk, but the latter is much faster. - # Since the number of *unique* junk elements is probably small, the - # memory burden of keeping this set alive is likely trivial compared to - # the size of b2j. - self.isbjunk = junk.__contains__ - self.isbpopular = popular.__contains__ + def isbjunk(self, item): + "Deprecated; use 'item in SequenceMatcher().bjunk'." + warnings.warn("'SequenceMatcher().isbjunk(item)' is deprecated;\n" + "use 'item in SMinstance.bjunk' instead.", + DeprecationWarning, 2) + return item in self.bjunk + + def isbpopular(self, item): + "Deprecated; use 'item in SequenceMatcher().bpopular'." + warnings.warn("'SequenceMatcher().isbpopular(item)' is deprecated;\n" + "use 'item in SMinstance.bpopular' instead.", + DeprecationWarning, 2) + return item in self.bpopular def find_longest_match(self, alo, ahi, blo, bhi): """Find longest matching block in a[alo:ahi] and b[blo:bhi]. @@ -406,7 +405,7 @@ # Windiff ends up at the same place as diff, but by pairing up # the unique 'b's and then matching the first two 'a's. - a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk + a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__ besti, bestj, bestsize = alo, blo, 0 # find longest junk-free match # during an iteration of the loop, j2len[j] = length of longest From python-checkins at python.org Fri Dec 3 23:50:06 2010 From: python-checkins at python.org (terry.reedy) Date: Fri, 3 Dec 2010 23:50:06 +0100 (CET) Subject: [Python-checkins] r87001 - python/branches/py3k/Misc/NEWS Message-ID: <20101203225006.6CE4FEE9E1@mail.python.org> Author: terry.reedy Date: Fri Dec 3 23:50:06 2010 New Revision: 87001 Log: Issue #10534: add NEWS entry for r86983 and r87000. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 3 23:50:06 2010 @@ -130,6 +130,9 @@ be set to False to turn off the previously undocumented 'popularity' heuristic. Patch by Terry Reedy and Eli Bendersky. +- Issue #10534: expose bjunk and bpopular sets; deprecate undocumented and now + redundant isbjunk and isbpopular methods. + - Issue #9846: zipfile is now correctly closing underlying file objects. - Issue #10459: Update CJK character names to Unicode 6.0. From python-checkins at python.org Sat Dec 4 00:11:07 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Dec 2010 00:11:07 +0100 (CET) Subject: [Python-checkins] r87002 - in python/branches/py3k/Lib/lib2to3: fixes/fix_urllib.py main.py refactor.py tests/test_refactor.py tests/test_util.py Message-ID: <20101203231107.89591EE986@mail.python.org> Author: martin.v.loewis Date: Sat Dec 4 00:11:07 2010 New Revision: 87002 Log: Merged revisions 85551,86156-86157,86464 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r85551 | benjamin.peterson | 2010-10-15 23:57:29 +0200 (Fr, 15 Okt 2010) | 1 line escape() is now in the html module ........ r86156 | georg.brandl | 2010-11-04 09:34:57 +0100 (Do, 04 Nov 2010) | 1 line Consistency fixes in option parser help texts. ........ r86157 | georg.brandl | 2010-11-04 09:35:30 +0100 (Do, 04 Nov 2010) | 1 line #10286: fix urllib class names. ........ r86464 | benjamin.peterson | 2010-11-14 16:28:52 +0100 (So, 14 Nov 2010) | 1 line match only .py files #10416 ........ Modified: python/branches/py3k/Lib/lib2to3/ (props changed) python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py python/branches/py3k/Lib/lib2to3/main.py python/branches/py3k/Lib/lib2to3/refactor.py python/branches/py3k/Lib/lib2to3/tests/test_refactor.py python/branches/py3k/Lib/lib2to3/tests/test_util.py Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py Sat Dec 4 00:11:07 2010 @@ -12,7 +12,7 @@ MAPPING = {"urllib": [ ("urllib.request", - ["URLOpener", "FancyURLOpener", "urlretrieve", + ["URLopener", "FancyURLopener", "urlretrieve", "_urlopener", "urlopen", "urlcleanup", "pathname2url", "url2pathname"]), ("urllib.parse", Modified: python/branches/py3k/Lib/lib2to3/main.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/main.py (original) +++ python/branches/py3k/Lib/lib2to3/main.py Sat Dec 4 00:11:07 2010 @@ -100,7 +100,7 @@ parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], - help="Prevent a fixer from being run.") + help="Prevent a transformation from being run") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", @@ -112,7 +112,7 @@ parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, - help="Don't write backups for modified files.") + help="Don't write backups for modified files") # Parse command line arguments refactor_stdin = False Modified: python/branches/py3k/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/refactor.py (original) +++ python/branches/py3k/Lib/lib2to3/refactor.py Sat Dec 4 00:11:07 2010 @@ -302,13 +302,14 @@ Files and subdirectories starting with '.' are skipped. """ + py_ext = os.extsep + "py" for dirpath, dirnames, filenames in os.walk(dir_name): self.log_debug("Descending into %s", dirpath) dirnames.sort() filenames.sort() for name in filenames: - if not name.startswith(".") and \ - os.path.splitext(name)[1].endswith("py"): + if (not name.startswith(".") and + os.path.splitext(name)[1] == py_ext): fullname = os.path.join(dirpath, name) self.refactor_file(fullname, write, doctests_only) # Modify dirnames in-place to remove subdirs with leading dots Modified: python/branches/py3k/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_refactor.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_refactor.py Sat Dec 4 00:11:07 2010 @@ -223,6 +223,7 @@ "hi.py", ".dumb", ".after.py", + "notpy.npy", "sappy"] expected = ["hi.py"] check(tree, expected) Modified: python/branches/py3k/Lib/lib2to3/tests/test_util.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_util.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_util.py Sat Dec 4 00:11:07 2010 @@ -568,8 +568,8 @@ def test_from_import(self): node = parse('bar()') - fixer_util.touch_import("cgi", "escape", node) - self.assertEqual(str(node), 'from cgi import escape\nbar()\n\n') + fixer_util.touch_import("html", "escape", node) + self.assertEqual(str(node), 'from html import escape\nbar()\n\n') def test_name_import(self): node = parse('bar()') From python-checkins at python.org Sat Dec 4 02:11:21 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 4 Dec 2010 02:11:21 +0100 (CET) Subject: [Python-checkins] r87003 - in python/branches/py3k: Doc/library/unittest.rst Lib/unittest/main.py Lib/unittest/test/test_program.py Misc/NEWS Message-ID: <20101204011121.E2995EE985@mail.python.org> Author: michael.foord Date: Sat Dec 4 02:11:21 2010 New Revision: 87003 Log: Issue 10620: Specifying test modules by path instead of module name to 'python -m unittest' Modified: python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Lib/unittest/main.py python/branches/py3k/Lib/unittest/test/test_program.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Sat Dec 4 02:11:21 2010 @@ -204,6 +204,16 @@ You can pass in a list with any combination of module names, and fully qualified class or method names. +Test modules can be specified by file path as well:: + + python -m unittest tests/test_something.py + +This allows you to use the shell filename completion to specify the test module. +The file specified must still be importable as a module. The path is converted +to a module name by removing the '.py' and converting path separators into '.'. +If you want to execute a test file that isn't importable as a module you should +execute the file directly instead. + You can run tests with more detail (higher verbosity) by passing in the -v flag:: python -m unittest -v test_module Modified: python/branches/py3k/Lib/unittest/main.py ============================================================================== --- python/branches/py3k/Lib/unittest/main.py (original) +++ python/branches/py3k/Lib/unittest/main.py Sat Dec 4 02:11:21 2010 @@ -58,7 +58,24 @@ in MyTestCase """ +def _convert_name(name): + # on Linux / Mac OS X 'foo.PY' is not importable, but on + # Windows it is. Simpler to do a case insensitive match + # a better check would be to check that the name is a + # valid Python module name. + if os.path.isfile(name) and name.lower().endswith('.py'): + if os.path.isabs(name): + rel_path = os.path.relpath(name, os.getcwd()) + if os.path.isabs(rel_path) or rel_path.startswith(os.pardir): + return name + name = rel_path + # on Windows both '\' and '/' are used as path + # separators. Better to replace both than rely on os.path.sep + return name[:-3].replace('\\', '.').replace('/', '.') + return name +def _convert_names(names): + return [_convert_name(name) for name in names] class TestProgram(object): """A command-line program that runs a set of tests; this is primarily @@ -153,7 +170,7 @@ # createTests will load tests from self.module self.testNames = None elif len(args) > 0: - self.testNames = args + self.testNames = _convert_names(args) if __name__ == '__main__': # to support python -m unittest ... self.module = None Modified: python/branches/py3k/Lib/unittest/test/test_program.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_program.py (original) +++ python/branches/py3k/Lib/unittest/test/test_program.py Sat Dec 4 02:11:21 2010 @@ -273,6 +273,85 @@ program.runTests() self.assertTrue(self.installed) + def _patch_isfile(self, names, exists=True): + def isfile(path): + return path in names + original = os.path.isfile + os.path.isfile = isfile + def restore(): + os.path.isfile = original + self.addCleanup(restore) + + + def testParseArgsFileNames(self): + # running tests with filenames instead of module names + program = self.program + argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt'] + self._patch_isfile(argv) + + program.createTests = lambda: None + program.parseArgs(argv) + + # note that 'wing.txt' is not a Python file so the name should + # *not* be converted to a module name + expected = ['foo', 'bar', 'baz', 'wing.txt'] + self.assertEqual(program.testNames, expected) + + + def testParseArgsFilePaths(self): + program = self.program + argv = ['progname', 'foo/bar/baz.py', 'green\\red.py'] + self._patch_isfile(argv) + + program.createTests = lambda: None + program.parseArgs(argv) + + expected = ['foo.bar.baz', 'green.red'] + self.assertEqual(program.testNames, expected) + + + def testParseArgsNonExistentFiles(self): + program = self.program + argv = ['progname', 'foo/bar/baz.py', 'green\\red.py'] + self._patch_isfile([]) + + program.createTests = lambda: None + program.parseArgs(argv) + + self.assertEqual(program.testNames, argv[1:]) + + def testParseArgsAbsolutePathsThatCanBeConverted(self): + cur_dir = os.getcwd() + program = self.program + def _join(name): + return os.path.join(cur_dir, name) + argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')] + self._patch_isfile(argv) + + program.createTests = lambda: None + program.parseArgs(argv) + + expected = ['foo.bar.baz', 'green.red'] + self.assertEqual(program.testNames, expected) + + def testParseArgsAbsolutePathsThatCannotBeConverted(self): + program = self.program + # will this test work on Windows? (is '/...' considered absolute?) + argv = ['progname', '/foo/bar/baz.py', '/green/red.py'] + self._patch_isfile(argv) + + program.createTests = lambda: None + program.parseArgs(argv) + + self.assertEqual(program.testNames, argv[1:]) + + # it may be better to use platform specific functions to normalise paths + # rather than accepting '.PY' and '\' as file seprator on Linux / Mac + # it would also be better to check that a filename is a valid module + # identifier (we have a regex for this in loader.py) + # for invalid filenames should we raise a useful error rather than + # leaving the current error message (import of filename fails) in place? + if __name__ == '__main__': unittest.main() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 02:11:21 2010 @@ -37,6 +37,13 @@ Library ------- +- Issue 10620: `python -m unittest` can accept file paths instead of module + names for running specific tests. + +- Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, + `assertNotEquals`, `assertAlmostEquals`, `assertNotAlmostEquals` and `assert_` + and replace them with the correct methods in the Python test suite. + - Issue #10272: The ssl module now raises socket.timeout instead of a generic SSLError on socket timeouts. @@ -236,10 +243,6 @@ - `python -m test` can be used to run the test suite as well as `python -m test.regrtest`. -- Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, - `assertNotEquals`, `assertAlmostEquals`, `assertNotAlmostEquals` and `assert_` - and replace them with the correct methods in the Python test suite. - - Do not fail test_socket when the IP address of the local hostname cannot be looked up. From python-checkins at python.org Sat Dec 4 02:43:59 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 4 Dec 2010 02:43:59 +0100 (CET) Subject: [Python-checkins] r87004 - python/branches/py3k/Lib/unittest/test/test_program.py Message-ID: <20101204014359.EB50DEE996@mail.python.org> Author: michael.foord Date: Sat Dec 4 02:43:59 2010 New Revision: 87004 Log: Correct comment in unittest test Modified: python/branches/py3k/Lib/unittest/test/test_program.py Modified: python/branches/py3k/Lib/unittest/test/test_program.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_program.py (original) +++ python/branches/py3k/Lib/unittest/test/test_program.py Sat Dec 4 02:43:59 2010 @@ -336,7 +336,7 @@ def testParseArgsAbsolutePathsThatCannotBeConverted(self): program = self.program - # will this test work on Windows? (is '/...' considered absolute?) + # even on Windows '/...' is considered absolute by os.path.abspath argv = ['progname', '/foo/bar/baz.py', '/green/red.py'] self._patch_isfile(argv) From python-checkins at python.org Sat Dec 4 03:19:06 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Dec 2010 03:19:06 +0100 (CET) Subject: [Python-checkins] r87005 - in python/branches/release27-maint/Lib/lib2to3: fixes/fix_urllib.py main.py refactor.py tests/test_refactor.py tests/test_util.py Message-ID: <20101204021906.3FF2BEE9B3@mail.python.org> Author: benjamin.peterson Date: Sat Dec 4 03:18:58 2010 New Revision: 87005 Log: Merged revisions 85551,86156-86157,86464 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r85551 | benjamin.peterson | 2010-10-15 16:57:29 -0500 (Fri, 15 Oct 2010) | 1 line escape() is now in the html module ........ r86156 | georg.brandl | 2010-11-04 03:34:57 -0500 (Thu, 04 Nov 2010) | 1 line Consistency fixes in option parser help texts. ........ r86157 | georg.brandl | 2010-11-04 03:35:30 -0500 (Thu, 04 Nov 2010) | 1 line #10286: fix urllib class names. ........ r86464 | benjamin.peterson | 2010-11-14 09:28:52 -0600 (Sun, 14 Nov 2010) | 1 line match only .py files #10416 ........ Modified: python/branches/release27-maint/Lib/lib2to3/ (props changed) python/branches/release27-maint/Lib/lib2to3/fixes/fix_urllib.py python/branches/release27-maint/Lib/lib2to3/main.py python/branches/release27-maint/Lib/lib2to3/refactor.py python/branches/release27-maint/Lib/lib2to3/tests/test_refactor.py python/branches/release27-maint/Lib/lib2to3/tests/test_util.py Modified: python/branches/release27-maint/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/branches/release27-maint/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/branches/release27-maint/Lib/lib2to3/fixes/fix_urllib.py Sat Dec 4 03:18:58 2010 @@ -12,7 +12,7 @@ MAPPING = {"urllib": [ ("urllib.request", - ["URLOpener", "FancyURLOpener", "urlretrieve", + ["URLopener", "FancyURLopener", "urlretrieve", "_urlopener", "urlopen", "urlcleanup", "pathname2url", "url2pathname"]), ("urllib.parse", Modified: python/branches/release27-maint/Lib/lib2to3/main.py ============================================================================== --- python/branches/release27-maint/Lib/lib2to3/main.py (original) +++ python/branches/release27-maint/Lib/lib2to3/main.py Sat Dec 4 03:18:58 2010 @@ -101,7 +101,7 @@ parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], - help="Prevent a fixer from being run.") + help="Prevent a transformation from being run") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", @@ -113,7 +113,7 @@ parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, - help="Don't write backups for modified files.") + help="Don't write backups for modified files") # Parse command line arguments refactor_stdin = False Modified: python/branches/release27-maint/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/release27-maint/Lib/lib2to3/refactor.py (original) +++ python/branches/release27-maint/Lib/lib2to3/refactor.py Sat Dec 4 03:18:58 2010 @@ -302,13 +302,14 @@ Files and subdirectories starting with '.' are skipped. """ + py_ext = os.extsep + "py" for dirpath, dirnames, filenames in os.walk(dir_name): self.log_debug("Descending into %s", dirpath) dirnames.sort() filenames.sort() for name in filenames: - if not name.startswith(".") and \ - os.path.splitext(name)[1].endswith("py"): + if (not name.startswith(".") and + os.path.splitext(name)[1] == py_ext): fullname = os.path.join(dirpath, name) self.refactor_file(fullname, write, doctests_only) # Modify dirnames in-place to remove subdirs with leading dots Modified: python/branches/release27-maint/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/branches/release27-maint/Lib/lib2to3/tests/test_refactor.py (original) +++ python/branches/release27-maint/Lib/lib2to3/tests/test_refactor.py Sat Dec 4 03:18:58 2010 @@ -223,6 +223,7 @@ "hi.py", ".dumb", ".after.py", + "notpy.npy", "sappy"] expected = ["hi.py"] check(tree, expected) Modified: python/branches/release27-maint/Lib/lib2to3/tests/test_util.py ============================================================================== --- python/branches/release27-maint/Lib/lib2to3/tests/test_util.py (original) +++ python/branches/release27-maint/Lib/lib2to3/tests/test_util.py Sat Dec 4 03:18:58 2010 @@ -568,8 +568,8 @@ def test_from_import(self): node = parse('bar()') - fixer_util.touch_import("cgi", "escape", node) - self.assertEqual(str(node), 'from cgi import escape\nbar()\n\n') + fixer_util.touch_import("html", "escape", node) + self.assertEqual(str(node), 'from html import escape\nbar()\n\n') def test_name_import(self): node = parse('bar()') From python-checkins at python.org Sat Dec 4 03:24:43 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Dec 2010 03:24:43 +0100 (CET) Subject: [Python-checkins] r87006 - in python/branches/release31-maint: Lib/lib2to3/fixes/fix_urllib.py Lib/lib2to3/main.py Lib/lib2to3/refactor.py Lib/lib2to3/tests/test_refactor.py Lib/lib2to3/tests/test_util.py Message-ID: <20101204022443.9C3F6EE98C@mail.python.org> Author: benjamin.peterson Date: Sat Dec 4 03:24:43 2010 New Revision: 87006 Log: Merged revisions 87002 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r87002 | martin.v.loewis | 2010-12-03 17:11:07 -0600 (Fri, 03 Dec 2010) | 21 lines Merged revisions 85551,86156-86157,86464 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r85551 | benjamin.peterson | 2010-10-15 23:57:29 +0200 (Fr, 15 Okt 2010) | 1 line escape() is now in the html module ........ r86156 | georg.brandl | 2010-11-04 09:34:57 +0100 (Do, 04 Nov 2010) | 1 line Consistency fixes in option parser help texts. ........ r86157 | georg.brandl | 2010-11-04 09:35:30 +0100 (Do, 04 Nov 2010) | 1 line #10286: fix urllib class names. ........ r86464 | benjamin.peterson | 2010-11-14 16:28:52 +0100 (So, 14 Nov 2010) | 1 line match only .py files #10416 ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py python/branches/release31-maint/Lib/lib2to3/main.py python/branches/release31-maint/Lib/lib2to3/refactor.py python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py python/branches/release31-maint/Lib/lib2to3/tests/test_util.py Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py Sat Dec 4 03:24:43 2010 @@ -12,7 +12,7 @@ MAPPING = {"urllib": [ ("urllib.request", - ["URLOpener", "FancyURLOpener", "urlretrieve", + ["URLopener", "FancyURLopener", "urlretrieve", "_urlopener", "urlopen", "urlcleanup", "pathname2url", "url2pathname"]), ("urllib.parse", Modified: python/branches/release31-maint/Lib/lib2to3/main.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/main.py (original) +++ python/branches/release31-maint/Lib/lib2to3/main.py Sat Dec 4 03:24:43 2010 @@ -100,7 +100,7 @@ parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], - help="Prevent a fixer from being run.") + help="Prevent a transformation from being run") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", @@ -112,7 +112,7 @@ parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, - help="Don't write backups for modified files.") + help="Don't write backups for modified files") # Parse command line arguments refactor_stdin = False Modified: python/branches/release31-maint/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/refactor.py (original) +++ python/branches/release31-maint/Lib/lib2to3/refactor.py Sat Dec 4 03:24:43 2010 @@ -302,13 +302,14 @@ Files and subdirectories starting with '.' are skipped. """ + py_ext = os.extsep + "py" for dirpath, dirnames, filenames in os.walk(dir_name): self.log_debug("Descending into %s", dirpath) dirnames.sort() filenames.sort() for name in filenames: - if not name.startswith(".") and \ - os.path.splitext(name)[1].endswith("py"): + if (not name.startswith(".") and + os.path.splitext(name)[1] == py_ext): fullname = os.path.join(dirpath, name) self.refactor_file(fullname, write, doctests_only) # Modify dirnames in-place to remove subdirs with leading dots Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py Sat Dec 4 03:24:43 2010 @@ -223,6 +223,7 @@ "hi.py", ".dumb", ".after.py", + "notpy.npy", "sappy"] expected = ["hi.py"] check(tree, expected) Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_util.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_util.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_util.py Sat Dec 4 03:24:43 2010 @@ -568,8 +568,8 @@ def test_from_import(self): node = parse('bar()') - fixer_util.touch_import("cgi", "escape", node) - self.assertEqual(str(node), 'from cgi import escape\nbar()\n\n') + fixer_util.touch_import("html", "escape", node) + self.assertEqual(str(node), 'from html import escape\nbar()\n\n') def test_name_import(self): node = parse('bar()') From python-checkins at python.org Sat Dec 4 04:38:46 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 4 Dec 2010 04:38:46 +0100 (CET) Subject: [Python-checkins] r87007 - in python/branches/py3k: Doc/c-api/unicode.rst Include/unicodeobject.h Lib/test/test_complex.py Lib/test/test_float.py Lib/test/test_int.py Lib/test/test_unicode.py Misc/NEWS Objects/complexobject.c Objects/floatobject.c Objects/longobject.c Objects/unicodeobject.c Message-ID: <20101204033846.D4B64EE9B0@mail.python.org> Author: alexander.belopolsky Date: Sat Dec 4 04:38:46 2010 New Revision: 87007 Log: Issue #10557: Fixed error messages from float() and other numeric types. Added a new API function, PyUnicode_TransformDecimalToASCII(), which transforms non-ASCII decimal digits in a Unicode string to their ASCII equivalents. Modified: python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Lib/test/test_complex.py python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Lib/test/test_int.py python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/complexobject.c python/branches/py3k/Objects/floatobject.c python/branches/py3k/Objects/longobject.c python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Doc/c-api/unicode.rst ============================================================================== --- python/branches/py3k/Doc/c-api/unicode.rst (original) +++ python/branches/py3k/Doc/c-api/unicode.rst Sat Dec 4 04:38:46 2010 @@ -328,6 +328,13 @@ Identical to :c:func:`PyUnicode_FromFormat` except that it takes exactly two arguments. +.. c:function:: PyObject* PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, Py_ssize_t size) + + Create a Unicode object by replacing all decimal digits in + :c:type:`Py_UNICODE` buffer of the given size by ASCII digits 0--9 + according to their decimal value. Return *NULL* if an exception + occurs. + .. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Sat Dec 4 04:38:46 2010 @@ -1225,6 +1225,17 @@ ); #endif +/* Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. + + Returns a new Unicode string on success, NULL on failure. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_TransformDecimalToASCII( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to transform */ + ); + /* --- File system encoding ---------------------------------------------- */ /* ParseTuple converter: encode str objects to bytes using Modified: python/branches/py3k/Lib/test/test_complex.py ============================================================================== --- python/branches/py3k/Lib/test/test_complex.py (original) +++ python/branches/py3k/Lib/test/test_complex.py Sat Dec 4 04:38:46 2010 @@ -220,6 +220,7 @@ self.assertEqual(complex(NS(1+10j)), 1+10j) self.assertRaises(TypeError, complex, OS(None)) self.assertRaises(TypeError, complex, NS(None)) + self.assertRaises(TypeError, complex, {}) self.assertAlmostEqual(complex("1+10j"), 1+10j) self.assertAlmostEqual(complex(10), 10+0j) @@ -325,6 +326,8 @@ # check that complex accepts long unicode strings self.assertEqual(type(complex("1"*500)), complex) + # check whitespace processing + self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) class EvilExc(Exception): pass Modified: python/branches/py3k/Lib/test/test_float.py ============================================================================== --- python/branches/py3k/Lib/test/test_float.py (original) +++ python/branches/py3k/Lib/test/test_float.py Sat Dec 4 04:38:46 2010 @@ -43,14 +43,30 @@ self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.") + self.assertRaises(ValueError, float, b"-") + self.assertRaises(TypeError, float, {}) + # Lone surrogate + self.assertRaises(UnicodeEncodeError, float, '\uD8F0') # check that we don't accept alternate exponent markers self.assertRaises(ValueError, float, "-1.7d29") self.assertRaises(ValueError, float, "3D-14") - self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14) + self.assertEqual(float(" \u0663.\u0661\u0664 "), 3.14) + self.assertEqual(float("\N{EM SPACE}3.14\N{EN SPACE}"), 3.14) # extra long strings should not be a problem float(b'.' + b'1'*1000) float('.' + '1'*1000) + def test_error_message(self): + testlist = ('\xbd', '123\xbd', ' 123 456 ') + for s in testlist: + try: + float(s) + except ValueError as e: + self.assertIn(s.strip(), e.args[0]) + else: + self.fail("Expected int(%r) to raise a ValueError", s) + + @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') def test_float_with_comma(self): # set locale to something that doesn't use '.' for the decimal point Modified: python/branches/py3k/Lib/test/test_int.py ============================================================================== --- python/branches/py3k/Lib/test/test_int.py (original) +++ python/branches/py3k/Lib/test/test_int.py Sat Dec 4 04:38:46 2010 @@ -20,7 +20,8 @@ (' 1\02 ', ValueError), ('', ValueError), (' ', ValueError), - (' \t\t ', ValueError) + (' \t\t ', ValueError), + ("\u0200", ValueError) ] class IntTestCases(unittest.TestCase): @@ -35,6 +36,8 @@ self.assertEqual(int(3.5), 3) self.assertEqual(int(-3.5), -3) self.assertEqual(int("-3"), -3) + self.assertEqual(int(" -3 "), -3) + self.assertEqual(int("\N{EM SPACE}-3\N{EN SPACE}"), -3) # Different base: self.assertEqual(int("10",16), 16) # Test conversion from strings and various anomalies @@ -302,6 +305,16 @@ self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) + def test_error_message(self): + testlist = ('\xbd', '123\xbd', ' 123 456 ') + for s in testlist: + try: + int(s) + except ValueError as e: + self.assertIn(s.strip(), e.args[0]) + else: + self.fail("Expected int(%r) to raise a ValueError", s) + def test_main(): run_unittest(IntTestCases) Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Dec 4 04:38:46 2010 @@ -1168,8 +1168,13 @@ # Error handling (wrong arguments) self.assertRaises(TypeError, "hello".encode, 42, 42, 42) - # Error handling (PyUnicode_EncodeDecimal()) - self.assertRaises(UnicodeError, int, "\u0200") + # Error handling (lone surrogate in PyUnicode_TransformDecimalToASCII()) + self.assertRaises(UnicodeError, int, "\ud800") + self.assertRaises(UnicodeError, int, "\udf00") + self.assertRaises(UnicodeError, float, "\ud800") + self.assertRaises(UnicodeError, float, "\udf00") + self.assertRaises(UnicodeError, complex, "\ud800") + self.assertRaises(UnicodeError, complex, "\udf00") def test_codecs(self): # Encoding Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 04:38:46 2010 @@ -222,6 +222,10 @@ C-API ----- +- Issue #10557: Added a new API function, PyUnicode_TransformDecimalToASCII(), + which transforms non-ASCII decimal digits in a Unicode string to their + ASCII equivalents. + - Issue #9518: Extend the PyModuleDef_HEAD_INIT macro to explicitly zero-initialize all fields, fixing compiler warnings seen when building extension modules with gcc with "-Wmissing-field-initializers" (implied by Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Sat Dec 4 04:38:46 2010 @@ -766,20 +766,26 @@ char *end; double x=0.0, y=0.0, z; int got_bracket=0; - char *s_buffer = NULL; + PyObject *s_buffer = NULL; Py_ssize_t len; if (PyUnicode_Check(v)) { - s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v) + 1); + Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v); + Py_UNICODE *bufptr; + s_buffer = PyUnicode_TransformDecimalToASCII( + PyUnicode_AS_UNICODE(v), buflen); if (s_buffer == NULL) - return PyErr_NoMemory(); - if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - s_buffer, - NULL)) + return NULL; + /* Replace non-ASCII whitespace with ' ' */ + bufptr = PyUnicode_AS_UNICODE(s_buffer); + for (i = 0; i < buflen; i++) { + Py_UNICODE ch = bufptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + bufptr[i] = ' '; + } + s = _PyUnicode_AsStringAndSize(s_buffer, &len); + if (s == NULL) goto error; - s = s_buffer; - len = strlen(s); } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, @@ -894,16 +900,14 @@ if (s-start != len) goto parse_error; - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return NULL; } Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Sat Dec 4 04:38:46 2010 @@ -174,22 +174,30 @@ { const char *s, *last, *end; double x; - char buffer[256]; /* for errors */ - char *s_buffer = NULL; + PyObject *s_buffer = NULL; Py_ssize_t len; PyObject *result = NULL; if (PyUnicode_Check(v)) { - s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1); + Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v); + Py_UNICODE *bufptr; + s_buffer = PyUnicode_TransformDecimalToASCII( + PyUnicode_AS_UNICODE(v), buflen); if (s_buffer == NULL) - return PyErr_NoMemory(); - if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - s_buffer, - NULL)) - goto error; - s = s_buffer; - len = strlen(s); + return NULL; + /* Replace non-ASCII whitespace with ' ' */ + bufptr = PyUnicode_AS_UNICODE(s_buffer); + for (i = 0; i < buflen; i++) { + Py_UNICODE ch = bufptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + bufptr[i] = ' '; + } + s = _PyUnicode_AsStringAndSize(s_buffer, &len); + if (s == NULL) { + Py_DECREF(s_buffer); + return NULL; + } + last = s + len; } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, @@ -197,29 +205,27 @@ return NULL; } last = s + len; - - while (Py_ISSPACE(*s)) + /* strip space */ + while (s < last && Py_ISSPACE(*s)) s++; + while (s < last - 1 && Py_ISSPACE(last[-1])) + last--; /* We don't care about overflow or underflow. If the platform * supports them, infinities and signed zeroes (on underflow) are * fine. */ x = PyOS_string_to_double(s, (char **)&end, NULL); - if (x == -1.0 && PyErr_Occurred()) - goto error; - while (Py_ISSPACE(*end)) - end++; - if (end == last) - result = PyFloat_FromDouble(x); - else { - PyOS_snprintf(buffer, sizeof(buffer), - "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); + if (end != last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", v); result = NULL; } + else if (x == -1.0 && PyErr_Occurred()) + result = NULL; + else + result = PyFloat_FromDouble(x); - error: - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return result; } Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Sat Dec 4 04:38:46 2010 @@ -2133,17 +2133,34 @@ PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) { PyObject *result; - char *buffer = (char *)PyMem_MALLOC(length+1); - - if (buffer == NULL) - return NULL; - - if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) { - PyMem_FREE(buffer); + PyObject *asciidig; + char *buffer, *end; + Py_ssize_t i, buflen; + Py_UNICODE *ptr; + + asciidig = PyUnicode_TransformDecimalToASCII(u, length); + if (asciidig == NULL) + return NULL; + /* Replace non-ASCII whitespace with ' ' */ + ptr = PyUnicode_AS_UNICODE(asciidig); + for (i = 0; i < length; i++) { + Py_UNICODE ch = ptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + ptr[i] = ' '; + } + buffer = _PyUnicode_AsStringAndSize(asciidig, &buflen); + if (buffer == NULL) { + Py_DECREF(asciidig); return NULL; } - result = PyLong_FromString(buffer, NULL, base); - PyMem_FREE(buffer); + result = PyLong_FromString(buffer, &end, base); + if (result != NULL && end != buffer + buflen) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for int()"); + Py_DECREF(result); + result = NULL; + } + Py_DECREF(asciidig); return result; } Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Sat Dec 4 04:38:46 2010 @@ -6206,6 +6206,30 @@ return NULL; } +PyObject * +PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, + Py_ssize_t length) +{ + PyObject *result; + Py_UNICODE *p; /* write pointer into result */ + Py_ssize_t i; + /* Copy to a new string */ + result = (PyObject *)_PyUnicode_New(length); + Py_UNICODE_COPY(PyUnicode_AS_UNICODE(result), s, length); + if (result == NULL) + return result; + p = PyUnicode_AS_UNICODE(result); + /* Iterate over code points */ + for (i = 0; i < length; i++) { + Py_UNICODE ch =s[i]; + if (ch > 127) { + int decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) + p[i] = '0' + decimal; + } + } + return result; +} /* --- Decimal Encoder ---------------------------------------------------- */ int PyUnicode_EncodeDecimal(Py_UNICODE *s, @@ -8967,6 +8991,13 @@ { return PyLong_FromLong(numfree); } + +static PyObject * +unicode__decimal2ascii(PyObject *self) +{ + return PyUnicode_TransformDecimalToASCII(PyUnicode_AS_UNICODE(self), + PyUnicode_GET_SIZE(self)); +} #endif PyDoc_STRVAR(startswith__doc__, @@ -9108,7 +9139,6 @@ return Py_BuildValue("(u#)", v->str, v->length); } - static PyMethodDef unicode_methods[] = { /* Order is according to common usage: often used methods should @@ -9170,8 +9200,9 @@ #endif #if 0 - /* This one is just used for debugging the implementation. */ + /* These methods are just used for debugging the implementation. */ {"freelistsize", (PyCFunction) unicode_freelistsize, METH_NOARGS}, + {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, #endif {"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS}, From solipsis at pitrou.net Sat Dec 4 04:50:42 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 04 Dec 2010 04:50:42 +0100 Subject: [Python-checkins] Daily py3k reference leaks (r87004): sum=0 Message-ID: py3k results for svn r87004 (hg cset d92c4fbe6b57) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog8Ghkso', '-x'] From python-checkins at python.org Sat Dec 4 10:04:05 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 10:04:05 +0100 (CET) Subject: [Python-checkins] r87008 - python/branches/py3k/Doc/library/dbm.rst Message-ID: <20101204090405.073A9EE985@mail.python.org> Author: georg.brandl Date: Sat Dec 4 10:04:04 2010 New Revision: 87008 Log: Fix typo. Modified: python/branches/py3k/Doc/library/dbm.rst Modified: python/branches/py3k/Doc/library/dbm.rst ============================================================================== --- python/branches/py3k/Doc/library/dbm.rst (original) +++ python/branches/py3k/Doc/library/dbm.rst Sat Dec 4 10:04:04 2010 @@ -20,7 +20,7 @@ .. function:: whichdb(filename) - This functionattempts to guess which of the several simple database modules + This function attempts to guess which of the several simple database modules available --- :mod:`dbm.gnu`, :mod:`dbm.ndbm` or :mod:`dbm.dumb` --- should be used to open a given file. From python-checkins at python.org Sat Dec 4 10:08:10 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Dec 2010 10:08:10 +0100 (CET) Subject: [Python-checkins] r87009 - python/branches/py3k/Objects/typeslots.py Message-ID: <20101204090810.61008EE985@mail.python.org> Author: martin.v.loewis Date: Sat Dec 4 10:08:10 2010 New Revision: 87009 Log: Make script 2-vs-3-agnostic. Modified: python/branches/py3k/Objects/typeslots.py Modified: python/branches/py3k/Objects/typeslots.py ============================================================================== --- python/branches/py3k/Objects/typeslots.py (original) +++ python/branches/py3k/Objects/typeslots.py Sat Dec 4 10:08:10 2010 @@ -21,4 +21,4 @@ M = max(res.keys())+1 for i in range(1,M): - print "offsetof(PyHeapTypeObject, %s)," % res[i] + print("offsetof(PyHeapTypeObject, %s)," % res[i]) From python-checkins at python.org Sat Dec 4 10:10:44 2010 From: python-checkins at python.org (gregory.p.smith) Date: Sat, 4 Dec 2010 10:10:44 +0100 (CET) Subject: [Python-checkins] r87010 - in python/branches/py3k: Doc/library/subprocess.rst Lib/subprocess.py Lib/test/test_subprocess.py Message-ID: <20101204091044.C6CBEEE985@mail.python.org> Author: gregory.p.smith Date: Sat Dec 4 10:10:44 2010 New Revision: 87010 Log: issue7213 + issue2320: Cause a DeprecationWarning if the close_fds argument is not passed to subprocess.Popen as the default value will be changing in a future Python to the safer and more often desired value of True. DeprecationWarnings that show up in a lot of existing code are controversial and have caused pain in the past. I'd like to leave this on for 3.2 beta1 and see how things go. We can remove the warning if it is deemed too noisy during any betas. (case study: the md5 and sha module DeprecationWarnings are loathed around the world as those modules were never going to be removed in 2.x and 2to3 has a fixer for code that uses them) Modified: python/branches/py3k/Doc/library/subprocess.rst python/branches/py3k/Lib/subprocess.py python/branches/py3k/Lib/test/test_subprocess.py Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Sat Dec 4 10:10:44 2010 @@ -153,10 +153,15 @@ If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and :const:`2` will be closed before the child process is executed. (Unix only). - Or, on Windows, if *close_fds* is true then no handles will be inherited by the + The recommended value for this argument is True. + On Windows, if *close_fds* is true then no handles will be inherited by the child process. Note that on Windows, you cannot set *close_fds* to true and also redirect the standard handles by setting *stdin*, *stdout* or *stderr*. +.. versionchanged:: 3.2 + Callers should always specify a *close_fds* to avoid a DeprecationWarning. + The default value for this argument will be changing in Python 3.3. + If *shell* is :const:`True`, the specified command will be executed through the shell. Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Sat Dec 4 10:10:44 2010 @@ -339,6 +339,7 @@ import gc import signal import builtins +import warnings # Exception classes used by this module. class CalledProcessError(Exception): @@ -378,7 +379,6 @@ import _posixsubprocess except ImportError: _posixsubprocess = None - import warnings warnings.warn("The _posixsubprocess module is not being used. " "Child process reliability may suffer if your " "program uses threads.", RuntimeWarning) @@ -605,7 +605,7 @@ class Popen(object): def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, - preexec_fn=None, close_fds=False, shell=False, + preexec_fn=None, close_fds=None, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False): @@ -618,6 +618,15 @@ if not isinstance(bufsize, int): raise TypeError("bufsize must be an integer") + if close_fds is None: + # Notification for http://bugs.python.org/issue7213 & issue2320 + warnings.warn( + 'The close_fds parameter was not specified. Its default' + ' will change from False to True in a future Python' + ' version. Most users should set it to True. Please' + ' update your code explicitly set close_fds.', + DeprecationWarning) + if mswindows: if preexec_fn is not None: raise ValueError("preexec_fn is not supported on Windows " Modified: python/branches/py3k/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k/Lib/test/test_subprocess.py (original) +++ python/branches/py3k/Lib/test/test_subprocess.py Sat Dec 4 10:10:44 2010 @@ -9,6 +9,7 @@ import time import re import sysconfig +import warnings try: import gc except ImportError: @@ -57,6 +58,34 @@ self.assertEqual(actual, expected, msg) +class DeprecationWarningTests(BaseTestCase): + def setUp(self): + BaseTestCase.setUp(self) + self._saved_warn = warnings.warn + self._warn_calls = [] + warnings.warn = self._record_warn + + def tearDown(self): + warnings.warn = self._saved_warn + BaseTestCase.tearDown(self) + + def _record_warn(self, *args): + """A warnings.warn function that records calls.""" + self._warn_calls.append(args) + self._saved_warn(*args) + + def testCloseFdsWarning(self): + quick_process = [sys.executable, "-c", "import sys; sys.exit(0)"] + subprocess.call(quick_process, close_fds=True) + self.assertEqual([], self._warn_calls) + subprocess.call(quick_process, close_fds=False) + self.assertEqual([], self._warn_calls) + self.assertWarns(DeprecationWarning, subprocess.call, quick_process) + self.assertEqual(1, len(self._warn_calls)) + self.assertIn('close_fds parameter was not specified', + self._warn_calls[0][0]) + + class ProcessTestCase(BaseTestCase): def test_call_seq(self): @@ -1233,7 +1262,8 @@ ProcessTestCaseNoPoll, HelperFunctionTests, CommandsWithSpaces, - ContextManagerTests) + ContextManagerTests, + DeprecationWarningTests) support.run_unittest(*unit_tests) support.reap_children() From python-checkins at python.org Sat Dec 4 10:11:42 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Dec 2010 10:11:42 +0100 (CET) Subject: [Python-checkins] r87011 - python/branches/py3k/Objects/typeslots.py Message-ID: <20101204091142.069BBEE985@mail.python.org> Author: martin.v.loewis Date: Sat Dec 4 10:11:41 2010 New Revision: 87011 Log: Add Revision keyword. Modified: python/branches/py3k/Objects/typeslots.py (contents, props changed) Modified: python/branches/py3k/Objects/typeslots.py ============================================================================== --- python/branches/py3k/Objects/typeslots.py (original) +++ python/branches/py3k/Objects/typeslots.py Sat Dec 4 10:11:41 2010 @@ -3,6 +3,7 @@ import sys, re +print("/* Generated by typeslots.py $Revision$ */") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) From python-checkins at python.org Sat Dec 4 10:12:14 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Dec 2010 10:12:14 +0100 (CET) Subject: [Python-checkins] r87012 - python/branches/py3k/Objects/typeslots.inc Message-ID: <20101204091214.ABFB6EE985@mail.python.org> Author: martin.v.loewis Date: Sat Dec 4 10:12:14 2010 New Revision: 87012 Log: Regenerate. Modified: python/branches/py3k/Objects/typeslots.inc Modified: python/branches/py3k/Objects/typeslots.inc ============================================================================== --- python/branches/py3k/Objects/typeslots.inc (original) +++ python/branches/py3k/Objects/typeslots.inc Sat Dec 4 10:12:14 2010 @@ -1,3 +1,4 @@ +/* Generated by typeslots.py $Revision: 87011 $ */ offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), From python-checkins at python.org Sat Dec 4 10:14:37 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 10:14:37 +0100 (CET) Subject: [Python-checkins] r87013 - in python/branches/py3k: Doc/library/dbm.rst Lib/dbm/dumb.py Lib/test/test_dbm_gnu.py Misc/NEWS Modules/_gdbmmodule.c Message-ID: <20101204091437.16391EEA08@mail.python.org> Author: georg.brandl Date: Sat Dec 4 10:14:36 2010 New Revision: 87013 Log: #6045: provide at least get() and setdefault() for all dbm modules. Modified: python/branches/py3k/Doc/library/dbm.rst python/branches/py3k/Lib/dbm/dumb.py python/branches/py3k/Lib/test/test_dbm_gnu.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_gdbmmodule.c Modified: python/branches/py3k/Doc/library/dbm.rst ============================================================================== --- python/branches/py3k/Doc/library/dbm.rst (original) +++ python/branches/py3k/Doc/library/dbm.rst Sat Dec 4 10:14:36 2010 @@ -61,10 +61,15 @@ modified by the prevailing umask). -The object returned by :func:`.open` supports most of the same functionality as +The object returned by :func:`.open` supports the same basic functionality as dictionaries; keys and their corresponding values can be stored, retrieved, and deleted, and the :keyword:`in` operator and the :meth:`keys` method are -available. Key and values are always stored as bytes. This means that when +available, as well as :meth:`get` and :meth:`setdefault`. + +.. versionchanged:: 3.2 + :meth:`get` and :meth:`setdefault` are now available in all database modules. + +Key and values are always stored as bytes. This means that when strings are used they are implicitly converted to the default encoding before being stored. Modified: python/branches/py3k/Lib/dbm/dumb.py ============================================================================== --- python/branches/py3k/Lib/dbm/dumb.py (original) +++ python/branches/py3k/Lib/dbm/dumb.py Sat Dec 4 10:14:36 2010 @@ -203,7 +203,7 @@ # The blocks used by the associated value are lost. del self._index[key] # XXX It's unclear why we do a _commit() here (the code always - # XXX has, so I'm not changing it). _setitem__ doesn't try to + # XXX has, so I'm not changing it). __setitem__ doesn't try to # XXX keep the directory file in synch. Why should we? Or # XXX why shouldn't __setitem__? self._commit() @@ -232,7 +232,7 @@ __del__ = close - def _chmod (self, file): + def _chmod(self, file): if hasattr(self._os, 'chmod'): self._os.chmod(file, self._mode) Modified: python/branches/py3k/Lib/test/test_dbm_gnu.py ============================================================================== --- python/branches/py3k/Lib/test/test_dbm_gnu.py (original) +++ python/branches/py3k/Lib/test/test_dbm_gnu.py Sat Dec 4 10:14:36 2010 @@ -32,6 +32,10 @@ key_set.remove(key) key = self.g.nextkey(key) self.assertRaises(KeyError, lambda: self.g['xxx']) + # get() and setdefault() work as in the dict interface + self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo') + self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo') + self.assertEqual(self.g[b'xxx'], b'foo') def test_error_conditions(self): # Try to open a non-existent database. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 10:14:36 2010 @@ -37,7 +37,9 @@ Library ------- -- Issue 10620: `python -m unittest` can accept file paths instead of module +- Issue #6045: dbm.gnu databases now support get() and setdefault() methods. + +- Issue #10620: `python -m unittest` can accept file paths instead of module names for running specific tests. - Issue #9424: Deprecate the `unittest.TestCase` methods `assertEquals`, Modified: python/branches/py3k/Modules/_gdbmmodule.c ============================================================================== --- python/branches/py3k/Modules/_gdbmmodule.c (original) +++ python/branches/py3k/Modules/_gdbmmodule.c Sat Dec 4 10:14:36 2010 @@ -135,6 +135,28 @@ return v; } +PyDoc_STRVAR(dbm_get__doc__, +"get(key[, default]) -> value\n\ +Get the value for key, or default if not present; if not given,\n\ +default is None."); + +static PyObject * +dbm_get(dbmobject *dp, PyObject *args) +{ + PyObject *v, *res; + PyObject *def = Py_None; + + if (!PyArg_UnpackTuple(args, "get", 1, 2, &v, &def)) + return NULL; + res = dbm_subscript(dp, v); + if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + Py_INCREF(def); + return def; + } + return res; +} + static int dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) { @@ -176,6 +198,29 @@ return 0; } +PyDoc_STRVAR(dbm_setdefault__doc__, +"setdefault(key[, default]) -> value\n\ +Get value for key, or set it to default and return default if not present;\n\ +if not given, default is None."); + +static PyObject * +dbm_setdefault(dbmobject *dp, PyObject *args) +{ + PyObject *v, *res; + PyObject *def = Py_None; + + if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &v, &def)) + return NULL; + res = dbm_subscript(dp, v); + if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + if (dbm_ass_sub(dp, v, def) < 0) + return NULL; + return dbm_subscript(dp, v); + } + return res; +} + static PyMappingMethods dbm_as_mapping = { (lenfunc)dbm_length, /*mp_length*/ (binaryfunc)dbm_subscript, /*mp_subscript*/ @@ -378,6 +423,8 @@ {"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__}, {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__}, {"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__}, + {"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__}, + {"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__}, {NULL, NULL} /* sentinel */ }; From python-checkins at python.org Sat Dec 4 10:44:30 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 4 Dec 2010 10:44:30 +0100 (CET) Subject: [Python-checkins] r87014 - python/branches/py3k/Misc/NEWS Message-ID: <20101204094430.51EC3EE995@mail.python.org> Author: senthil.kumaran Date: Sat Dec 4 10:44:30 2010 New Revision: 87014 Log: Add the NEWS entry for issue7904 Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 10:44:30 2010 @@ -37,6 +37,10 @@ Library ------- +- Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by + RFC3986. Anything before :// is considered a scheme and is followed by an + authority (or netloc) and by '/' led path, which is optional. + - Issue #6045: dbm.gnu databases now support get() and setdefault() methods. - Issue #10620: `python -m unittest` can accept file paths instead of module From python-checkins at python.org Sat Dec 4 10:50:38 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 4 Dec 2010 10:50:38 +0100 (CET) Subject: [Python-checkins] r87015 - in python/branches/release31-maint: Misc/NEWS Message-ID: <20101204095038.1DCC1EE9DF@mail.python.org> Author: senthil.kumaran Date: Sat Dec 4 10:50:37 2010 New Revision: 87015 Log: Merged revisions 87014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r87014 | senthil.kumaran | 2010-12-04 17:44:30 +0800 (Sat, 04 Dec 2010) | 3 lines Add the NEWS entry for issue7904 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Dec 4 10:50:37 2010 @@ -13,6 +13,10 @@ Library ------- +- Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by + RFC3986. Anything before :// is considered a scheme and is followed by an + authority (or netloc) and by '/' led path, which is optional. + - Issue #10478: Reentrant calls inside buffered IO objects (for example by way of a signal handler) now raise a RuntimeError instead of freezing the current process. From python-checkins at python.org Sat Dec 4 10:58:29 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 4 Dec 2010 10:58:29 +0100 (CET) Subject: [Python-checkins] r87016 - in python/branches/release27-maint: Misc/NEWS Message-ID: <20101204095829.46A13EE9DF@mail.python.org> Author: senthil.kumaran Date: Sat Dec 4 10:58:29 2010 New Revision: 87016 Log: Merged revisions 87014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r87014 | senthil.kumaran | 2010-12-04 17:44:30 +0800 (Sat, 04 Dec 2010) | 3 lines Add the NEWS entry for issue7904 ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Misc/NEWS Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Sat Dec 4 10:58:29 2010 @@ -1428,6 +1428,10 @@ Library ------- +- Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by + RFC3986. Anything before :// is considered a scheme and is followed by an + authority (or netloc) and by '/' led path, which is optional. + - Issue #1555570: email no longer inserts extra blank lines when a \r\n combo crosses an 8192 byte boundary. From python-checkins at python.org Sat Dec 4 10:59:52 2010 From: python-checkins at python.org (gregory.p.smith) Date: Sat, 4 Dec 2010 10:59:52 +0100 (CET) Subject: [Python-checkins] r87017 - python/branches/py3k/Lib/test/test_subprocess.py Message-ID: <20101204095952.CF5A4EE9DF@mail.python.org> Author: gregory.p.smith Date: Sat Dec 4 10:59:52 2010 New Revision: 87017 Log: refactor the warning test. Modified: python/branches/py3k/Lib/test/test_subprocess.py Modified: python/branches/py3k/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k/Lib/test/test_subprocess.py (original) +++ python/branches/py3k/Lib/test/test_subprocess.py Sat Dec 4 10:59:52 2010 @@ -59,31 +59,19 @@ class DeprecationWarningTests(BaseTestCase): - def setUp(self): - BaseTestCase.setUp(self) - self._saved_warn = warnings.warn - self._warn_calls = [] - warnings.warn = self._record_warn - - def tearDown(self): - warnings.warn = self._saved_warn - BaseTestCase.tearDown(self) - - def _record_warn(self, *args): - """A warnings.warn function that records calls.""" - self._warn_calls.append(args) - self._saved_warn(*args) - def testCloseFdsWarning(self): quick_process = [sys.executable, "-c", "import sys; sys.exit(0)"] - subprocess.call(quick_process, close_fds=True) - self.assertEqual([], self._warn_calls) - subprocess.call(quick_process, close_fds=False) - self.assertEqual([], self._warn_calls) - self.assertWarns(DeprecationWarning, subprocess.call, quick_process) - self.assertEqual(1, len(self._warn_calls)) - self.assertIn('close_fds parameter was not specified', - self._warn_calls[0][0]) + with warnings.catch_warnings(record=True) as warnlist: + warnings.simplefilter("always") + subprocess.call(quick_process, close_fds=True) + self.assertEqual([], warnlist) + subprocess.call(quick_process, close_fds=False) + self.assertEqual([], warnlist) + with self.assertWarns(DeprecationWarning) as wm: + subprocess.Popen(quick_process).wait() + self.assertEqual(1, len(wm.warnings)) + self.assertIn('close_fds parameter was not specified', + str(wm.warnings[0])) class ProcessTestCase(BaseTestCase): From python-checkins at python.org Sat Dec 4 11:16:05 2010 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sat, 4 Dec 2010 11:16:05 +0100 (CET) Subject: [Python-checkins] r87018 - in python/branches/py3k: Misc/NEWS Modules/posixmodule.c Message-ID: <20101204101605.A18F0EE98B@mail.python.org> Author: hirokazu.yamamoto Date: Sat Dec 4 11:16:05 2010 New Revision: 87018 Log: Fixed several corner case issues on os.stat/os.lstat related to reparse points. (Windows) - Set S_IEXEC via final path name not link name. - Set S_IFLNK also via FindFirstFile (when CreateFile fails) Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/posixmodule.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 11:16:05 2010 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Fixed several corner case issues on os.stat/os.lstat related to reparse + points. (Windows) + - PEP 384 (Defining a Stable ABI) is implemented. - Issue #2690: Range objects support negative indices and slicing Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Sat Dec 4 11:16:05 2010 @@ -477,7 +477,7 @@ #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int -_Py_ReadLink(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) +win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) { char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; @@ -493,7 +493,7 @@ target_buffer, sizeof(target_buffer), &n_bytes_returned, NULL)) /* we're not using OVERLAPPED_IO */ - return 0; + return -1; if (reparse_tag) *reparse_tag = rdb->ReparseTag; @@ -513,12 +513,12 @@ break; default: SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */ - return 0; + return -1; } buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1)); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); - return 0; + return -1; } wcsncpy(buf, ptr, len); buf[len] = L'\0'; @@ -527,7 +527,7 @@ *target_path = buf; } - return 1; + return 0; } #endif /* MS_WINDOWS */ @@ -1028,7 +1028,7 @@ } static int -attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, struct win32_stat *result) +attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result) { memset(result, 0, sizeof(*result)); result->st_mode = attributes_to_mode(info->dwFileAttributes); @@ -1038,12 +1038,18 @@ FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); result->st_nlink = info->nNumberOfLinks; result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; + if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { + /* first clear the S_IFMT bits */ + result->st_mode ^= (result->st_mode & 0170000); + /* now set the bits that make this a symlink */ + result->st_mode |= 0120000; + } return 0; } static BOOL -attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info) +attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) { HANDLE hFindFile; WIN32_FIND_DATAA FileData; @@ -1052,6 +1058,7 @@ return FALSE; FindClose(hFindFile); memset(info, 0, sizeof(*info)); + *reparse_tag = 0; info->dwFileAttributes = FileData.dwFileAttributes; info->ftCreationTime = FileData.ftCreationTime; info->ftLastAccessTime = FileData.ftLastAccessTime; @@ -1059,11 +1066,13 @@ info->nFileSizeHigh = FileData.nFileSizeHigh; info->nFileSizeLow = FileData.nFileSizeLow; /* info->nNumberOfLinks = 1; */ + if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + *reparse_tag = FileData.dwReserved0; return TRUE; } static BOOL -attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info) +attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) { HANDLE hFindFile; WIN32_FIND_DATAW FileData; @@ -1072,6 +1081,7 @@ return FALSE; FindClose(hFindFile); memset(info, 0, sizeof(*info)); + *reparse_tag = 0; info->dwFileAttributes = FileData.dwFileAttributes; info->ftCreationTime = FileData.ftCreationTime; info->ftLastAccessTime = FileData.ftLastAccessTime; @@ -1079,6 +1089,8 @@ info->nFileSizeHigh = FileData.nFileSizeHigh; info->nFileSizeLow = FileData.nFileSizeLow; /* info->nNumberOfLinks = 1; */ + if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + *reparse_tag = FileData.dwReserved0; return TRUE; } @@ -1087,16 +1099,23 @@ #endif static int -win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth); +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth); static int -win32_xstat(const char *path, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth) { int code; HANDLE hFile; BY_HANDLE_FILE_INFORMATION info; + ULONG reparse_tag = 0; + wchar_t *target_path; const char *dot; + if (depth > SYMLOOP_MAX) { + SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + return -1; + } + hFile = CreateFileA( path, 0, /* desired access */ @@ -1107,32 +1126,43 @@ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, NULL); - if(hFile == INVALID_HANDLE_VALUE) { + if (hFile == INVALID_HANDLE_VALUE) { /* Either the target doesn't exist, or we don't have access to get a handle to it. If the former, we need to return an error. If the latter, we can use attributes_from_dir. */ if (GetLastError() != ERROR_SHARING_VIOLATION) - goto err; - else { - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir(path, &info)) - /* Very strange. This should not fail now */ - goto err; - if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - /* Should traverse, but cannot open reparse point handle */ + return -1; + /* Could not get attributes on open file. Fall back to + reading the directory. */ + if (!attributes_from_dir(path, &info, &reparse_tag)) + /* Very strange. This should not fail now */ + return -1; + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (traverse) { + /* Should traverse, but could not open reparse point handle */ SetLastError(ERROR_SHARING_VIOLATION); - goto err; + return -1; + } + } + } else { + if (!GetFileInformationByHandle(hFile, &info)) { + CloseHandle(hFile); + return -1;; + } + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); + CloseHandle(hFile); + if (code < 0) + return code; + if (traverse) { + code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + free(target_path); + return code; } - attribute_data_to_stat(&info, result); } - } - else { - code = win32_xstat_for_handle(hFile, result, traverse, depth); CloseHandle(hFile); - if (code != 0) - return code; } + attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = strrchr(path, '.'); @@ -1142,22 +1172,23 @@ result->st_mode |= 0111; } return 0; - -err: - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - return -1; } static int -win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) { int code; HANDLE hFile; BY_HANDLE_FILE_INFORMATION info; + ULONG reparse_tag = 0; + wchar_t *target_path; const wchar_t *dot; + if (depth > SYMLOOP_MAX) { + SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + return -1; + } + hFile = CreateFileW( path, 0, /* desired access */ @@ -1168,32 +1199,43 @@ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, NULL); - if(hFile == INVALID_HANDLE_VALUE) { + if (hFile == INVALID_HANDLE_VALUE) { /* Either the target doesn't exist, or we don't have access to get a handle to it. If the former, we need to return an error. If the latter, we can use attributes_from_dir. */ if (GetLastError() != ERROR_SHARING_VIOLATION) - goto err; - else { - /* Could not get attributes on open file. Fall back to - reading the directory. */ - if (!attributes_from_dir_w(path, &info)) - /* Very strange. This should not fail now */ - goto err; - if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - /* Should traverse, but cannot open reparse point handle */ + return -1; + /* Could not get attributes on open file. Fall back to + reading the directory. */ + if (!attributes_from_dir_w(path, &info, &reparse_tag)) + /* Very strange. This should not fail now */ + return -1; + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (traverse) { + /* Should traverse, but could not open reparse point handle */ SetLastError(ERROR_SHARING_VIOLATION); - goto err; + return -1; + } + } + } else { + if (!GetFileInformationByHandle(hFile, &info)) { + CloseHandle(hFile); + return -1;; + } + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); + CloseHandle(hFile); + if (code < 0) + return code; + if (traverse) { + code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + free(target_path); + return code; } - attribute_data_to_stat(&info, result); } - } - else { - code = win32_xstat_for_handle(hFile, result, traverse, depth); CloseHandle(hFile); - if (code != 0) - return code; } + attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = wcsrchr(path, '.'); @@ -1203,51 +1245,26 @@ result->st_mode |= 0111; } return 0; +} -err: +static int +win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) +{ /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ + int code = win32_xstat_impl(path, result, traverse, 0); errno = 0; - return -1; + return code; } static int -win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) { - int code; - BOOL reparse_tag; - wchar_t *target_path; - BY_HANDLE_FILE_INFORMATION info; - - if (!GetFileInformationByHandle(hFile, &info)) - return -1; - - if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (traverse) { - if (depth + 1 > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ - return -1; - } - if (!_Py_ReadLink(hFile, NULL, &target_path)) - return -1; - code = win32_xstat_w(target_path, result, traverse, depth + 1); - free(target_path); - return code; - } else { - if (!_Py_ReadLink(hFile, &reparse_tag, NULL)) - return -1; - attribute_data_to_stat(&info, result); - if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { - /* first clear the S_IFMT bits */ - result->st_mode ^= (result->st_mode & 0170000); - /* now set the bits that make this a symlink */ - result->st_mode |= 0120000; - } - } - } else { - attribute_data_to_stat(&info, result); - } - return 0; + /* Protocol violation: we explicitly clear errno, instead of + setting it to a POSIX error. Callers should use GetLastError. */ + int code = win32_xstat_impl_w(path, result, traverse, 0); + errno = 0; + return code; } /* About the following functions: win32_lstat, win32_lstat_w, win32_stat, @@ -1267,25 +1284,25 @@ static int win32_lstat(const char* path, struct win32_stat *result) { - return win32_xstat(path, result, FALSE, 0); + return win32_xstat(path, result, FALSE); } static int win32_lstat_w(const wchar_t* path, struct win32_stat *result) { - return win32_xstat_w(path, result, FALSE, 0); + return win32_xstat_w(path, result, FALSE); } static int win32_stat(const char* path, struct win32_stat *result) { - return win32_xstat(path, result, TRUE, 0); + return win32_xstat(path, result, TRUE); } static int win32_stat_w(const wchar_t* path, struct win32_stat *result) { - return win32_xstat_w(path, result, TRUE, 0); + return win32_xstat_w(path, result, TRUE); } static int @@ -1330,7 +1347,7 @@ return -1; } - attribute_data_to_stat(&info, result); + attribute_data_to_stat(&info, 0, result); /* specific to fstat() */ result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; return 0; From python-checkins at python.org Sat Dec 4 11:26:46 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 11:26:46 +0100 (CET) Subject: [Python-checkins] r87019 - in python/branches/py3k: Doc/c-api/veryhigh.rst Doc/library/compileall.rst Doc/library/functions.rst Doc/library/py_compile.rst Doc/library/zipfile.rst Include/compile.h Include/pythonrun.h Lib/compileall.py Lib/py_compile.py Lib/test/test_builtin.py Lib/test/test_compileall.py Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Python/bltinmodule.c Python/compile.c Python/pythonrun.c Message-ID: <20101204102646.686CDEE985@mail.python.org> Author: georg.brandl Date: Sat Dec 4 11:26:46 2010 New Revision: 87019 Log: Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile. Modified: python/branches/py3k/Doc/c-api/veryhigh.rst python/branches/py3k/Doc/library/compileall.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/py_compile.rst python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Include/compile.h python/branches/py3k/Include/pythonrun.h python/branches/py3k/Lib/compileall.py python/branches/py3k/Lib/py_compile.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_compileall.py python/branches/py3k/Lib/test/test_zipfile.py python/branches/py3k/Lib/zipfile.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/bltinmodule.c python/branches/py3k/Python/compile.c python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Doc/c-api/veryhigh.rst ============================================================================== --- python/branches/py3k/Doc/c-api/veryhigh.rst (original) +++ python/branches/py3k/Doc/c-api/veryhigh.rst Sat Dec 4 11:26:46 2010 @@ -230,6 +230,12 @@ .. c:function:: PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags) + This is a simplified interface to :c:func:`Py_CompileStringExFlags` below, with + *optimize* set to ``-1``. + + +.. c:function:: PyObject* Py_CompileStringExFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags, int optimize) + Parse and compile the Python source code in *str*, returning the resulting code object. The start token is given by *start*; this can be used to constrain the code which can be compiled and should be :const:`Py_eval_input`, @@ -238,6 +244,14 @@ :exc:`SyntaxError` exception messages. This returns *NULL* if the code cannot be parsed or compiled. + The integer *optimize* specifies the optimization level of the compiler; a + value of ``-1`` selects the optimization level of the interpreter as given by + :option:`-O` options. Explicit levels are ``0`` (no optimization; + ``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false) + or ``2`` (docstrings are removed too). + + .. versionadded:: 3.2 + .. c:function:: PyObject* PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) Modified: python/branches/py3k/Doc/library/compileall.rst ============================================================================== --- python/branches/py3k/Doc/library/compileall.rst (original) +++ python/branches/py3k/Doc/library/compileall.rst Sat Dec 4 11:26:46 2010 @@ -58,7 +58,7 @@ Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. The *maxlevels* parameter is used to limit the depth of @@ -76,14 +76,23 @@ If *legacy* is true, old-style ``.pyc`` file path names are written, otherwise (the default), :pep:`3147`-style path names are written. + *optimize* specifies the optimization level for the compiler. It is passed to + the built-in :func:`compile` function. -.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False) + .. versionchanged:: 3.2 + Added the *optimize* parameter. + + +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False, optimize=-1) Byte-compile all the :file:`.py` files found along ``sys.path``. If *skip_curdir* is true (the default), the current directory is not included in - the search. The *maxlevels* parameter defaults to ``0``, and the *force* - and *legacy* parameters default to ``False``. All are - passed to the :func:`compile_dir` function. + the search. All other parameters are passed to the :func:`compile_dir` + function. + + .. versionchanged:: 3.2 + Added the *optimize* parameter. + To force a recompile of all the :file:`.py` files in the :file:`Lib/` subdirectory and all its subdirectories:: Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sat Dec 4 11:26:46 2010 @@ -174,7 +174,7 @@ type hierarchy in :ref:`types`. -.. function:: compile(source, filename, mode, flags=0, dont_inherit=False) +.. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) Compile the *source* into a code or AST object. Code objects can be executed by :func:`exec` or :func:`eval`. *source* can either be a string or an AST @@ -206,6 +206,12 @@ can be found as the :attr:`compiler_flag` attribute on the :class:`_Feature` instance in the :mod:`__future__` module. + The argument *optimize* specifies the optimization level of the compiler; the + default value of ``-1`` selects the optimization level of the interpreter as + given by :option:`-O` options. Explicit levels are ``0`` (no optimization; + ``__debug__`` is true), ``1`` (asserts are removed, ``__debug__`` is false) + or ``2`` (docstrings are removed too). + This function raises :exc:`SyntaxError` if the compiled source is invalid, and :exc:`TypeError` if the source contains null bytes. @@ -218,7 +224,7 @@ .. versionchanged:: 3.2 Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode - does not have to end in a newline anymore. + does not have to end in a newline anymore. Added the *optimize* parameter. .. function:: complex([real[, imag]]) Modified: python/branches/py3k/Doc/library/py_compile.rst ============================================================================== --- python/branches/py3k/Doc/library/py_compile.rst (original) +++ python/branches/py3k/Doc/library/py_compile.rst Sat Dec 4 11:26:46 2010 @@ -22,7 +22,7 @@ Exception raised when an error occurs while attempting to compile the file. -.. function:: compile(file, cfile=None, dfile=None, doraise=False) +.. function:: compile(file, cfile=None, dfile=None, doraise=False, optimize=-1) Compile a source file to byte-code and write out the byte-code cache file. The source code is loaded from the file name *file*. The byte-code is written to @@ -37,6 +37,13 @@ returns the path to byte-compiled file, i.e. whatever *cfile* value was used. + *optimize* controls the optimization level and is passed to the built-in + :func:`compile` function. The default of ``-1`` selects the optimization + level of the current interpreter. + + .. versionchanged:: 3.2 + Added the *optimize* parameter. + .. function:: main(args=None) Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Sat Dec 4 11:26:46 2010 @@ -51,6 +51,7 @@ .. class:: PyZipFile + :noindex: Class for creating ZIP archives containing Python libraries. @@ -318,37 +319,53 @@ string no longer than 65535 bytes. Comments longer than this will be truncated in the written archive when :meth:`ZipFile.close` is called. + .. _pyzipfile-objects: PyZipFile Objects ----------------- The :class:`PyZipFile` constructor takes the same parameters as the -:class:`ZipFile` constructor. Instances have one method in addition to those of -:class:`ZipFile` objects. +:class:`ZipFile` constructor, and one additional parameter, *optimize*. + +.. class:: PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=False, \ + optimize=-1) + + .. versionadded:: 3.2 + The *optimize* parameter. + + Instances have one method in addition to those of :class:`ZipFile` objects: + .. method:: PyZipFile.writepy(pathname, basename='') -.. method:: PyZipFile.writepy(pathname, basename='') + Search for files :file:`\*.py` and add the corresponding file to the + archive. - Search for files :file:`\*.py` and add the corresponding file to the archive. - The corresponding file is a :file:`\*.pyo` file if available, else a - :file:`\*.pyc` file, compiling if necessary. If the pathname is a file, the - filename must end with :file:`.py`, and just the (corresponding - :file:`\*.py[co]`) file is added at the top level (no path information). If the - pathname is a file that does not end with :file:`.py`, a :exc:`RuntimeError` - will be raised. If it is a directory, and the directory is not a package - directory, then all the files :file:`\*.py[co]` are added at the top level. If - the directory is a package directory, then all :file:`\*.py[co]` are added under - the package name as a file path, and if any subdirectories are package - directories, all of these are added recursively. *basename* is intended for - internal use only. The :meth:`writepy` method makes archives with file names - like this:: - - string.pyc # Top level name - test/__init__.pyc # Package directory - test/testall.pyc # Module test.testall - test/bogus/__init__.pyc # Subpackage directory - test/bogus/myfile.pyc # Submodule test.bogus.myfile + If the *optimize* parameter to :class:`PyZipFile` was not given or ``-1``, + the corresponding file is a :file:`\*.pyo` file if available, else a + :file:`\*.pyc` file, compiling if necessary. + + If the *optimize* parameter to :class:`PyZipFile` was ``0``, ``1`` or + ``2``, only files with that optimization level (see :func:`compile`) are + added to the archive, compiling if necessary. + + If the pathname is a file, the filename must end with :file:`.py`, and + just the (corresponding :file:`\*.py[co]`) file is added at the top level + (no path information). If the pathname is a file that does not end with + :file:`.py`, a :exc:`RuntimeError` will be raised. If it is a directory, + and the directory is not a package directory, then all the files + :file:`\*.py[co]` are added at the top level. If the directory is a + package directory, then all :file:`\*.py[co]` are added under the package + name as a file path, and if any subdirectories are package directories, + all of these are added recursively. *basename* is intended for internal + use only. The :meth:`writepy` method makes archives with file names like + this:: + + string.pyc # Top level name + test/__init__.pyc # Package directory + test/testall.pyc # Module test.testall + test/bogus/__init__.pyc # Subpackage directory + test/bogus/myfile.pyc # Submodule test.bogus.myfile .. _zipinfo-objects: Modified: python/branches/py3k/Include/compile.h ============================================================================== --- python/branches/py3k/Include/compile.h (original) +++ python/branches/py3k/Include/compile.h Sat Dec 4 11:26:46 2010 @@ -29,8 +29,9 @@ #define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" struct _mod; /* Declare the existence of this type */ -PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *, - PyCompilerFlags *, PyArena *); +#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) +PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx(struct _mod *, const char *, + PyCompilerFlags *, int, PyArena *); PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *); Modified: python/branches/py3k/Include/pythonrun.h ============================================================================== --- python/branches/py3k/Include/pythonrun.h (original) +++ python/branches/py3k/Include/pythonrun.h Sat Dec 4 11:26:46 2010 @@ -76,9 +76,10 @@ #ifdef Py_LIMITED_API PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int); #else -#define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL) -PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int, - PyCompilerFlags *); +#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) +PyAPI_FUNC(PyObject *) Py_CompileStringExFlags(const char *, const char *, int, + PyCompilerFlags *, int); #endif PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int); Modified: python/branches/py3k/Lib/compileall.py ============================================================================== --- python/branches/py3k/Lib/compileall.py (original) +++ python/branches/py3k/Lib/compileall.py Sat Dec 4 11:26:46 2010 @@ -19,8 +19,8 @@ __all__ = ["compile_dir","compile_file","compile_path"] -def compile_dir(dir, maxlevels=10, ddir=None, - force=False, rx=None, quiet=False, legacy=False): +def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, + quiet=False, legacy=False, optimize=-1): """Byte-compile all modules in the given directory tree. Arguments (only dir is required): @@ -32,6 +32,7 @@ force: if True, force compilation, even if timestamps are up-to-date quiet: if True, be quiet during compilation legacy: if True, produce legacy pyc paths instead of PEP 3147 paths + optimize: optimization level or -1 for level of the interpreter """ if not quiet: print('Listing', dir, '...') @@ -51,7 +52,8 @@ else: dfile = None if not os.path.isdir(fullname): - if not compile_file(fullname, ddir, force, rx, quiet, legacy): + if not compile_file(fullname, ddir, force, rx, quiet, + legacy, optimize): success = 0 elif (maxlevels > 0 and name != os.curdir and name != os.pardir and os.path.isdir(fullname) and not os.path.islink(fullname)): @@ -61,7 +63,7 @@ return success def compile_file(fullname, ddir=None, force=0, rx=None, quiet=False, - legacy=False): + legacy=False, optimize=-1): """Byte-compile file. fullname: the file to byte-compile ddir: if given, purported directory name (this is the @@ -69,6 +71,7 @@ force: if True, force compilation, even if timestamps are up-to-date quiet: if True, be quiet during compilation legacy: if True, produce legacy pyc paths instead of PEP 3147 paths + optimize: optimization level or -1 for level of the interpreter """ success = 1 name = os.path.basename(fullname) @@ -84,7 +87,11 @@ if legacy: cfile = fullname + ('c' if __debug__ else 'o') else: - cfile = imp.cache_from_source(fullname) + if optimize >= 0: + cfile = imp.cache_from_source(fullname, + debug_override=not optimize) + else: + cfile = imp.cache_from_source(fullname) cache_dir = os.path.dirname(cfile) head, tail = name[:-3], name[-3:] if tail == '.py': @@ -101,7 +108,8 @@ if not quiet: print('Compiling', fullname, '...') try: - ok = py_compile.compile(fullname, cfile, dfile, True) + ok = py_compile.compile(fullname, cfile, dfile, True, + optimize=optimize) except py_compile.PyCompileError as err: if quiet: print('*** Error compiling', fullname, '...') @@ -126,7 +134,7 @@ return success def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False, - legacy=False): + legacy=False, optimize=-1): """Byte-compile all module on sys.path. Arguments (all optional): @@ -136,6 +144,7 @@ force: as for compile_dir() (default False) quiet: as for compile_dir() (default False) legacy: as for compile_dir() (default False) + optimize: as for compile_dir() (default -1) """ success = 1 for dir in sys.path: @@ -144,7 +153,7 @@ else: success = success and compile_dir(dir, maxlevels, None, force, quiet=quiet, - legacy=legacy) + legacy=legacy, optimize=optimize) return success Modified: python/branches/py3k/Lib/py_compile.py ============================================================================== --- python/branches/py3k/Lib/py_compile.py (original) +++ python/branches/py3k/Lib/py_compile.py Sat Dec 4 11:26:46 2010 @@ -72,7 +72,7 @@ (x >> 16) & 0xff, (x >> 24) & 0xff])) -def compile(file, cfile=None, dfile=None, doraise=False): +def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): """Byte-compile one Python source file to Python bytecode. :param file: The source file name. @@ -86,6 +86,10 @@ will be printed, and the function will return to the caller. If an exception occurs and this flag is set to True, a PyCompileError exception will be raised. + :param optimize: The optimization level for the compiler. Valid values + are -1, 0, 1 and 2. A value of -1 means to use the optimization + level of the current interpreter, as given by -O command line options. + :return: Path to the resulting byte compiled file. Note that it isn't necessary to byte-compile Python modules for @@ -111,7 +115,8 @@ timestamp = int(os.stat(file).st_mtime) codestring = f.read() try: - codeobject = builtins.compile(codestring, dfile or file,'exec') + codeobject = builtins.compile(codestring, dfile or file, 'exec', + optimize=optimize) except Exception as err: py_exc = PyCompileError(err.__class__, err, dfile or file) if doraise: @@ -120,7 +125,10 @@ sys.stderr.write(py_exc.msg + '\n') return if cfile is None: - cfile = imp.cache_from_source(file) + if optimize >= 0: + cfile = imp.cache_from_source(file, debug_override=not optimize) + else: + cfile = imp.cache_from_source(file) try: os.makedirs(os.path.dirname(cfile)) except OSError as error: Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Sat Dec 4 11:26:46 2010 @@ -6,6 +6,7 @@ import warnings import collections import io +import ast import types import builtins import random @@ -285,6 +286,34 @@ self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') + # test the optimize argument + + codestr = '''def f(): + """doc""" + try: + assert False + except AssertionError: + return (True, f.__doc__) + else: + return (False, f.__doc__) + ''' + def f(): """doc""" + values = [(-1, __debug__, f.__doc__), + (0, True, 'doc'), + (1, False, 'doc'), + (2, False, None)] + for optval, debugval, docstring in values: + # test both direct compilation and compilation via AST + codeobjs = [] + codeobjs.append(compile(codestr, "", "exec", optimize=optval)) + tree = ast.parse(codestr) + codeobjs.append(compile(tree, "", "exec", optimize=optval)) + for code in codeobjs: + ns = {} + exec(code, ns) + rv = ns['f']() + self.assertEqual(rv, (debugval, docstring)) + def test_delattr(self): sys.spam = 1 delattr(sys, 'spam') Modified: python/branches/py3k/Lib/test/test_compileall.py ============================================================================== --- python/branches/py3k/Lib/test/test_compileall.py (original) +++ python/branches/py3k/Lib/test/test_compileall.py Sat Dec 4 11:26:46 2010 @@ -88,6 +88,15 @@ compileall.compile_file(data_file) self.assertFalse(os.path.exists(os.path.join(data_dir, '__pycache__'))) + def test_optimize(self): + # make sure compiling with different optimization settings than the + # interpreter's creates the correct file names + optimize = 1 if __debug__ else 0 + compileall.compile_dir(self.directory, quiet=True, optimize=optimize) + cached = imp.cache_from_source(self.source_path, + debug_override=not optimize) + self.assertTrue(os.path.isfile(cached)) + class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Sat Dec 4 11:26:46 2010 @@ -654,6 +654,22 @@ self.assertTrue('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names) + def test_write_with_optimization(self): + import email + packagedir = os.path.dirname(email.__file__) + # use .pyc if running test in optimization mode, + # use .pyo if running test in debug mode + optlevel = 1 if __debug__ else 0 + ext = '.pyo' if optlevel == 1 else '.pyc' + + with TemporaryFile() as t, \ + zipfile.PyZipFile(t, "w", optimize=optlevel) as zipfp: + zipfp.writepy(packagedir) + + names = zipfp.namelist() + self.assertIn('email/__init__' + ext, names) + self.assertIn('email/mime/text' + ext, names) + def test_write_python_directory(self): os.mkdir(TESTFN2) try: Modified: python/branches/py3k/Lib/zipfile.py ============================================================================== --- python/branches/py3k/Lib/zipfile.py (original) +++ python/branches/py3k/Lib/zipfile.py Sat Dec 4 11:26:46 2010 @@ -1295,6 +1295,12 @@ class PyZipFile(ZipFile): """Class to create ZIP archives with Python library files and packages.""" + def __init__(self, file, mode="r", compression=ZIP_STORED, + allowZip64=False, optimize=-1): + ZipFile.__init__(self, file, mode=mode, compression=compression, + allowZip64=allowZip64) + self._optimize = optimize + def writepy(self, pathname, basename=""): """Add all files from "pathname" to the ZIP archive. @@ -1367,44 +1373,63 @@ archive name, compiling if necessary. For example, given /python/lib/string, return (/python/lib/string.pyc, string). """ + def _compile(file, optimize=-1): + import py_compile + if self.debug: + print("Compiling", file) + try: + py_compile.compile(file, doraise=True, optimize=optimize) + except py_compile.PyCompileError as error: + print(err.msg) + return False + return True + file_py = pathname + ".py" file_pyc = pathname + ".pyc" file_pyo = pathname + ".pyo" pycache_pyc = imp.cache_from_source(file_py, True) pycache_pyo = imp.cache_from_source(file_py, False) - if (os.path.isfile(file_pyo) and - os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime): - # Use .pyo file. - arcname = fname = file_pyo - elif (os.path.isfile(file_pyc) and - os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime): - # Use .pyc file. - arcname = fname = file_pyc - elif (os.path.isfile(pycache_pyc) and - os.stat(pycache_pyc).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_pyc - arcname = file_pyc - elif (os.path.isfile(pycache_pyo) and - os.stat(pycache_pyo).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyo file, but write it to the legacy pyo - # file name in the archive. - fname = pycache_pyo - arcname = file_pyo + if self._optimize == -1: + # legacy mode: use whatever file is present + if (os.path.isfile(file_pyo) and + os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime): + # Use .pyo file. + arcname = fname = file_pyo + elif (os.path.isfile(file_pyc) and + os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime): + # Use .pyc file. + arcname = fname = file_pyc + elif (os.path.isfile(pycache_pyc) and + os.stat(pycache_pyc).st_mtime >= os.stat(file_py).st_mtime): + # Use the __pycache__/*.pyc file, but write it to the legacy pyc + # file name in the archive. + fname = pycache_pyc + arcname = file_pyc + elif (os.path.isfile(pycache_pyo) and + os.stat(pycache_pyo).st_mtime >= os.stat(file_py).st_mtime): + # Use the __pycache__/*.pyo file, but write it to the legacy pyo + # file name in the archive. + fname = pycache_pyo + arcname = file_pyo + else: + # Compile py into PEP 3147 pyc file. + if _compile(file_py): + fname = (pycache_pyc if __debug__ else pycache_pyo) + arcname = (file_pyc if __debug__ else file_pyo) + else: + fname = arcname = file_py else: - # Compile py into PEP 3147 pyc file. - import py_compile - if self.debug: - print("Compiling", file_py) - try: - py_compile.compile(file_py, doraise=True) - except py_compile.PyCompileError as error: - print(err.msg) - fname = file_py + # new mode: use given optimization level + if self._optimize == 0: + fname = pycache_pyc + arcname = file_pyc else: - fname = (pycache_pyc if __debug__ else pycache_pyo) - arcname = (file_pyc if __debug__ else file_pyo) + fname = pycache_pyo + arcname = file_pyo + if not (os.path.isfile(fname) and + os.stat(fname).st_mtime >= os.stat(file_py).st_mtime): + if not _compile(file_py, optimize=self._optimize): + fname = arcname = file_py archivename = os.path.split(arcname)[1] if basename: archivename = "%s/%s" % (basename, archivename) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 11:26:46 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Provide an *optimize* parameter in the built-in compile() function. + - Fixed several corner case issues on os.stat/os.lstat related to reparse points. (Windows) @@ -40,6 +42,9 @@ Library ------- +- Provide an interface to set the optimization level of compilation in + py_compile, compileall and zipfile.PyZipFile. + - Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by RFC3986. Anything before :// is considered a scheme and is followed by an authority (or netloc) and by '/' led path, which is optional. Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Sat Dec 4 11:26:46 2010 @@ -543,19 +543,20 @@ int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int optimize = -1; int is_ast; PyCompilerFlags cf; PyObject *cmd; static char *kwlist[] = {"source", "filename", "mode", "flags", - "dont_inherit", NULL}; + "dont_inherit", "optimize", NULL}; int start[] = {Py_file_input, Py_eval_input, Py_single_input}; PyObject *result; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|ii:compile", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist, &cmd, PyUnicode_FSConverter, &filename_obj, &startstr, &supplied_flags, - &dont_inherit)) + &dont_inherit, &optimize)) return NULL; filename = PyBytes_AS_STRING(filename_obj); @@ -570,6 +571,12 @@ } /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ + if (optimize < -1 || optimize > 2) { + PyErr_SetString(PyExc_ValueError, + "compile(): invalid optimize value"); + goto error; + } + if (!dont_inherit) { PyEval_MergeCompilerFlags(&cf); } @@ -604,8 +611,8 @@ PyArena_Free(arena); goto error; } - result = (PyObject*)PyAST_Compile(mod, filename, - &cf, arena); + result = (PyObject*)PyAST_CompileEx(mod, filename, + &cf, optimize, arena); PyArena_Free(arena); } goto finally; @@ -615,7 +622,7 @@ if (str == NULL) goto error; - result = Py_CompileStringFlags(str, filename, start[mode], &cf); + result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize); goto finally; error: Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Sat Dec 4 11:26:46 2010 @@ -139,6 +139,7 @@ PyFutureFeatures *c_future; /* pointer to module's __future__ */ PyCompilerFlags *c_flags; + int c_optimize; /* optimization level */ int c_interactive; /* true if in interactive mode */ int c_nestlevel; @@ -175,7 +176,7 @@ static int compiler_in_loop(struct compiler *); static int inplace_binop(struct compiler *, operator_ty); -static int expr_constant(expr_ty e); +static int expr_constant(struct compiler *, expr_ty); static int compiler_with(struct compiler *, stmt_ty); static int compiler_call_helper(struct compiler *c, int n, @@ -254,8 +255,8 @@ } PyCodeObject * -PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, - PyArena *arena) +PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, + int optimize, PyArena *arena) { struct compiler c; PyCodeObject *co = NULL; @@ -283,6 +284,7 @@ c.c_future->ff_features = merged; flags->cf_flags = merged; c.c_flags = flags; + c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize; c.c_nestlevel = 0; c.c_st = PySymtable_Build(mod, filename, c.c_future); @@ -1149,7 +1151,7 @@ if (!asdl_seq_LEN(stmts)) return 1; st = (stmt_ty)asdl_seq_GET(stmts, 0); - if (compiler_isdocstring(st) && Py_OptimizeFlag < 2) { + if (compiler_isdocstring(st) && c->c_optimize < 2) { /* don't generate docstrings if -OO */ i = 1; VISIT(c, expr, st->v.Expr.value); @@ -1463,7 +1465,7 @@ st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0); docstring = compiler_isdocstring(st); - if (docstring && Py_OptimizeFlag < 2) + if (docstring && c->c_optimize < 2) first_const = st->v.Expr.value->v.Str.s; if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { compiler_exit_scope(c); @@ -1697,7 +1699,7 @@ if (end == NULL) return 0; - constant = expr_constant(s->v.If.test); + constant = expr_constant(c, s->v.If.test); /* constant = 0: "if 0" * constant = 1: "if 1", "if 2", ... * constant = -1: rest */ @@ -1759,7 +1761,7 @@ compiler_while(struct compiler *c, stmt_ty s) { basicblock *loop, *orelse, *end, *anchor = NULL; - int constant = expr_constant(s->v.While.test); + int constant = expr_constant(c, s->v.While.test); if (constant == 0) { if (s->v.While.orelse) @@ -2211,7 +2213,7 @@ static PyObject *assertion_error = NULL; basicblock *end; - if (Py_OptimizeFlag) + if (c->c_optimize) return 1; if (assertion_error == NULL) { assertion_error = PyUnicode_InternFromString("AssertionError"); @@ -3011,7 +3013,7 @@ */ static int -expr_constant(expr_ty e) +expr_constant(struct compiler *c, expr_ty e) { char *id; switch (e->kind) { @@ -3029,7 +3031,7 @@ if (strcmp(id, "False") == 0) return 0; if (strcmp(id, "None") == 0) return 0; if (strcmp(id, "__debug__") == 0) - return ! Py_OptimizeFlag; + return ! c->c_optimize; /* fall through */ default: return -1; @@ -4080,3 +4082,13 @@ assemble_free(&a); return co; } + +#undef PyAST_Compile +PyAPI_FUNC(PyCodeObject *) +PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, + PyArena *arena) +{ + return PyAST_CompileEx(mod, filename, flags, -1, arena); +} + + Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Sat Dec 4 11:26:46 2010 @@ -1793,8 +1793,8 @@ } PyObject * -Py_CompileStringFlags(const char *str, const char *filename, int start, - PyCompilerFlags *flags) +Py_CompileStringExFlags(const char *str, const char *filename, int start, + PyCompilerFlags *flags, int optimize) { PyCodeObject *co; mod_ty mod; @@ -1812,7 +1812,7 @@ PyArena_Free(arena); return result; } - co = PyAST_Compile(mod, filename, flags, arena); + co = PyAST_CompileEx(mod, filename, flags, optimize, arena); PyArena_Free(arena); return (PyObject *)co; } @@ -2450,7 +2450,15 @@ PyAPI_FUNC(PyObject *) Py_CompileString(const char *str, const char *p, int s) { - return Py_CompileStringFlags(str, p, s, NULL); + return Py_CompileStringExFlags(str, p, s, NULL, -1); +} + +#undef Py_CompileStringFlags +PyAPI_FUNC(PyObject *) +Py_CompileStringFlags(const char *str, const char *p, int s, + PyCompilerFlags *flags) +{ + return Py_CompileStringExFlags(str, p, s, flags, -1); } #undef PyRun_InteractiveOne From python-checkins at python.org Sat Dec 4 11:39:14 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 11:39:14 +0100 (CET) Subject: [Python-checkins] r87020 - in python/branches/py3k/Lib: http/cookies.py http/server.py pydoc.py tabnanny.py test/pystone.py test/test_long.py Message-ID: <20101204103914.ED971EE985@mail.python.org> Author: georg.brandl Date: Sat Dec 4 11:39:14 2010 New Revision: 87020 Log: #1513299: cleanup some map() uses where a comprehension works better. Modified: python/branches/py3k/Lib/http/cookies.py python/branches/py3k/Lib/http/server.py python/branches/py3k/Lib/pydoc.py python/branches/py3k/Lib/tabnanny.py python/branches/py3k/Lib/test/pystone.py python/branches/py3k/Lib/test/test_long.py Modified: python/branches/py3k/Lib/http/cookies.py ============================================================================== --- python/branches/py3k/Lib/http/cookies.py (original) +++ python/branches/py3k/Lib/http/cookies.py Sat Dec 4 11:39:14 2010 @@ -230,7 +230,7 @@ if all(c in LegalChars for c in str): return str else: - return '"' + _nulljoin(map(_Translator.get, str, str)) + '"' + return '"' + _nulljoin(_Translator.get(s, s) for s in str) + '"' _OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") Modified: python/branches/py3k/Lib/http/server.py ============================================================================== --- python/branches/py3k/Lib/http/server.py (original) +++ python/branches/py3k/Lib/http/server.py Sat Dec 4 11:39:14 2010 @@ -868,7 +868,7 @@ try: nobody = pwd.getpwnam('nobody')[2] except KeyError: - nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) + nobody = 1 + max(x[2] for x in pwd.getpwall()) return nobody Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Sat Dec 4 11:39:14 2010 @@ -1000,7 +1000,7 @@ def bold(self, text): """Format a string in bold by overstriking.""" - return ''.join(map(lambda ch: ch + '\b' + ch, text)) + return ''.join(ch + '\b' + ch for ch in text) def indent(self, text, prefix=' '): """Indent text by prepending a given prefix to each line.""" @@ -1024,7 +1024,7 @@ c, bases = entry result = result + prefix + classname(c, modname) if bases and bases != (parent,): - parents = map(lambda c, m=modname: classname(c, m), bases) + parents = (classname(c, modname) for c in bases) result = result + '(%s)' % ', '.join(parents) result = result + '\n' elif type(entry) is type([]): Modified: python/branches/py3k/Lib/tabnanny.py ============================================================================== --- python/branches/py3k/Lib/tabnanny.py (original) +++ python/branches/py3k/Lib/tabnanny.py Sat Dec 4 11:39:14 2010 @@ -264,7 +264,7 @@ return a def format_witnesses(w): - firsts = map(lambda tup: str(tup[0]), w) + firsts = (str(tup[0]) for tup in w) prefix = "at tab size" if len(w) > 1: prefix = prefix + "s" Modified: python/branches/py3k/Lib/test/pystone.py ============================================================================== --- python/branches/py3k/Lib/test/pystone.py (original) +++ python/branches/py3k/Lib/test/pystone.py Sat Dec 4 11:39:14 2010 @@ -72,7 +72,7 @@ Char1Glob = '\0' Char2Glob = '\0' Array1Glob = [0]*51 -Array2Glob = list(map(lambda x: x[:], [Array1Glob]*51)) +Array2Glob = [x[:] for x in [Array1Glob]*51] PtrGlb = None PtrGlbNext = None Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Sat Dec 4 11:39:14 2010 @@ -276,7 +276,7 @@ digits = digits or [0] return '-'[:sign] + \ {2: '0b', 8: '0o', 10: '', 16: '0x'}[base] + \ - "".join(map(lambda i: "0123456789abcdef"[i], digits)) + "".join("0123456789abcdef"[i] for i in digits) def check_format_1(self, x): for base, mapper in (8, oct), (10, repr), (16, hex): From python-checkins at python.org Sat Dec 4 11:47:18 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 11:47:18 +0100 (CET) Subject: [Python-checkins] r87021 - in python/branches/py3k: Doc/using/cmdline.rst Misc/NEWS Misc/python.man Modules/main.c Message-ID: <20101204104718.498CCEE99F@mail.python.org> Author: georg.brandl Date: Sat Dec 4 11:47:18 2010 New Revision: 87021 Log: #1772833: add -q command line option. Modified: python/branches/py3k/Doc/using/cmdline.rst python/branches/py3k/Misc/NEWS python/branches/py3k/Misc/python.man python/branches/py3k/Modules/main.c Modified: python/branches/py3k/Doc/using/cmdline.rst ============================================================================== --- python/branches/py3k/Doc/using/cmdline.rst (original) +++ python/branches/py3k/Doc/using/cmdline.rst Sat Dec 4 11:47:18 2010 @@ -220,6 +220,13 @@ Discard docstrings in addition to the :option:`-O` optimizations. +.. cmdoption:: -q + + Don't display the copyright and version messages even in interactive mode. + + .. versionadded:: 3.2 + + .. cmdoption:: -s Don't add user site directory to sys.path Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 11:47:18 2010 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #1772833: Add the -q command-line option to suppress copyright + and version output in interactive mode. + - Provide an *optimize* parameter in the built-in compile() function. - Fixed several corner case issues on os.stat/os.lstat related to reparse Modified: python/branches/py3k/Misc/python.man ============================================================================== --- python/branches/py3k/Misc/python.man (original) +++ python/branches/py3k/Misc/python.man Sat Dec 4 11:47:18 2010 @@ -26,6 +26,9 @@ .B \-m .I module-name ] +[ +.B \-q +] .br [ .B \-O @@ -145,6 +148,10 @@ .B \-O0 Discard docstrings in addition to the \fB-O\fP optimizations. .TP +.B \-q +Do not print the version and copyright messages. These messages are +also suppressed in non-interactive mode. +.TP .BI "\-Q " argument Division control; see PEP 238. The argument must be one of "old" (the default, int/int and long/long return an int or long), "new" (new Modified: python/branches/py3k/Modules/main.c ============================================================================== --- python/branches/py3k/Modules/main.c (original) +++ python/branches/py3k/Modules/main.c Sat Dec 4 11:47:18 2010 @@ -46,7 +46,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS L"bBc:dEhiJm:OsStuvVW:xX:?" +#define BASE_OPTS L"bBc:dEhiJm:OqsStuvVW:xX:?" #define PROGRAM_OPTS BASE_OPTS @@ -71,6 +71,7 @@ -m mod : run library module as a script (terminates option list)\n\ -O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ +-q : don't print version and copyright messages on interactive startup\n\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ "; @@ -318,6 +319,7 @@ int stdin_is_interactive = 0; int help = 0; int version = 0; + int quiet = 0; int saw_unbuffered_flag = 0; PyCompilerFlags cf; @@ -424,6 +426,10 @@ PySys_AddXOption(_PyOS_optarg); break; + case 'q': + quiet++; + break; + /* This space reserved for other options */ default: @@ -588,8 +594,9 @@ #endif Py_Initialize(); - if (Py_VerboseFlag || - (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) { + if (!quiet && (Py_VerboseFlag || + (command == NULL && filename == NULL && + module == NULL && stdin_is_interactive))) { fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (!Py_NoSiteFlag) From python-checkins at python.org Sat Dec 4 12:02:05 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 12:02:05 +0100 (CET) Subject: [Python-checkins] r87022 - in python/branches/py3k: Lib/test/test_array.py Misc/NEWS Modules/arraymodule.c Message-ID: <20101204110205.28A21EEA06@mail.python.org> Author: georg.brandl Date: Sat Dec 4 12:02:04 2010 New Revision: 87022 Log: #1569291: speed up array.repeat() by making only O(log n) memcpy() calls; the code follows unicode_repeat. Modified: python/branches/py3k/Lib/test/test_array.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/arraymodule.c Modified: python/branches/py3k/Lib/test/test_array.py ============================================================================== --- python/branches/py3k/Lib/test/test_array.py (original) +++ python/branches/py3k/Lib/test/test_array.py Sat Dec 4 12:02:04 2010 @@ -504,6 +504,12 @@ array.array(self.typecode) ) + a = 5 * array.array(self.typecode, self.example[:1]) + self.assertEqual( + a, + array.array(self.typecode, [a[0]] * 5) + ) + self.assertRaises(TypeError, a.__mul__, "bad") def test_imul(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 12:02:04 2010 @@ -45,6 +45,8 @@ Library ------- +- Issue #1569291: Speed up array.repeat(). + - Provide an interface to set the optimization level of compilation in py_compile, compileall and zipfile.PyZipFile. Modified: python/branches/py3k/Modules/arraymodule.c ============================================================================== --- python/branches/py3k/Modules/arraymodule.c (original) +++ python/branches/py3k/Modules/arraymodule.c Sat Dec 4 12:02:04 2010 @@ -674,11 +674,9 @@ static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { - Py_ssize_t i; Py_ssize_t size; arrayobject *np; - char *p; - Py_ssize_t nbytes; + Py_ssize_t oldbytes, newbytes; if (n < 0) n = 0; if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { @@ -688,13 +686,23 @@ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); if (np == NULL) return NULL; - p = np->ob_item; - nbytes = Py_SIZE(a) * a->ob_descr->itemsize; - for (i = 0; i < n; i++) { - memcpy(p, a->ob_item, nbytes); - p += nbytes; + if (n == 0) + return (PyObject *)np; + oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; + newbytes = oldbytes * n; + /* this follows the code in unicode_repeat */ + if (oldbytes == 1) { + memset(np->ob_item, a->ob_item[0], newbytes); + } else { + Py_ssize_t done = oldbytes; + Py_MEMCPY(np->ob_item, a->ob_item, oldbytes); + while (done < newbytes) { + Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; + Py_MEMCPY(np->ob_item+done, np->ob_item, ncopy); + done += ncopy; + } } - return (PyObject *) np; + return (PyObject *)np; } static int From python-checkins at python.org Sat Dec 4 12:06:25 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Dec 2010 12:06:25 +0100 (CET) Subject: [Python-checkins] r87023 - python/branches/py3k/Objects/longobject.c Message-ID: <20101204110625.B90E2EEA40@mail.python.org> Author: mark.dickinson Date: Sat Dec 4 12:06:25 2010 New Revision: 87023 Log: Fix indentation in Objects/longobject.c Modified: python/branches/py3k/Objects/longobject.c Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Sat Dec 4 12:06:25 2010 @@ -2144,9 +2144,9 @@ /* Replace non-ASCII whitespace with ' ' */ ptr = PyUnicode_AS_UNICODE(asciidig); for (i = 0; i < length; i++) { - Py_UNICODE ch = ptr[i]; - if (ch > 127 && Py_UNICODE_ISSPACE(ch)) - ptr[i] = ' '; + Py_UNICODE ch = ptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + ptr[i] = ' '; } buffer = _PyUnicode_AsStringAndSize(asciidig, &buflen); if (buffer == NULL) { From python-checkins at python.org Sat Dec 4 12:12:44 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 12:12:44 +0100 (CET) Subject: [Python-checkins] r87024 - in python/branches/py3k: Doc/library/shelve.rst Lib/shelve.py Lib/test/test_shelve.py Misc/NEWS Message-ID: <20101204111244.24A5CEE98D@mail.python.org> Author: georg.brandl Date: Sat Dec 4 12:12:43 2010 New Revision: 87024 Log: #7905: Actually respect the keyencoding parameter to shelve.Shelf. Modified: python/branches/py3k/Doc/library/shelve.rst python/branches/py3k/Lib/shelve.py python/branches/py3k/Lib/test/test_shelve.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k/Doc/library/shelve.rst (original) +++ python/branches/py3k/Doc/library/shelve.rst Sat Dec 4 12:12:43 2010 @@ -101,7 +101,7 @@ implementation used. -.. class:: Shelf(dict, protocol=None, writeback=False) +.. class:: Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8') A subclass of :class:`collections.MutableMapping` which stores pickled values in the *dict* object. @@ -115,8 +115,15 @@ This allows natural operations on mutable entries, but can consume much more memory and make sync and close take a long time. + The *keyencoding* parameter is the encoding used to encode keys before they + are used with the underlying dict. -.. class:: BsdDbShelf(dict, protocol=None, writeback=False) + .. versionadded:: 3.2 + The *keyencoding* parameter; previously, keys were always encoded in + UTF-8. + + +.. class:: BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8') A subclass of :class:`Shelf` which exposes :meth:`first`, :meth:`!next`, :meth:`previous`, :meth:`last` and :meth:`set_location` which are available @@ -125,8 +132,8 @@ modules. The *dict* object passed to the constructor must support those methods. This is generally accomplished by calling one of :func:`bsddb.hashopen`, :func:`bsddb.btopen` or :func:`bsddb.rnopen`. The - optional *protocol* and *writeback* parameters have the same interpretation - as for the :class:`Shelf` class. + optional *protocol*, *writeback*, and *keyencoding* parameters have the same + interpretation as for the :class:`Shelf` class. .. class:: DbfilenameShelf(filename, flag='c', protocol=None, writeback=False) Modified: python/branches/py3k/Lib/shelve.py ============================================================================== --- python/branches/py3k/Lib/shelve.py (original) +++ python/branches/py3k/Lib/shelve.py Sat Dec 4 12:12:43 2010 @@ -73,6 +73,7 @@ def __repr__(self): return '' + class Shelf(collections.MutableMapping): """Base class for shelf implementations. @@ -88,7 +89,7 @@ self._protocol = protocol self.writeback = writeback self.cache = {} - self.keyencoding = "utf-8" + self.keyencoding = keyencoding def __iter__(self): for k in self.dict.keys(): Modified: python/branches/py3k/Lib/test/test_shelve.py ============================================================================== --- python/branches/py3k/Lib/test/test_shelve.py (original) +++ python/branches/py3k/Lib/test/test_shelve.py Sat Dec 4 12:12:43 2010 @@ -122,6 +122,19 @@ self.assertEqual(len(d1), 1) self.assertEqual(len(d2), 1) + def test_keyencoding(self): + d = {} + key = 'P??p' + # the default keyencoding is utf-8 + shelve.Shelf(d)[key] = [1] + self.assertIn(key.encode('utf-8'), d) + # but a different one can be given + shelve.Shelf(d, keyencoding='latin1')[key] = [1] + self.assertIn(key.encode('latin1'), d) + # with all consequences + s = shelve.Shelf(d, keyencoding='ascii') + self.assertRaises(UnicodeEncodeError, s.__setitem__, key, [1]) + def test_writeback_also_writes_immediately(self): # Issue 5754 d = {} Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 12:12:43 2010 @@ -45,6 +45,8 @@ Library ------- +- Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf. + - Issue #1569291: Speed up array.repeat(). - Provide an interface to set the optimization level of compilation in From python-checkins at python.org Sat Dec 4 12:20:26 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Dec 2010 12:20:26 +0100 (CET) Subject: [Python-checkins] r87025 - in python/branches/py3k: Doc/library/pdb.rst Lib/pdb.py Misc/NEWS Message-ID: <20101204112026.67F11EE999@mail.python.org> Author: georg.brandl Date: Sat Dec 4 12:20:26 2010 New Revision: 87025 Log: Add the "interact" pdb command from pdb++. Modified: python/branches/py3k/Doc/library/pdb.rst python/branches/py3k/Lib/pdb.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/pdb.rst ============================================================================== --- python/branches/py3k/Doc/library/pdb.rst (original) +++ python/branches/py3k/Doc/library/pdb.rst Sat Dec 4 12:20:26 2010 @@ -407,6 +407,14 @@ .. versionadded:: 3.2 +.. pdbcommand:: interact + + Start an interative interpreter (using the :mod:`code` module) whose global + namespace contains all the (global and local) names found in the current + scope. + + .. versionadded:: 3.2 + .. _debugger-aliases: .. pdbcommand:: alias [name [command]] Modified: python/branches/py3k/Lib/pdb.py ============================================================================== --- python/branches/py3k/Lib/pdb.py (original) +++ python/branches/py3k/Lib/pdb.py Sat Dec 4 12:20:26 2010 @@ -67,15 +67,16 @@ # commands and is appended to __doc__ after the class has been defined. import sys -import linecache import cmd import bdb import dis import os import re +import code import pprint -import traceback import inspect +import traceback +import linecache class Restart(Exception): @@ -1167,6 +1168,16 @@ # None of the above... self.message(type(value)) + def do_interact(self, arg): + """interact + + Start an interative interpreter whose global namespace + contains all the (global and local) names found in the current scope. + """ + ns = self.curframe.f_globals.copy() + ns.update(self.curframe_locals) + code.interact("*interactive*", local=ns) + def do_alias(self, arg): """alias [name [command [parameter parameter ...] ]] Create an alias called 'name' that executes 'command'. The @@ -1342,8 +1353,8 @@ 'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable', 'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until', 'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist', - 'args', 'print', 'pp', 'whatis', 'source', 'alias', 'unalias', - 'debug', 'quit', + 'args', 'print', 'pp', 'whatis', 'source', 'interact', 'alias', + 'unalias', 'debug', 'quit', ] for _command in _help_order: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 4 12:20:26 2010 @@ -45,6 +45,8 @@ Library ------- +- Add the "interact" pdb command. + - Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf. - Issue #1569291: Speed up array.repeat(). From python-checkins at python.org Sat Dec 4 12:22:11 2010 From: python-checkins at python.org (gregory.p.smith) Date: Sat, 4 Dec 2010 12:22:11 +0100 (CET) Subject: [Python-checkins] r87026 - in python/branches/py3k: Lib/subprocess.py Modules/_posixsubprocess.c Message-ID: <20101204112211.419BBEE995@mail.python.org> Author: gregory.p.smith Date: Sat Dec 4 12:22:11 2010 New Revision: 87026 Log: issue6559: Adds a pass_fds parameter to subprocess.Popen that allows the caller to list exactly which file descriptors should be kept open. Modified: python/branches/py3k/Lib/subprocess.py python/branches/py3k/Modules/_posixsubprocess.c Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Sat Dec 4 12:22:11 2010 @@ -608,7 +608,8 @@ preexec_fn=None, close_fds=None, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, - restore_signals=True, start_new_session=False): + restore_signals=True, start_new_session=False, + pass_fds=()): """Create new Popen instance.""" _cleanup() @@ -644,6 +645,9 @@ raise ValueError("creationflags is only supported on Windows " "platforms") + if pass_fds and not close_fds: + raise ValueError("pass_fds requires close_fds=True.") + self.stdin = None self.stdout = None self.stderr = None @@ -671,7 +675,7 @@ errread, errwrite) = self._get_handles(stdin, stdout, stderr) self._execute_child(args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, + pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, @@ -848,7 +852,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, + pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, @@ -856,6 +860,8 @@ unused_restore_signals, unused_start_new_session): """Execute program (MS Windows version)""" + assert not pass_fds, "pass_fds not yet supported on Windows" + if not isinstance(args, str): args = list2cmdline(args) @@ -1075,8 +1081,19 @@ os.closerange(but + 1, MAXFD) + def _close_all_but_a_sorted_few_fds(self, fds_to_keep): + # precondition: fds_to_keep must be sorted and unique + start_fd = 3 + for fd in fds_to_keep: + if fd > start_fd: + os.closerange(start_fd, fd) + start_fd = fd + 1 + if start_fd <= MAXFD: + os.closerange(start_fd, MAXFD) + + def _execute_child(self, args, executable, preexec_fn, close_fds, - cwd, env, universal_newlines, + pass_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, @@ -1124,9 +1141,11 @@ executable_list = tuple( os.path.join(os.fsencode(dir), executable) for dir in os.get_exec_path(env)) + fds_to_keep = set(pass_fds) + fds_to_keep.add(errpipe_write) self.pid = _posixsubprocess.fork_exec( args, executable_list, - close_fds, cwd, env_list, + close_fds, sorted(fds_to_keep), cwd, env_list, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, @@ -1180,7 +1199,14 @@ # Close all other fds, if asked for if close_fds: - self._close_fds(but=errpipe_write) + if pass_fds: + fds_to_keep = set(pass_fds) + fds_to_keep.add(errpipe_write) + self._close_all_but_a_sorted_few_fds( + sorted(fds_to_keep)) + else: + self._close_fds(but=errpipe_write) + if cwd is not None: os.chdir(cwd) Modified: python/branches/py3k/Modules/_posixsubprocess.c ============================================================================== --- python/branches/py3k/Modules/_posixsubprocess.c (original) +++ python/branches/py3k/Modules/_posixsubprocess.c Sat Dec 4 12:22:11 2010 @@ -42,7 +42,8 @@ int errread, int errwrite, int errpipe_read, int errpipe_write, int close_fds, int restore_signals, - int call_setsid, + int call_setsid, Py_ssize_t num_fds_to_keep, + PyObject *py_fds_to_keep, PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) { @@ -91,11 +92,28 @@ /* close() is intentionally not checked for errors here as we are closing */ /* a large range of fds, some of which may be invalid. */ if (close_fds) { - for (fd_num = 3; fd_num < errpipe_write; ++fd_num) { - close(fd_num); - } - for (fd_num = errpipe_write+1; fd_num < max_fd; ++fd_num) { - close(fd_num); + Py_ssize_t keep_seq_idx; + int start_fd = 3; + for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { + PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep, + keep_seq_idx); + int keep_fd = PyLong_AsLong(py_keep_fd); + if (keep_fd < 0) { /* Negative number, overflow or not a Long. */ + err_msg = "bad value in fds_to_keep."; + errno = 0; /* We don't want to report an OSError. */ + goto error; + } + if (keep_fd <= start_fd) + continue; + for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { + close(fd_num); + } + start_fd = keep_fd + 1; + } + if (start_fd <= max_fd) { + for (fd_num = start_fd; fd_num < max_fd; ++fd_num) { + close(fd_num); + } } } @@ -170,7 +188,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) { PyObject *gc_module = NULL; - PyObject *executable_list, *py_close_fds; + PyObject *executable_list, *py_close_fds, *py_fds_to_keep; PyObject *env_list, *preexec_fn; PyObject *process_args, *converted_args = NULL, *fast_args = NULL; PyObject *preexec_fn_args_tuple = NULL; @@ -182,11 +200,11 @@ pid_t pid; int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; - Py_ssize_t arg_num; + Py_ssize_t arg_num, num_fds_to_keep; if (!PyArg_ParseTuple( - args, "OOOOOiiiiiiiiiiO:fork_exec", - &process_args, &executable_list, &py_close_fds, + args, "OOOOOOiiiiiiiiiiO:fork_exec", + &process_args, &executable_list, &py_close_fds, &py_fds_to_keep, &cwd_obj, &env_list, &p2cread, &p2cwrite, &c2pread, &c2pwrite, &errread, &errwrite, &errpipe_read, &errpipe_write, @@ -198,6 +216,11 @@ PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); return NULL; } + num_fds_to_keep = PySequence_Length(py_fds_to_keep); + if (num_fds_to_keep < 0) { + PyErr_SetString(PyExc_ValueError, "bad fds_to_keep"); + return NULL; + } /* We need to call gc.disable() when we'll be calling preexec_fn */ if (preexec_fn != Py_None) { @@ -298,6 +321,7 @@ p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, close_fds, restore_signals, call_setsid, + num_fds_to_keep, py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); _exit(255); return NULL; /* Dead code to avoid a potential compiler warning. */ From python-checkins at python.org Sat Dec 4 12:36:58 2010 From: python-checkins at python.org (gregory.p.smith) Date: Sat, 4 Dec 2010 12:36:58 +0100 (CET) Subject: [Python-checkins] r87027 - python/branches/py3k/Doc/tools/sphinxext/static/basic.css Message-ID: <20101204113658.ABA4DEE995@mail.python.org> Author: gregory.p.smith Date: Sat Dec 4 12:36:58 2010 New Revision: 87027 Log: issue10622: fix superflous scrollbar on the right side of
 boxes in the
generated html docs.  visible in chrome, possibly other webkit browsers.


Modified:
   python/branches/py3k/Doc/tools/sphinxext/static/basic.css

Modified: python/branches/py3k/Doc/tools/sphinxext/static/basic.css
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/static/basic.css	(original)
+++ python/branches/py3k/Doc/tools/sphinxext/static/basic.css	Sat Dec  4 12:36:58 2010
@@ -364,6 +364,7 @@
 
 pre {
     overflow: auto;
+    overflow-y: hidden;
 }
 
 td.linenos pre {

From python-checkins at python.org  Sat Dec  4 12:48:12 2010
From: python-checkins at python.org (lukasz.langa)
Date: Sat,  4 Dec 2010 12:48:12 +0100 (CET)
Subject: [Python-checkins] r87028 - python/branches/py3k/Lib/configparser.py
Message-ID: <20101204114812.1B65AEE985@mail.python.org>

Author: lukasz.langa
Date: Sat Dec  4 12:48:11 2010
New Revision: 87028

Log:
configparser: minute refactoring of RawConfigParser.items()



Modified:
   python/branches/py3k/Lib/configparser.py

Modified: python/branches/py3k/Lib/configparser.py
==============================================================================
--- python/branches/py3k/Lib/configparser.py	(original)
+++ python/branches/py3k/Lib/configparser.py	Sat Dec  4 12:48:11 2010
@@ -848,15 +848,11 @@
         if vars:
             for key, value in vars.items():
                 d[self.optionxform(key)] = value
-        options = list(d.keys())
+        value_getter = lambda option: self._interpolation.before_get(self,
+            section, option, d[option], d)
         if raw:
-            return [(option, d[option])
-                    for option in options]
-        else:
-            return [(option, self._interpolation.before_get(self, section,
-                                                            option, d[option],
-                                                            d))
-                    for option in options]
+            value_getter = lambda option: d[option]
+        return [(option, value_getter(option)) for option in d.keys()]
 
     def optionxform(self, optionstr):
         return optionstr.lower()

From python-checkins at python.org  Sat Dec  4 12:52:59 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 12:52:59 +0100 (CET)
Subject: [Python-checkins] r87029 -
	python/branches/py3k/Objects/floatobject.c
Message-ID: <20101204115259.00445EE995@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 12:52:58 2010
New Revision: 87029

Log:
Remove some unecessary '#ifdef Py_NAN's from floatobject.c

Modified:
   python/branches/py3k/Objects/floatobject.c

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Sat Dec  4 12:52:58 2010
@@ -575,13 +575,11 @@
     double a,b;
     CONVERT_TO_DOUBLE(v, a);
     CONVERT_TO_DOUBLE(w, b);
-#ifdef Py_NAN
     if (b == 0.0) {
         PyErr_SetString(PyExc_ZeroDivisionError,
                         "float division by zero");
         return NULL;
     }
-#endif
     PyFPE_START_PROTECT("divide", return 0)
     a = a / b;
     PyFPE_END_PROTECT(a)
@@ -595,13 +593,11 @@
     double mod;
     CONVERT_TO_DOUBLE(v, vx);
     CONVERT_TO_DOUBLE(w, wx);
-#ifdef Py_NAN
     if (wx == 0.0) {
         PyErr_SetString(PyExc_ZeroDivisionError,
                         "float modulo");
         return NULL;
     }
-#endif
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
     /* note: checking mod*wx < 0 is incorrect -- underflows to
@@ -1492,13 +1488,11 @@
                       "Cannot pass infinity to float.as_integer_ratio.");
       return NULL;
     }
-#ifdef Py_NAN
     if (Py_IS_NAN(self)) {
       PyErr_SetString(PyExc_ValueError,
                       "Cannot pass NaN to float.as_integer_ratio.");
       return NULL;
     }
-#endif
 
     PyFPE_START_PROTECT("as_integer_ratio", goto error);
     float_part = frexp(self, &exponent);        /* self == float_part * 2**exponent exactly */

From python-checkins at python.org  Sat Dec  4 13:00:49 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat,  4 Dec 2010 13:00:49 +0100 (CET)
Subject: [Python-checkins] r87030 - in python/branches/py3k:
	Include/pythonrun.h PC/python3.def
Message-ID: <20101204120049.93710EEA3D@mail.python.org>

Author: martin.v.loewis
Date: Sat Dec  4 13:00:49 2010
New Revision: 87030

Log:
Expose CompileString, not CompileStringFlags under the
limited API.


Modified:
   python/branches/py3k/Include/pythonrun.h
   python/branches/py3k/PC/python3.def

Modified: python/branches/py3k/Include/pythonrun.h
==============================================================================
--- python/branches/py3k/Include/pythonrun.h	(original)
+++ python/branches/py3k/Include/pythonrun.h	Sat Dec  4 13:00:49 2010
@@ -74,7 +74,7 @@
 #endif
 
 #ifdef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int);
+PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int);
 #else
 #define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1)
 #define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1)

Modified: python/branches/py3k/PC/python3.def
==============================================================================
--- python/branches/py3k/PC/python3.def	(original)
+++ python/branches/py3k/PC/python3.def	Sat Dec  4 13:00:49 2010
@@ -632,7 +632,7 @@
   Py_AddPendingCall=python32.Py_AddPendingCall
   Py_AtExit=python32.Py_AtExit
   Py_BuildValue=python32.Py_BuildValue
-  Py_CompileStringFlags=python32.Py_CompileStringFlags
+  Py_CompileString=python32.Py_CompileString
   Py_DecRef=python32.Py_DecRef
   Py_EndInterpreter=python32.Py_EndInterpreter
   Py_Exit=python32.Py_Exit

From python-checkins at python.org  Sat Dec  4 13:20:57 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sat,  4 Dec 2010 13:20:57 +0100 (CET)
Subject: [Python-checkins] r87031 - python/branches/py3k/PCbuild/pcbuild.sln
Message-ID: <20101204122057.4BE4BEE999@mail.python.org>

Author: hirokazu.yamamoto
Date: Sat Dec  4 13:20:57 2010
New Revision: 87031

Log:
I hope this will fix Win2008(x64) buildbot error.


Modified:
   python/branches/py3k/PCbuild/pcbuild.sln

Modified: python/branches/py3k/PCbuild/pcbuild.sln
==============================================================================
--- python/branches/py3k/PCbuild/pcbuild.sln	(original)
+++ python/branches/py3k/PCbuild/pcbuild.sln	Sat Dec  4 13:20:57 2010
@@ -560,28 +560,34 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGUpdate|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Release|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Release|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Release|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Release|x64
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = PGUpdate|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = PGUpdate|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.Build.0 = PGUpdate|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.Build.0 = Debug|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Debug|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.Build.0 = Debug|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = Release|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = Release|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = Release|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = Release|Win32
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64
+		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64
 		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32
 		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32
 		{F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64

From python-checkins at python.org  Sat Dec  4 13:25:30 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 13:25:30 +0100 (CET)
Subject: [Python-checkins] r87032 - in python/branches/py3k:
	Lib/test/test_float.py Misc/NEWS Objects/floatobject.c
Message-ID: <20101204122530.A25B7EE999@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 13:25:30 2010
New Revision: 87032

Log:
Issue #10596: Fix float.__mod__ to have the same behaviour as
float.__divmod__ with respect to signed zeros.


Modified:
   python/branches/py3k/Lib/test/test_float.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/floatobject.c

Modified: python/branches/py3k/Lib/test/test_float.py
==============================================================================
--- python/branches/py3k/Lib/test/test_float.py	(original)
+++ python/branches/py3k/Lib/test/test_float.py	Sat Dec  4 13:25:30 2010
@@ -197,6 +197,26 @@
         self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
 
     @requires_IEEE_754
+    def test_float_mod(self):
+        # Check behaviour of % operator for IEEE 754 special cases.
+        # In particular, check signs of zeros.
+        mod = operator.mod
+
+        self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
+        self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
+        self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
+
+        self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
+        self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
+        self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
+
+    @requires_IEEE_754
     def test_float_pow(self):
         # test builtin pow and ** operator for IEEE 754 special cases.
         # Special cases taken from section F.9.4.4 of the C99 specification

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 13:25:30 2010
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #10596: Fix float.__mod__ to have the same behaviour as
+  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
+  0.0, not -0.0.
+
 - Issue #1772833: Add the -q command-line option to suppress copyright
   and version output in interactive mode.
 

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Sat Dec  4 13:25:30 2010
@@ -600,10 +600,20 @@
     }
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
-    /* note: checking mod*wx < 0 is incorrect -- underflows to
-       0 if wx < sqrt(smallest nonzero double) */
-    if (mod && ((wx < 0) != (mod < 0))) {
-        mod += wx;
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);

From python-checkins at python.org  Sat Dec  4 13:30:41 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 13:30:41 +0100 (CET)
Subject: [Python-checkins] r87033 - in python/branches/release27-maint:
	Lib/test/test_float.py Misc/NEWS Objects/floatobject.c
Message-ID: <20101204123041.BB0D9EE999@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 13:30:41 2010
New Revision: 87033

Log:
Merged revisions 87032 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87032 | mark.dickinson | 2010-12-04 12:25:30 +0000 (Sat, 04 Dec 2010) | 3 lines
  
  Issue #10596: Fix float.__mod__ to have the same behaviour as
  float.__divmod__ with respect to signed zeros.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/test/test_float.py
   python/branches/release27-maint/Misc/NEWS
   python/branches/release27-maint/Objects/floatobject.c

Modified: python/branches/release27-maint/Lib/test/test_float.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_float.py	(original)
+++ python/branches/release27-maint/Lib/test/test_float.py	Sat Dec  4 13:30:41 2010
@@ -162,6 +162,26 @@
         self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
 
     @requires_IEEE_754
+    def test_float_mod(self):
+        # Check behaviour of % operator for IEEE 754 special cases.
+        # In particular, check signs of zeros.
+        mod = operator.mod
+
+        self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
+        self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
+        self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
+
+        self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
+        self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
+        self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
+
+    @requires_IEEE_754
     def test_float_pow(self):
         # test builtin pow and ** operator for IEEE 754 special cases.
         # Special cases taken from section F.9.4.4 of the C99 specification

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sat Dec  4 13:30:41 2010
@@ -9,6 +9,10 @@
 Core and Builtins
 -----------------
 
+- Issue #10596: Fix float.__mod__ to have the same behaviour as
+  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
+  0.0, not -0.0.
+
 Library
 -------
 

Modified: python/branches/release27-maint/Objects/floatobject.c
==============================================================================
--- python/branches/release27-maint/Objects/floatobject.c	(original)
+++ python/branches/release27-maint/Objects/floatobject.c	Sat Dec  4 13:30:41 2010
@@ -716,10 +716,20 @@
 #endif
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
-    /* note: checking mod*wx < 0 is incorrect -- underflows to
-       0 if wx < sqrt(smallest nonzero double) */
-    if (mod && ((wx < 0) != (mod < 0))) {
-        mod += wx;
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);

From python-checkins at python.org  Sat Dec  4 13:38:19 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 13:38:19 +0100 (CET)
Subject: [Python-checkins] r87034 - in python/branches/release31-maint:
	Lib/test/test_float.py Misc/NEWS Objects/floatobject.c
Message-ID: <20101204123819.72967EE999@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 13:38:19 2010
New Revision: 87034

Log:
Merged revisions 87032 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87032 | mark.dickinson | 2010-12-04 12:25:30 +0000 (Sat, 04 Dec 2010) | 3 lines
  
  Issue #10596: Fix float.__mod__ to have the same behaviour as
  float.__divmod__ with respect to signed zeros.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_float.py
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Objects/floatobject.c

Modified: python/branches/release31-maint/Lib/test/test_float.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_float.py	(original)
+++ python/branches/release31-maint/Lib/test/test_float.py	Sat Dec  4 13:38:19 2010
@@ -231,6 +231,26 @@
             self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
 
 
+    @requires_IEEE_754
+    def test_float_mod(self):
+        # Check behaviour of % operator for IEEE 754 special cases.
+        # In particular, check signs of zeros.
+        mod = operator.mod
+
+        self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
+        self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
+        self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
+
+        self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
+        self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
+        self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
+
 
 class FormatFunctionsTestCase(unittest.TestCase):
 

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sat Dec  4 13:38:19 2010
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #10596: Fix float.__mod__ to have the same behaviour as
+  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
+  0.0, not -0.0.
+
 Library
 -------
 

Modified: python/branches/release31-maint/Objects/floatobject.c
==============================================================================
--- python/branches/release31-maint/Objects/floatobject.c	(original)
+++ python/branches/release31-maint/Objects/floatobject.c	Sat Dec  4 13:38:19 2010
@@ -600,10 +600,20 @@
 #endif
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
-    /* note: checking mod*wx < 0 is incorrect -- underflows to
-       0 if wx < sqrt(smallest nonzero double) */
-    if (mod && ((wx < 0) != (mod < 0))) {
-        mod += wx;
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);

From python-checkins at python.org  Sat Dec  4 13:42:18 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 13:42:18 +0100 (CET)
Subject: [Python-checkins] r87035 - in python/branches/release31-maint:
	Lib/test/test_float.py Misc/NEWS Objects/floatobject.c
Message-ID: <20101204124218.6DB58EE9F3@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 13:42:18 2010
New Revision: 87035

Log:
Backout broken backport.  (Sorry.)

Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_float.py
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Objects/floatobject.c

Modified: python/branches/release31-maint/Lib/test/test_float.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_float.py	(original)
+++ python/branches/release31-maint/Lib/test/test_float.py	Sat Dec  4 13:42:18 2010
@@ -12,6 +12,16 @@
 INF = float("inf")
 NAN = float("nan")
 
+have_getformat = hasattr(float, "__getformat__")
+requires_getformat = unittest.skipUnless(have_getformat,
+                                         "requires __getformat__")
+requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
+                                         "requires __setformat__")
+# decorator for skipping tests on non-IEEE 754 platforms
+requires_IEEE_754 = unittest.skipUnless(have_getformat and
+    float.__getformat__("double").startswith("IEEE"),
+    "test requires IEEE 754 doubles")
+
 #locate file with float format test values
 test_dir = os.path.dirname(__file__) or os.curdir
 format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
@@ -231,26 +241,6 @@
             self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
 
 
-    @requires_IEEE_754
-    def test_float_mod(self):
-        # Check behaviour of % operator for IEEE 754 special cases.
-        # In particular, check signs of zeros.
-        mod = operator.mod
-
-        self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
-        self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
-        self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
-        self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
-        self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
-        self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
-
-        self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
-        self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
-        self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
-        self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
-        self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
-        self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
-
 
 class FormatFunctionsTestCase(unittest.TestCase):
 

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sat Dec  4 13:42:18 2010
@@ -10,10 +10,6 @@
 Core and Builtins
 -----------------
 
-- Issue #10596: Fix float.__mod__ to have the same behaviour as
-  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
-  0.0, not -0.0.
-
 Library
 -------
 

Modified: python/branches/release31-maint/Objects/floatobject.c
==============================================================================
--- python/branches/release31-maint/Objects/floatobject.c	(original)
+++ python/branches/release31-maint/Objects/floatobject.c	Sat Dec  4 13:42:18 2010
@@ -600,20 +600,10 @@
 #endif
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
-    if (mod) {
-        /* ensure the remainder has the same sign as the denominator */
-        if ((wx < 0) != (mod < 0)) {
-            mod += wx;
-        }
-    }
-    else {
-        /* the remainder is zero, and in the presence of signed zeroes
-           fmod returns different results across platforms; ensure
-           it has the same sign as the denominator; we'd like to do
-           "mod = wx * 0.0", but that may get optimized away */
-        mod *= mod;  /* hide "mod = +0" from optimizer */
-        if (wx < 0.0)
-            mod = -mod;
+    /* note: checking mod*wx < 0 is incorrect -- underflows to
+       0 if wx < sqrt(smallest nonzero double) */
+    if (mod && ((wx < 0) != (mod < 0))) {
+        mod += wx;
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);

From python-checkins at python.org  Sat Dec  4 13:46:02 2010
From: python-checkins at python.org (lukasz.langa)
Date: Sat,  4 Dec 2010 13:46:02 +0100 (CET)
Subject: [Python-checkins] r87036 - in python/branches/py3k:
	Doc/library/configparser.rst Lib/configparser.py
	Lib/test/test_cfgparser.py
Message-ID: <20101204124602.226A0EE9F5@mail.python.org>

Author: lukasz.langa
Date: Sat Dec  4 13:46:01 2010
New Revision: 87036

Log:
configparser: fixed inconsistency where in SafeConfigParser option values
 were ensured to be strings but section names and option keys were not.
 Behaviour unchanged for RawConfigParser and ConfigParser.



Modified:
   python/branches/py3k/Doc/library/configparser.rst
   python/branches/py3k/Lib/configparser.py
   python/branches/py3k/Lib/test/test_cfgparser.py

Modified: python/branches/py3k/Doc/library/configparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/configparser.rst	(original)
+++ python/branches/py3k/Doc/library/configparser.rst	Sat Dec  4 13:46:01 2010
@@ -836,7 +836,11 @@
 
       Add a section named *section* to the instance.  If a section by the given
       name already exists, :exc:`DuplicateSectionError` is raised.  If the
-      *default section* name is passed, :exc:`ValueError` is raised.
+      *default section* name is passed, :exc:`ValueError` is raised.  The name
+      of the section must be a string; if not, :exc:`TypeError` is raised.
+
+      .. versionchanged:: 3.2
+         Non-string section names raise :exc:`TypeError`.
 
 
    .. method:: has_section(section)
@@ -976,8 +980,8 @@
    .. method:: set(section, option, value)
 
       If the given section exists, set the given option to the specified value;
-      otherwise raise :exc:`NoSectionError`.  *value* must be a string; if not,
-      :exc:`TypeError` is raised.
+      otherwise raise :exc:`NoSectionError`.  *option* and *value* must be
+      strings; if not, :exc:`TypeError` is raised.
 
 
    .. method:: write(fileobject, space_around_delimiters=True)
@@ -1044,7 +1048,7 @@
 .. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True, default_section=configaparser.DEFAULTSECT, interpolation=None)
 
    Legacy variant of the :class:`SafeConfigParser` with interpolation disabled
-   by default and an unsafe ``set`` method.
+   by default and unsafe ``add_section`` and ``set`` methods.
 
    .. note::
       Consider using :class:`SafeConfigParser` instead which checks types of
@@ -1052,6 +1056,16 @@
       can use ``SafeConfigParser(interpolation=None)``.
 
 
+   .. method:: add_section(section)
+
+      Add a section named *section* to the instance.  If a section by the given
+      name already exists, :exc:`DuplicateSectionError` is raised.  If the
+      *default section* name is passed, :exc:`ValueError` is raised.
+
+      Type of *section* is not checked which lets users create non-string named
+      sections. This behaviour is unsupported and may cause internal errors.
+
+
    .. method:: set(section, option, value)
 
       If the given section exists, set the given option to the specified value;

Modified: python/branches/py3k/Lib/configparser.py
==============================================================================
--- python/branches/py3k/Lib/configparser.py	(original)
+++ python/branches/py3k/Lib/configparser.py	Sat Dec  4 13:46:01 2010
@@ -727,11 +727,15 @@
         that should be present in the section. If the used dictionary type
         preserves order, sections and their keys will be added in order.
 
+        All types held in the dictionary are converted to strings during
+        reading, including section names, option names and keys.
+
         Optional second argument is the `source' specifying the name of the
         dictionary being read.
         """
         elements_added = set()
         for section, keys in dictionary.items():
+            section = str(section)
             try:
                 self.add_section(section)
             except (DuplicateSectionError, ValueError):
@@ -739,7 +743,7 @@
                     raise
                 elements_added.add(section)
             for key, value in keys.items():
-                key = self.optionxform(key)
+                key = self.optionxform(str(key))
                 if value is not None:
                     value = str(value)
                 if self._strict and (section, key) in elements_added:
@@ -1128,7 +1132,7 @@
             raise ValueError('Not a boolean: %s' % value)
         return self.BOOLEAN_STATES[value.lower()]
 
-    def _validate_value_type(self, value):
+    def _validate_value_types(self, *, section="", option="", value=""):
         """Raises a TypeError for non-string values.
 
         The only legal non-string value if we allow valueless
@@ -1141,6 +1145,10 @@
         for RawConfigParsers and ConfigParsers. It is invoked in every
         case for mapping protocol access and in SafeConfigParser.set().
         """
+        if not isinstance(section, str):
+            raise TypeError("section names must be strings")
+        if not isinstance(option, str):
+            raise TypeError("option keys must be strings")
         if not self._allow_no_value or value:
             if not isinstance(value, str):
                 raise TypeError("option values must be strings")
@@ -1169,9 +1177,16 @@
     def set(self, section, option, value=None):
         """Set an option.  Extends RawConfigParser.set by validating type and
         interpolation syntax on the value."""
-        self._validate_value_type(value)
+        self._validate_value_types(option=option, value=value)
         super().set(section, option, value)
 
+    def add_section(self, section):
+        """Create a new section in the configuration.  Extends
+        RawConfigParser.add_section by validating if the section name is
+        a string."""
+        self._validate_value_types(section=section)
+        super().add_section(section)
+
 
 class SectionProxy(MutableMapping):
     """A proxy for a single section from a parser."""
@@ -1196,7 +1211,7 @@
         return self._parser.get(self._name, key)
 
     def __setitem__(self, key, value):
-        self._parser._validate_value_type(value)
+        self._parser._validate_value_types(option=key, value=value)
         return self._parser.set(self._name, key, value)
 
     def __delitem__(self, key):

Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py	(original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py	Sat Dec  4 13:46:01 2010
@@ -106,6 +106,7 @@
         self.assertAlmostEqual(cf.getfloat('Types', 'float'), 0.44)
         eq(cf.get('Types', 'float'), "0.44")
         eq(cf.getboolean('Types', 'boolean'), False)
+        eq(cf.get('Types', '123'), 'strange but acceptable')
         if self.allow_no_value:
             eq(cf.get('NoValue', 'option-without-value'), None)
 
@@ -214,6 +215,7 @@
 int {0[1]} 42
 float {0[0]} 0.44
 boolean {0[0]} NO
+123 {0[1]} strange but acceptable
 """.format(self.delimiters, self.comment_prefixes)
         if self.allow_no_value:
             config_string += (
@@ -286,6 +288,7 @@
                 "int": 42,
                 "float": 0.44,
                 "boolean": False,
+                123: "strange but acceptable",
             },
         }
         if self.allow_no_value:
@@ -716,6 +719,15 @@
                                 raw=True), '%(list)s')
         self.assertRaises(ValueError, cf.get, 'non-string',
                           'string_with_interpolation', raw=False)
+        cf.add_section(123)
+        cf.set(123, 'this is sick', True)
+        self.assertEqual(cf.get(123, 'this is sick', raw=True), True)
+        with self.assertRaises(TypeError):
+            cf.get(123, 'this is sick')
+        cf.optionxform = lambda x: x
+        cf.set('non-string', 1, 1)
+        self.assertRaises(TypeError, cf.get, 'non-string', 1, 1)
+        self.assertEqual(cf.get('non-string', 1, raw=True), 1)
 
 class ConfigParserTestCaseNonStandardDelimiters(ConfigParserTestCase):
     delimiters = (':=', '$')
@@ -783,6 +795,15 @@
         self.assertEqual(cf.get('non-string', 'list'),
                          [0, 1, 1, 2, 3, 5, 8, 13])
         self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159})
+        cf.add_section(123)
+        cf.set(123, 'this is sick', True)
+        self.assertEqual(cf.get(123, 'this is sick'), True)
+        if cf._dict.__class__ is configparser._default_dict:
+            # would not work for SortedDict; only checking for the most common
+            # default dictionary (OrderedDict)
+            cf.optionxform = lambda x: x
+            cf.set('non-string', 1, 1)
+            self.assertEqual(cf.get('non-string', 1), 1)
 
 class RawConfigParserTestCaseNonStandardDelimiters(RawConfigParserTestCase):
     delimiters = (':=', '$')
@@ -848,6 +869,8 @@
         self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
         self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
         self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+        self.assertRaises(TypeError, cf.set, "sect", 123, "invalid opt name!")
+        self.assertRaises(TypeError, cf.add_section, 123)
 
     def test_add_section_default(self):
         cf = self.newconfig()

From python-checkins at python.org  Sat Dec  4 14:04:18 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 14:04:18 +0100 (CET)
Subject: [Python-checkins] r87037 - in python/branches/release31-maint:
	Lib/test/test_float.py Misc/NEWS Objects/floatobject.c
Message-ID: <20101204130418.7F13CEEA42@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 14:04:18 2010
New Revision: 87037

Log:
Merged revisions 87032 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87032 | mark.dickinson | 2010-12-04 12:25:30 +0000 (Sat, 04 Dec 2010) | 3 lines
  
  Issue #10596: Fix float.__mod__ to have the same behaviour as
  float.__divmod__ with respect to signed zeros.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_float.py
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Objects/floatobject.c

Modified: python/branches/release31-maint/Lib/test/test_float.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_float.py	(original)
+++ python/branches/release31-maint/Lib/test/test_float.py	Sat Dec  4 14:04:18 2010
@@ -240,6 +240,31 @@
             self.assertTrue(s == s, "{%r} not equal to itself" % f)
             self.assertTrue(d == d, "{%r : None} not equal to itself" % f)
 
+    def assertEqualAndEqualSign(self, a, b):
+        # fail unless a == b and a and b have the same sign bit;
+        # the only difference from assertEqual is that this test
+        # distingishes -0.0 and 0.0.
+        self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
+
+    @requires_IEEE_754
+    def test_float_mod(self):
+        # Check behaviour of % operator for IEEE 754 special cases.
+        # In particular, check signs of zeros.
+        mod = operator.mod
+
+        self.assertEqualAndEqualSign(mod(-1.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, 1.0), 1.0)
+        self.assertEqualAndEqualSign(mod(-0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(0.0, 1.0), 0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, 1.0), 1e-100)
+        self.assertEqualAndEqualSign(mod(1.0, 1.0), 0.0)
+
+        self.assertEqualAndEqualSign(mod(-1.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(-1e-100, -1.0), -1e-100)
+        self.assertEqualAndEqualSign(mod(-0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(0.0, -1.0), -0.0)
+        self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
+        self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
 
 
 class FormatFunctionsTestCase(unittest.TestCase):

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sat Dec  4 14:04:18 2010
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #10596: Fix float.__mod__ to have the same behaviour as
+  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
+  0.0, not -0.0.
+
 Library
 -------
 

Modified: python/branches/release31-maint/Objects/floatobject.c
==============================================================================
--- python/branches/release31-maint/Objects/floatobject.c	(original)
+++ python/branches/release31-maint/Objects/floatobject.c	Sat Dec  4 14:04:18 2010
@@ -600,10 +600,20 @@
 #endif
     PyFPE_START_PROTECT("modulo", return 0)
     mod = fmod(vx, wx);
-    /* note: checking mod*wx < 0 is incorrect -- underflows to
-       0 if wx < sqrt(smallest nonzero double) */
-    if (mod && ((wx < 0) != (mod < 0))) {
-        mod += wx;
+    if (mod) {
+        /* ensure the remainder has the same sign as the denominator */
+        if ((wx < 0) != (mod < 0)) {
+            mod += wx;
+        }
+    }
+    else {
+        /* the remainder is zero, and in the presence of signed zeroes
+           fmod returns different results across platforms; ensure
+           it has the same sign as the denominator; we'd like to do
+           "mod = wx * 0.0", but that may get optimized away */
+        mod *= mod;  /* hide "mod = +0" from optimizer */
+        if (wx < 0.0)
+            mod = -mod;
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);

From python-checkins at python.org  Sat Dec  4 14:14:29 2010
From: python-checkins at python.org (mark.dickinson)
Date: Sat,  4 Dec 2010 14:14:29 +0100 (CET)
Subject: [Python-checkins] r87038 -
	python/branches/py3k/Objects/floatobject.c
Message-ID: <20101204131429.98941EE985@mail.python.org>

Author: mark.dickinson
Date: Sat Dec  4 14:14:29 2010
New Revision: 87038

Log:
Use copysign to produce appropriately signed zeros instead of trying to worm around possible compiler optimizations.

Modified:
   python/branches/py3k/Objects/floatobject.c

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Sat Dec  4 14:14:29 2010
@@ -609,11 +609,8 @@
     else {
         /* the remainder is zero, and in the presence of signed zeroes
            fmod returns different results across platforms; ensure
-           it has the same sign as the denominator; we'd like to do
-           "mod = wx * 0.0", but that may get optimized away */
-        mod *= mod;  /* hide "mod = +0" from optimizer */
-        if (wx < 0.0)
-            mod = -mod;
+           it has the same sign as the denominator. */
+        mod = copysign(0.0, wx);
     }
     PyFPE_END_PROTECT(mod)
     return PyFloat_FromDouble(mod);
@@ -649,11 +646,8 @@
     else {
         /* the remainder is zero, and in the presence of signed zeroes
            fmod returns different results across platforms; ensure
-           it has the same sign as the denominator; we'd like to do
-           "mod = wx * 0.0", but that may get optimized away */
-        mod *= mod;  /* hide "mod = +0" from optimizer */
-        if (wx < 0.0)
-            mod = -mod;
+           it has the same sign as the denominator. */
+        mod = copysign(0.0, wx);
     }
     /* snap quotient to nearest integral value */
     if (div) {
@@ -663,8 +657,7 @@
     }
     else {
         /* div is zero - get the same sign as the true quotient */
-        div *= div;             /* hide "div = +0" from optimizers */
-        floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
+        floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
     }
     PyFPE_END_PROTECT(floordiv)
     return Py_BuildValue("(dd)", floordiv, mod);

From python-checkins at python.org  Sat Dec  4 14:27:34 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 14:27:34 +0100 (CET)
Subject: [Python-checkins] r87039 - in python/branches/py3k:
	Lib/test/test_complex.py Objects/complexobject.c
Message-ID: <20101204132734.BF017EE9F5@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 14:27:34 2010
New Revision: 87039

Log:
Removed static function complex_format, moved it into complex_repr. Modified tests to check both str and repr, which are the same for complex.

Modified:
   python/branches/py3k/Lib/test/test_complex.py
   python/branches/py3k/Objects/complexobject.c

Modified: python/branches/py3k/Lib/test/test_complex.py
==============================================================================
--- python/branches/py3k/Lib/test/test_complex.py	(original)
+++ python/branches/py3k/Lib/test/test_complex.py	Sat Dec  4 14:27:34 2010
@@ -381,29 +381,33 @@
         for num in nums:
             self.assertAlmostEqual((num.real**2 + num.imag**2)  ** 0.5, abs(num))
 
-    def test_repr(self):
-        self.assertEqual(repr(1+6j), '(1+6j)')
-        self.assertEqual(repr(1-6j), '(1-6j)')
-
-        self.assertNotEqual(repr(-(1+0j)), '(-1+-0j)')
+    def test_repr_str(self):
+        def test(v, expected, test_fn=self.assertEqual):
+            test_fn(repr(v), expected)
+            test_fn(str(v), expected)
+
+        test(1+6j, '(1+6j)')
+        test(1-6j, '(1-6j)')
+
+        test(-(1+0j), '(-1+-0j)', test_fn=self.assertNotEqual)
+
+        test(complex(1., INF), "(1+infj)")
+        test(complex(1., -INF), "(1-infj)")
+        test(complex(INF, 1), "(inf+1j)")
+        test(complex(-INF, INF), "(-inf+infj)")
+        test(complex(NAN, 1), "(nan+1j)")
+        test(complex(1, NAN), "(1+nanj)")
+        test(complex(NAN, NAN), "(nan+nanj)")
+
+        test(complex(0, INF), "infj")
+        test(complex(0, -INF), "-infj")
+        test(complex(0, NAN), "nanj")
 
         self.assertEqual(1-6j,complex(repr(1-6j)))
         self.assertEqual(1+6j,complex(repr(1+6j)))
         self.assertEqual(-6j,complex(repr(-6j)))
         self.assertEqual(6j,complex(repr(6j)))
 
-        self.assertEqual(repr(complex(1., INF)), "(1+infj)")
-        self.assertEqual(repr(complex(1., -INF)), "(1-infj)")
-        self.assertEqual(repr(complex(INF, 1)), "(inf+1j)")
-        self.assertEqual(repr(complex(-INF, INF)), "(-inf+infj)")
-        self.assertEqual(repr(complex(NAN, 1)), "(nan+1j)")
-        self.assertEqual(repr(complex(1, NAN)), "(1+nanj)")
-        self.assertEqual(repr(complex(NAN, NAN)), "(nan+nanj)")
-
-        self.assertEqual(repr(complex(0, INF)), "infj")
-        self.assertEqual(repr(complex(0, -INF)), "-infj")
-        self.assertEqual(repr(complex(0, NAN)), "nanj")
-
     def test_neg(self):
         self.assertEqual(-(1+6j), -1-6j)
 

Modified: python/branches/py3k/Objects/complexobject.c
==============================================================================
--- python/branches/py3k/Objects/complexobject.c	(original)
+++ python/branches/py3k/Objects/complexobject.c	Sat Dec  4 14:27:34 2010
@@ -324,10 +324,11 @@
     op->ob_type->tp_free(op);
 }
 
-
 static PyObject *
-complex_format(PyComplexObject *v, int precision, char format_code)
+complex_repr(PyComplexObject *v)
 {
+    int precision = 0;
+    char format_code = 'r';
     PyObject *result = NULL;
     Py_ssize_t len;
 
@@ -344,6 +345,8 @@
     char *tail = "";
 
     if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
+        /* Real part is +0: just output the imaginary part and do not
+           include parens. */
         re = "";
         im = PyOS_double_to_string(v->cval.imag, format_code,
                                    precision, 0, NULL);
@@ -352,7 +355,8 @@
             goto done;
         }
     } else {
-        /* Format imaginary part with sign, real part without */
+        /* Format imaginary part with sign, real part without. Include
+           parens in the result. */
         pre = PyOS_double_to_string(v->cval.real, format_code,
                                     precision, 0, NULL);
         if (!pre) {
@@ -371,7 +375,7 @@
         tail = ")";
     }
     /* Alloc the final buffer. Add one for the "j" in the format string,
-       and one for the trailing zero. */
+       and one for the trailing zero byte. */
     len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
     buf = PyMem_Malloc(len);
     if (!buf) {
@@ -388,12 +392,6 @@
     return result;
 }
 
-static PyObject *
-complex_repr(PyComplexObject *v)
-{
-    return complex_format(v, 0, 'r');
-}
-
 static Py_hash_t
 complex_hash(PyComplexObject *v)
 {

From python-checkins at python.org  Sat Dec  4 14:32:18 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 14:32:18 +0100 (CET)
Subject: [Python-checkins] r87040 - in python/branches/py3k/Lib/test:
	support.py test_math.py
Message-ID: <20101204133218.C34FBEE9F5@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 14:32:18 2010
New Revision: 87040

Log:
Issue #10624: Move requires_IEEE_754 into test.support. I'll fix up other uses of it shortly.

Modified:
   python/branches/py3k/Lib/test/support.py
   python/branches/py3k/Lib/test/test_math.py

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Sat Dec  4 14:32:18 2010
@@ -366,6 +366,11 @@
         return (len(x) > len(y)) - (len(x) < len(y))
     return (x > y) - (x < y)
 
+# decorator for skipping tests on non-IEEE 754 platforms
+requires_IEEE_754 = unittest.skipUnless(
+    float.__getformat__("double").startswith("IEEE"),
+    "test requires IEEE 754 doubles")
+
 is_jython = sys.platform.startswith('java')
 
 # Filename used for testing

Modified: python/branches/py3k/Lib/test/test_math.py
==============================================================================
--- python/branches/py3k/Lib/test/test_math.py	(original)
+++ python/branches/py3k/Lib/test/test_math.py	Sat Dec  4 14:32:18 2010
@@ -1,7 +1,7 @@
 # Python test set -- math module
 # XXXX Should not do tests around zero only
 
-from test.support import run_unittest, verbose
+from test.support import run_unittest, verbose, requires_IEEE_754
 import unittest
 import math
 import os
@@ -15,11 +15,6 @@
 INF = float('inf')
 NINF = float('-inf')
 
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
-
 # detect evidence of double-rounding: fsum is not always correctly
 # rounded on machines that suffer from double rounding.
 x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer

From python-checkins at python.org  Sat Dec  4 14:48:13 2010
From: python-checkins at python.org (lukasz.langa)
Date: Sat,  4 Dec 2010 14:48:13 +0100 (CET)
Subject: [Python-checkins] r87041 -
	python/branches/py3k/Lib/test/test_cfgparser.py
Message-ID: <20101204134813.AC860EEA3E@mail.python.org>

Author: lukasz.langa
Date: Sat Dec  4 14:48:13 2010
New Revision: 87041

Log:
support for checking test coverage added.
70% coverage at the moment (not tragic but needs work).



Modified:
   python/branches/py3k/Lib/test/test_cfgparser.py

Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py	(original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py	Sat Dec  4 14:48:13 2010
@@ -2,8 +2,9 @@
 import configparser
 import io
 import os
-import unittest
+import sys
 import textwrap
+import unittest
 import warnings
 
 from test import support
@@ -1084,6 +1085,17 @@
         ConfigParserTestCaseNonStandardDefaultSection,
         )
 
+def test_coverage(coverdir):
+    trace = support.import_module('trace')
+    tracer=trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
+                       count=1)
+    tracer.run('test_main()')
+    r=tracer.results()
+    print("Writing coverage results...")
+    r.write_results(show_missing=True, summary=True, coverdir=coverdir)
 
 if __name__ == "__main__":
-    test_main()
+    if "-c" in sys.argv:
+        test_coverage('/tmp/cmd.cover')
+    else:
+        test_main()

From python-checkins at python.org  Sat Dec  4 14:49:33 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat,  4 Dec 2010 14:49:33 +0100 (CET)
Subject: [Python-checkins] r87042 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101204134933.195E7EEA5F@mail.python.org>

Author: martin.v.loewis
Date: Sat Dec  4 14:49:32 2010
New Revision: 87042

Log:
Fix PEP number.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sat Dec  4 14:49:32 2010
@@ -49,7 +49,7 @@
 
 This article explains the new features in Python 3.2, compared to 3.1.
 
-PEP 382: Defining a Stable ABI
+PEP 384: Defining a Stable ABI
 ==============================
 
 In the past, extension modules built for one Python version were often

From python-checkins at python.org  Sat Dec  4 16:17:38 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 16:17:38 +0100 (CET)
Subject: [Python-checkins] r87043 - in python/branches/py3k/Lib/test:
	datetimetester.py test_cmath.py test_complex.py
	test_decimal.py test_float.py test_fractions.py test_long.py
Message-ID: <20101204151738.ADD50EE9B0@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 16:17:38 2010
New Revision: 87043

Log:
Issue #10624: Use support.requires_IEEE_754 in all appropriate tests.

Modified:
   python/branches/py3k/Lib/test/datetimetester.py
   python/branches/py3k/Lib/test/test_cmath.py
   python/branches/py3k/Lib/test/test_complex.py
   python/branches/py3k/Lib/test/test_decimal.py
   python/branches/py3k/Lib/test/test_float.py
   python/branches/py3k/Lib/test/test_fractions.py
   python/branches/py3k/Lib/test/test_long.py

Modified: python/branches/py3k/Lib/test/datetimetester.py
==============================================================================
--- python/branches/py3k/Lib/test/datetimetester.py	(original)
+++ python/branches/py3k/Lib/test/datetimetester.py	Sat Dec  4 16:17:38 2010
@@ -38,11 +38,6 @@
 INF = float("inf")
 NAN = float("nan")
 
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
-
 
 #############################################################################
 # module tests
@@ -407,7 +402,7 @@
         self.assertRaises(ZeroDivisionError, lambda: a / 0.0)
         self.assertRaises(TypeError, lambda: a / '')
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_disallowed_special(self):
         a = timedelta(42)
         self.assertRaises(ValueError, a.__mul__, NAN)
@@ -589,7 +584,7 @@
         self.assertRaises(OverflowError, day.__truediv__, 1e-10)
         self.assertRaises(OverflowError, day.__truediv__, 9e-10)
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def _test_overflow_special(self):
         day = timedelta(1)
         self.assertRaises(OverflowError, day.__mul__, INF)

Modified: python/branches/py3k/Lib/test/test_cmath.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cmath.py	(original)
+++ python/branches/py3k/Lib/test/test_cmath.py	Sat Dec  4 16:17:38 2010
@@ -1,5 +1,5 @@
-from test.support import run_unittest
-from test.test_math import parse_testfile, test_file, requires_IEEE_754
+from test.support import run_unittest, requires_IEEE_754
+from test.test_math import parse_testfile, test_file
 import unittest
 import cmath, math
 from cmath import phase, polar, rect, pi
@@ -312,10 +312,8 @@
                 self.rAssertAlmostEqual(math.log(v, base), z.real)
                 self.assertEqual(0., z.imag)
 
+    @requires_IEEE_754
     def test_specific_values(self):
-        if not float.__getformat__("double").startswith("IEEE"):
-            return
-
         def rect_complex(z):
             """Wrapped version of rect that accepts a complex number instead of
             two float arguments."""
@@ -460,9 +458,11 @@
         self.assertEqual(abs(complex(INF, NAN)), INF)
         self.assertTrue(math.isnan(abs(complex(NAN, NAN))))
 
+
+    @requires_IEEE_754
+    def test_abs_overflows(self):
         # result overflows
-        if float.__getformat__("double").startswith("IEEE"):
-            self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
+        self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
 
     def assertCEqual(self, a, b):
         eps = 1E-7

Modified: python/branches/py3k/Lib/test/test_complex.py
==============================================================================
--- python/branches/py3k/Lib/test/test_complex.py	(original)
+++ python/branches/py3k/Lib/test/test_complex.py	Sat Dec  4 16:17:38 2010
@@ -435,15 +435,14 @@
         self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
         self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
 
-    if float.__getformat__("double").startswith("IEEE"):
-        def test_plus_minus_0j(self):
-            # test that -0j and 0j literals are not identified
-            z1, z2 = 0j, -0j
-            self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.))
-            self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.))
+    @support.requires_IEEE_754
+    def test_plus_minus_0j(self):
+        # test that -0j and 0j literals are not identified
+        z1, z2 = 0j, -0j
+        self.assertEqual(atan2(z1.imag, -1.), atan2(0., -1.))
+        self.assertEqual(atan2(z2.imag, -1.), atan2(-0., -1.))
 
-    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
-                         "test requires IEEE 754 doubles")
+    @support.requires_IEEE_754
     def test_negated_imaginary_literal(self):
         z0 = -0j
         z1 = -7j
@@ -459,15 +458,13 @@
         self.assertFloatsAreIdentical(z2.real, -0.0)
         self.assertFloatsAreIdentical(z2.imag, -INF)
 
-    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
-                         "test requires IEEE 754 doubles")
+    @support.requires_IEEE_754
     def test_overflow(self):
         self.assertEqual(complex("1e500"), complex(INF, 0.0))
         self.assertEqual(complex("-1e500j"), complex(0.0, -INF))
         self.assertEqual(complex("-1e500+1.8e308j"), complex(-INF, INF))
 
-    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
-                         "test requires IEEE 754 doubles")
+    @support.requires_IEEE_754
     def test_repr_roundtrip(self):
         vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN]
         vals += [-v for v in vals]

Modified: python/branches/py3k/Lib/test/test_decimal.py
==============================================================================
--- python/branches/py3k/Lib/test/test_decimal.py	(original)
+++ python/branches/py3k/Lib/test/test_decimal.py	Sat Dec  4 16:17:38 2010
@@ -32,7 +32,8 @@
 import unittest
 from decimal import *
 import numbers
-from test.support import run_unittest, run_doctest, is_resource_enabled
+from test.support import (run_unittest, run_doctest, is_resource_enabled,
+                          requires_IEEE_754)
 from test.support import check_warnings
 import random
 try:
@@ -61,11 +62,6 @@
         )
     setcontext(DefaultTestContext)
 
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
-
 TESTDATADIR = 'decimaltestdata'
 if __name__ == '__main__':
     file = sys.argv[0]

Modified: python/branches/py3k/Lib/test/test_float.py
==============================================================================
--- python/branches/py3k/Lib/test/test_float.py	(original)
+++ python/branches/py3k/Lib/test/test_float.py	Sat Dec  4 16:17:38 2010
@@ -16,10 +16,6 @@
                                          "requires __getformat__")
 requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"),
                                          "requires __setformat__")
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(have_getformat and
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
 
 #locate file with float format test values
 test_dir = os.path.dirname(__file__) or os.curdir
@@ -196,7 +192,7 @@
         # distingishes -0.0 and 0.0.
         self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_float_mod(self):
         # Check behaviour of % operator for IEEE 754 special cases.
         # In particular, check signs of zeros.
@@ -216,7 +212,7 @@
         self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
         self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_float_pow(self):
         # test builtin pow and ** operator for IEEE 754 special cases.
         # Special cases taken from section F.9.4.4 of the C99 specification
@@ -503,7 +499,7 @@
 
 class IEEEFormatTestCase(unittest.TestCase):
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_double_specials_do_unpack(self):
         for fmt, data in [('>d', BE_DOUBLE_INF),
                           ('>d', BE_DOUBLE_NAN),
@@ -511,7 +507,7 @@
                           ('f', BE_FLOAT_INF),
                           ('>f', BE_FLOAT_NAN),
@@ -574,7 +570,7 @@
         self.assertEqual(format(INF, 'f'), 'inf')
         self.assertEqual(format(INF, 'F'), 'INF')
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_format_testfile(self):
         with open(format_testfile) as testfile:
             for line in testfile:
@@ -658,7 +654,7 @@
             self.assertEqual(repr(float(s)), str(float(s)))
             self.assertEqual(repr(float(negs)), str(float(negs)))
 
- at requires_IEEE_754
+ at support.requires_IEEE_754
 class RoundTestCase(unittest.TestCase):
 
     def test_inf_nan(self):

Modified: python/branches/py3k/Lib/test/test_fractions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_fractions.py	(original)
+++ python/branches/py3k/Lib/test/test_fractions.py	Sat Dec  4 16:17:38 2010
@@ -1,7 +1,7 @@
 """Tests for Lib/fractions.py."""
 
 from decimal import Decimal
-from test.support import run_unittest
+from test.support import run_unittest, requires_IEEE_754
 import math
 import numbers
 import operator
@@ -12,11 +12,6 @@
 F = fractions.Fraction
 gcd = fractions.gcd
 
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
-
 class DummyFloat(object):
     """Dummy float class for testing comparisons with Fractions"""
 

Modified: python/branches/py3k/Lib/test/test_long.py
==============================================================================
--- python/branches/py3k/Lib/test/test_long.py	(original)
+++ python/branches/py3k/Lib/test/test_long.py	Sat Dec  4 16:17:38 2010
@@ -1,5 +1,6 @@
 import unittest
 from test import support
+
 import sys
 
 import random
@@ -15,11 +16,6 @@
     def __str__(self):
         return self.format % self.args
 
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
-    float.__getformat__("double").startswith("IEEE"),
-    "test requires IEEE 754 doubles")
-
 # SHIFT should match the value in longintrepr.h for best testing.
 SHIFT = sys.int_info.bits_per_digit
 BASE = 2 ** SHIFT
@@ -371,8 +367,7 @@
                 return 1729
         self.assertEqual(int(LongTrunc()), 1729)
 
-    @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
-                         "test requires IEEE 754 doubles")
+    @support.requires_IEEE_754
     def test_float_conversion(self):
 
         exact_values = [0, 1, 2,
@@ -703,7 +698,7 @@
         self.assertEqual(expected, got, "Incorrectly rounded division {}/{}: "
                          "expected {}, got {}".format(a, b, expected, got))
 
-    @requires_IEEE_754
+    @support.requires_IEEE_754
     def test_correctly_rounded_true_division(self):
         # more stringent tests than those above, checking that the
         # result of true division of ints is always correctly rounded.

From python-checkins at python.org  Sat Dec  4 16:26:14 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 16:26:14 +0100 (CET)
Subject: [Python-checkins] r87044 -
	python/branches/py3k/Lib/test/test_complex.py
Message-ID: <20101204152614.07BB7EE9B0@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 16:26:13 2010
New Revision: 87044

Log:
Issue 10625: Add tests for negative zeros in complex str and repr.

Modified:
   python/branches/py3k/Lib/test/test_complex.py

Modified: python/branches/py3k/Lib/test/test_complex.py
==============================================================================
--- python/branches/py3k/Lib/test/test_complex.py	(original)
+++ python/branches/py3k/Lib/test/test_complex.py	Sat Dec  4 16:26:13 2010
@@ -408,6 +408,22 @@
         self.assertEqual(-6j,complex(repr(-6j)))
         self.assertEqual(6j,complex(repr(6j)))
 
+    @support.requires_IEEE_754
+    def test_negative_zero_repr_str(self):
+        def test(v, expected, test_fn=self.assertEqual):
+            test_fn(repr(v), expected)
+            test_fn(str(v), expected)
+
+        test(complex(0., 1.),   "1j")
+        test(complex(-0., 1.),  "(-0+1j)")
+        test(complex(0., -1.),  "-1j")
+        test(complex(-0., -1.), "(-0-1j)")
+
+        test(complex(0., 0.),   "0j")
+        test(complex(0., -0.),  "-0j")
+        test(complex(-0., 0.),  "(-0+0j)")
+        test(complex(-0., -0.), "(-0-0j)")
+
     def test_neg(self):
         self.assertEqual(-(1+6j), -1-6j)
 

From python-checkins at python.org  Sat Dec  4 17:00:47 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 17:00:47 +0100 (CET)
Subject: [Python-checkins] r87045 - in python/branches/py3k:
	Doc/library/pdb.rst Lib/bdb.py Lib/pdb.py Misc/NEWS
Message-ID: <20101204160047.AB862EE9E1@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 17:00:47 2010
New Revision: 87045

Log:
#7245: Add a SIGINT handler on continue in pdb that allows to break a program again by pressing Ctrl-C.

Modified:
   python/branches/py3k/Doc/library/pdb.rst
   python/branches/py3k/Lib/bdb.py
   python/branches/py3k/Lib/pdb.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/pdb.rst
==============================================================================
--- python/branches/py3k/Doc/library/pdb.rst	(original)
+++ python/branches/py3k/Doc/library/pdb.rst	Sat Dec  4 17:00:47 2010
@@ -135,7 +135,8 @@
 :class:`Pdb` class and calling the method of the same name.  If you want to
 access further features, you have to do this yourself:
 
-.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None)
+.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \
+               nosigint=False)
 
    :class:`Pdb` is the debugger class.
 
@@ -146,6 +147,11 @@
    patterns.  The debugger will not step into frames that originate in a module
    that matches one of these patterns. [1]_
 
+   By default, Pdb sets a handler for the SIGINT signal (which is sent when the
+   user presses Ctrl-C on the console) when you give a ``continue`` command.
+   This allows you to break into the debugger again by pressing Ctrl-C.  If you
+   want Pdb not to touch the SIGINT handler, set *nosigint* tot true.
+
    Example call to enable tracing with *skip*::
 
       import pdb; pdb.Pdb(skip=['django.*']).set_trace()
@@ -153,6 +159,10 @@
    .. versionadded:: 3.1
       The *skip* argument.
 
+   .. versionadded:: 3.2
+      The *nosigint* argument.  Previously, a SIGINT handler was never set by
+      Pdb.
+
    .. method:: run(statement, globals=None, locals=None)
                runeval(expression, globals=None, locals=None)
                runcall(function, *args, **kwds)

Modified: python/branches/py3k/Lib/bdb.py
==============================================================================
--- python/branches/py3k/Lib/bdb.py	(original)
+++ python/branches/py3k/Lib/bdb.py	Sat Dec  4 17:00:47 2010
@@ -214,7 +214,7 @@
     def set_continue(self):
         # Don't stop except at breakpoints or when finished
         self._set_stopinfo(self.botframe, None, -1)
-        if not self.breaks:
+        if not self.breaks and not self.watching:
             # no breakpoints; run without debugger overhead
             sys.settrace(None)
             frame = sys._getframe().f_back

Modified: python/branches/py3k/Lib/pdb.py
==============================================================================
--- python/branches/py3k/Lib/pdb.py	(original)
+++ python/branches/py3k/Lib/pdb.py	Sat Dec  4 17:00:47 2010
@@ -66,14 +66,15 @@
 # NOTE: the actual command documentation is collected from docstrings of the
 # commands and is appended to __doc__ after the class has been defined.
 
+import os
+import re
 import sys
 import cmd
 import bdb
 import dis
-import os
-import re
 import code
 import pprint
+import signal
 import inspect
 import traceback
 import linecache
@@ -133,7 +134,8 @@
 
 class Pdb(bdb.Bdb, cmd.Cmd):
 
-    def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None):
+    def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
+                 nosigint=False):
         bdb.Bdb.__init__(self, skip=skip)
         cmd.Cmd.__init__(self, completekey, stdin, stdout)
         if stdout:
@@ -148,6 +150,8 @@
             import readline
         except ImportError:
             pass
+        self.allow_kbdint = False
+        self.nosigint = nosigint
 
         # Read $HOME/.pdbrc and ./.pdbrc
         self.rcLines = []
@@ -174,6 +178,15 @@
         self.commands_bnum = None # The breakpoint number for which we are
                                   # defining a list
 
+    def sigint_handler(self, signum, frame):
+        if self.allow_kbdint:
+            raise KeyboardInterrupt
+        self.message("\nProgram interrupted. (Use 'cont' to resume).")
+        self.set_step()
+        self.set_trace(frame)
+        # restore previous signal handler
+        signal.signal(signal.SIGINT, self._previous_sigint_handler)
+
     def reset(self):
         bdb.Bdb.reset(self)
         self.forget()
@@ -261,7 +274,7 @@
             if not self.commands_silent[currentbp]:
                 self.print_stack_entry(self.stack[self.curindex])
             if self.commands_doprompt[currentbp]:
-                self.cmdloop()
+                self._cmdloop()
             self.forget()
             return
         return 1
@@ -286,6 +299,17 @@
         self.interaction(frame, exc_traceback)
 
     # General interaction function
+    def _cmdloop(self):
+        while True:
+            try:
+                # keyboard interrupts allow for an easy way to cancel
+                # the current command, so allow them during interactive input
+                self.allow_kbdint = True
+                self.cmdloop()
+                self.allow_kbdint = False
+                break
+            except KeyboardInterrupt:
+                self.message('--KeyboardInterrupt--')
 
     def interaction(self, frame, traceback):
         if self.setup(frame, traceback):
@@ -294,7 +318,7 @@
             self.forget()
             return
         self.print_stack_entry(self.stack[self.curindex])
-        self.cmdloop()
+        self._cmdloop()
         self.forget()
 
     def displayhook(self, obj):
@@ -909,6 +933,9 @@
         """c(ont(inue))
         Continue execution, only stop when a breakpoint is encountered.
         """
+        if not self.nosigint:
+            self._previous_sigint_handler = \
+                signal.signal(signal.SIGINT, self.sigint_handler)
         self.set_continue()
         return 1
     do_c = do_cont = do_continue

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 17:00:47 2010
@@ -49,6 +49,9 @@
 Library
 -------
 
+- Issue #7245: Add a SIGINT handler in pdb that allows to break a program
+  again after a "continue" command.
+
 - Add the "interact" pdb command.
 
 - Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf.

From python-checkins at python.org  Sat Dec  4 17:09:22 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 17:09:22 +0100 (CET)
Subject: [Python-checkins] r87046 - python/branches/release31-maint
Message-ID: <20101204160922.6325EEE99B@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 17:09:22 2010
New Revision: 87046

Log:
Blocked revisions 87039-87040,87043-87044 via svnmerge

........
  r87039 | eric.smith | 2010-12-04 08:27:34 -0500 (Sat, 04 Dec 2010) | 1 line
  
  Removed static function complex_format, moved it into complex_repr. Modified tests to check both str and repr, which are the same for complex.
........
  r87040 | eric.smith | 2010-12-04 08:32:18 -0500 (Sat, 04 Dec 2010) | 1 line
  
  Issue #10624: Move requires_IEEE_754 into test.support. I'll fix up other uses of it shortly.
........
  r87043 | eric.smith | 2010-12-04 10:17:38 -0500 (Sat, 04 Dec 2010) | 1 line
  
  Issue #10624: Use support.requires_IEEE_754 in all appropriate tests.
........
  r87044 | eric.smith | 2010-12-04 10:26:13 -0500 (Sat, 04 Dec 2010) | 1 line
  
  Issue 10625: Add tests for negative zeros in complex str and repr.
........


Modified:
   python/branches/release31-maint/   (props changed)

From python-checkins at python.org  Sat Dec  4 17:21:42 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 17:21:42 +0100 (CET)
Subject: [Python-checkins] r87047 - in python/branches/py3k:
	Doc/library/pdb.rst Lib/pdb.py Misc/NEWS
Message-ID: <20101204162142.D1CA1EE99B@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 17:21:42 2010
New Revision: 87047

Log:
Add display/undisplay pdb commands.

Modified:
   python/branches/py3k/Doc/library/pdb.rst
   python/branches/py3k/Lib/pdb.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/pdb.rst
==============================================================================
--- python/branches/py3k/Doc/library/pdb.rst	(original)
+++ python/branches/py3k/Doc/library/pdb.rst	Sat Dec  4 17:21:42 2010
@@ -417,6 +417,22 @@
 
    .. versionadded:: 3.2
 
+.. pdbcommand:: display [expression]
+
+   Display the value of the expression if it changed, each time execution stops
+   in the current frame.
+
+   Without expression, list all display expressions for the current frame.
+
+   .. versionadded:: 3.2
+
+.. pdbcommand:: undisplay [expression]
+
+   Do not display the expression any more in the current frame.  Without
+   expression, clear all display expressions for the current frame.
+
+   .. versionadded:: 3.2
+
 .. pdbcommand:: interact
 
    Start an interative interpreter (using the :mod:`code` module) whose global

Modified: python/branches/py3k/Lib/pdb.py
==============================================================================
--- python/branches/py3k/Lib/pdb.py	(original)
+++ python/branches/py3k/Lib/pdb.py	Sat Dec  4 17:21:42 2010
@@ -125,6 +125,12 @@
     return 0
 
 
+class _rstr(str):
+    """String that doesn't quote its repr."""
+    def __repr__(self):
+        return self
+
+
 # Interaction prompt line will separate file and call info from code
 # text using value of line_prefix string.  A newline and arrow may
 # be to your liking.  You can set it once pdb is imported using the
@@ -142,6 +148,7 @@
             self.use_rawinput = 0
         self.prompt = '(Pdb) '
         self.aliases = {}
+        self.displaying = {}
         self.mainpyfile = ''
         self._wait_for_mainpyfile = False
         self.tb_lineno = {}
@@ -311,6 +318,20 @@
             except KeyboardInterrupt:
                 self.message('--KeyboardInterrupt--')
 
+    # Called before loop, handles display expressions
+    def preloop(self):
+        displaying = self.displaying.get(self.curframe)
+        if displaying:
+            for expr, oldvalue in displaying.items():
+                newvalue = self._getval_except(expr)
+                # check for identity first; this prevents custom __eq__ to
+                # be called at every loop, and also prevents instances whose
+                # fields are changed to be displayed
+                if newvalue is not oldvalue and newvalue != oldvalue:
+                    displaying[expr] = newvalue
+                    self.message('display %s: %r  [old: %r]' %
+                                 (expr, newvalue, oldvalue))
+
     def interaction(self, frame, traceback):
         if self.setup(frame, traceback):
             # no interaction desired at this time (happens if .pdbrc contains
@@ -1041,6 +1062,17 @@
             self.error(traceback.format_exception_only(*exc_info)[-1].strip())
             raise
 
+    def _getval_except(self, arg, frame=None):
+        try:
+            if frame is None:
+                return eval(arg, self.curframe.f_globals, self.curframe_locals)
+            else:
+                return eval(arg, frame.f_globals, frame.f_locals)
+        except:
+            exc_info = sys.exc_info()[:2]
+            err = traceback.format_exception_only(*exc_info)[-1].strip()
+            return _rstr('** raised %s **' % err)
+
     def do_p(self, arg):
         """p(rint) expression
         Print the value of the expression.
@@ -1195,6 +1227,38 @@
         # None of the above...
         self.message(type(value))
 
+    def do_display(self, arg):
+        """display [expression]
+
+        Display the value of the expression if it changed, each time execution
+        stops in the current frame.
+
+        Without expression, list all display expressions for the current frame.
+        """
+        if not arg:
+            self.message('Currently displaying:')
+            for item in self.displaying.get(self.curframe, {}).items():
+                self.message('%s: %r' % item)
+        else:
+            val = self._getval_except(arg)
+            self.displaying.setdefault(self.curframe, {})[arg] = val
+            self.message('display %s: %r' % (arg, val))
+
+    def do_undisplay(self, arg):
+        """undisplay [expression]
+
+        Do not display the expression any more in the current frame.
+
+        Without expression, clear all display expressions for the current frame.
+        """
+        if arg:
+            try:
+                del self.displaying.get(self.curframe, {})[arg]
+            except KeyError:
+                self.error('not displaying %s' % arg)
+        else:
+            self.displaying.pop(self.curframe, None)
+
     def do_interact(self, arg):
         """interact
 
@@ -1380,8 +1444,8 @@
         'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable',
         'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until',
         'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist',
-        'args', 'print', 'pp', 'whatis', 'source', 'interact', 'alias',
-        'unalias', 'debug', 'quit',
+        'args', 'print', 'pp', 'whatis', 'source', 'display', 'undisplay',
+        'interact', 'alias', 'unalias', 'debug', 'quit',
     ]
 
     for _command in _help_order:

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 17:21:42 2010
@@ -49,6 +49,8 @@
 Library
 -------
 
+- Add the "display" and "undisplay" pdb commands.
+
 - Issue #7245: Add a SIGINT handler in pdb that allows to break a program
   again after a "continue" command.
 

From python-checkins at python.org  Sat Dec  4 17:22:45 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 17:22:45 +0100 (CET)
Subject: [Python-checkins] r87048 - python/branches/py3k/Lib/bdb.py
Message-ID: <20101204162245.0F789EE986@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 17:22:44 2010
New Revision: 87048

Log:
Fix accidental checkin.

Modified:
   python/branches/py3k/Lib/bdb.py

Modified: python/branches/py3k/Lib/bdb.py
==============================================================================
--- python/branches/py3k/Lib/bdb.py	(original)
+++ python/branches/py3k/Lib/bdb.py	Sat Dec  4 17:22:44 2010
@@ -214,7 +214,7 @@
     def set_continue(self):
         # Don't stop except at breakpoints or when finished
         self._set_stopinfo(self.botframe, None, -1)
-        if not self.breaks and not self.watching:
+        if not self.breaks:
             # no breakpoints; run without debugger overhead
             sys.settrace(None)
             frame = sys._getframe().f_back

From python-checkins at python.org  Sat Dec  4 17:42:07 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat,  4 Dec 2010 17:42:07 +0100 (CET)
Subject: [Python-checkins] r87049 - peps/trunk/pep-0384.txt
Message-ID: <20101204164207.C2F4BEE9D1@mail.python.org>

Author: martin.v.loewis
Date: Sat Dec  4 17:42:07 2010
New Revision: 87049

Log:
Add structseq support.
Incorporate 3149 support.
Mark as final.


Modified:
   peps/trunk/pep-0384.txt

Modified: peps/trunk/pep-0384.txt
==============================================================================
--- peps/trunk/pep-0384.txt	(original)
+++ peps/trunk/pep-0384.txt	Sat Dec  4 17:42:07 2010
@@ -3,7 +3,7 @@
 Version: $Revision$
 Last-Modified: $Date$
 Author: Martin v. L?wis 
-Status: Draft
+Status: Final
 Type: Standards Track
 Content-Type: text/x-rst
 Created: 17-May-2009
@@ -107,6 +107,8 @@
 - PyModuleDefBase (ob_base, m_init, m_index, m_copy)
 - PyModuleDef (m_base, m_name, m_doc, m_size, m_methods, m_traverse,
   m_clear, m_free)
+- PyStructSequence_Field (name, doc)
+- PyStructSequence_Desc (name, doc, fields, sequence)
 - PyType_Slot (see below)
 - PyType_Spec (see below)
 
@@ -280,6 +282,9 @@
   PyInterpreterState_ThreadHead, PyThreadState_Next
 - Py_SubversionRevision, Py_SubversionShortBranch
 
+PyStructSequence_InitType is not available, as it requires
+the caller to provide a static type object.
+
 Py_FatalError will be moved from pydebug.h into some other
 header file (e.g. pyerrors.h).
 
@@ -332,6 +337,13 @@
 PYTHON_API_VERSION as conforming. If Python is compiled as a shared
 library, it is installed as both libpython3.so, and libpython3.y.so;
 applications conforming to this PEP should then link to the former.
+The ABI version is symbolically available as ``PYTHON_ABI_VERSION``.
+
+Also on Unix, the PEP 3149 tag abi is accepted
+in file names of extension modules. No checking is performed that
+files named in this way are actually restricted to the limited API,
+and no support for building such files will be added to distutils
+due to the distutils code freeze.
 
 Implementation Strategy
 =======================

From python-checkins at python.org  Sat Dec  4 18:09:30 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 18:09:30 +0100 (CET)
Subject: [Python-checkins] r87050 -
	python/branches/py3k/Objects/bytearrayobject.c
Message-ID: <20101204170930.605E5EE9F5@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 18:09:30 2010
New Revision: 87050

Log:
Fix typo.

Modified:
   python/branches/py3k/Objects/bytearrayobject.c

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c	(original)
+++ python/branches/py3k/Objects/bytearrayobject.c	Sat Dec  4 18:09:30 2010
@@ -589,7 +589,7 @@
         needed = 0;
     }
     else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
-        /* Make a copy an call this function recursively */
+        /* Make a copy and call this function recursively */
         int err;
         values = PyByteArray_FromObject(values);
         if (values == NULL)

From python-checkins at python.org  Sat Dec  4 18:11:36 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 18:11:36 +0100 (CET)
Subject: [Python-checkins] r87051 - in python/branches/py3k/Lib: doctest.py
	test/test_pdb.py test/test_zipimport_support.py
Message-ID: <20101204171136.A0C73EE9DD@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 18:11:36 2010
New Revision: 87051

Log:
Fix test suite to not activate new sigint behavior in pdb.

Modified:
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/test/test_pdb.py
   python/branches/py3k/Lib/test/test_zipimport_support.py

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Sat Dec  4 18:11:36 2010
@@ -318,7 +318,8 @@
     def __init__(self, out):
         self.__out = out
         self.__debugger_used = False
-        pdb.Pdb.__init__(self, stdout=out)
+        # do not play signal games in the pdb
+        pdb.Pdb.__init__(self, stdout=out, nosigint=True)
         # still use input() to get user input
         self.use_rawinput = 1
 
@@ -2528,14 +2529,16 @@
                     exec(f.read(), globs, globs)
             except:
                 print(sys.exc_info()[1])
-                pdb.post_mortem(sys.exc_info()[2])
+                p = pdb.Pdb(nosigint=True)
+                p.reset()
+                p.interaction(None, sys.exc_info()[2])
         else:
             fp = open(srcfilename)
             try:
                 script = fp.read()
             finally:
                 fp.close()
-            pdb.run("exec(%r)" % script, globs, globs)
+            pdb.Pdb(nosigint=True).run("exec(%r)" % script, globs, globs)
 
     finally:
         os.remove(srcfilename)

Modified: python/branches/py3k/Lib/test/test_pdb.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pdb.py	(original)
+++ python/branches/py3k/Lib/test/test_pdb.py	Sat Dec  4 18:11:36 2010
@@ -29,7 +29,7 @@
     """This tests the custom displayhook for pdb.
 
     >>> def test_function(foo, bar):
-    ...     import pdb; pdb.Pdb().set_trace()
+    ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
     ...     pass
 
     >>> with PdbTestInput([
@@ -69,7 +69,7 @@
     ...     return foo.upper()
 
     >>> def test_function():
-    ...     import pdb; pdb.Pdb().set_trace()
+    ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
     ...     ret = test_function_2('baz')
     ...     print(ret)
 
@@ -168,7 +168,7 @@
     """Test basic commands related to breakpoints.
 
     >>> def test_function():
-    ...     import pdb; pdb.Pdb().set_trace()
+    ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
     ...     print(1)
     ...     print(2)
     ...     print(3)
@@ -297,7 +297,7 @@
     ...     return foo
 
     >>> def test_function():
-    ...     import pdb; pdb.Pdb().set_trace()
+    ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
     ...     ret = test_function_2('baz')
 
     >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
@@ -320,7 +320,7 @@
     -> ret = test_function_2('baz')
     (Pdb) list
       1         def test_function():
-      2             import pdb; pdb.Pdb().set_trace()
+      2             import pdb; pdb.Pdb(nosigint=True).set_trace()
       3  ->         ret = test_function_2('baz')
     [EOF]
     (Pdb) step
@@ -383,7 +383,7 @@
     ...         print('Exception!')
 
     >>> def test_function():
-    ...     import pdb; pdb.Pdb().set_trace()
+    ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
     ...     test_function_2()
     ...     print('Not reached.')
 
@@ -416,7 +416,7 @@
     -> 1/0
     (Pdb) list
       1         def test_function():
-      2             import pdb; pdb.Pdb().set_trace()
+      2             import pdb; pdb.Pdb(nosigint=True).set_trace()
       3  ->         test_function_2()
       4             print('Not reached.')
     [EOF]
@@ -440,7 +440,7 @@
 
     >>> def skip_module():
     ...     import string
-    ...     import pdb; pdb.Pdb(skip=['stri*']).set_trace()
+    ...     import pdb; pdb.Pdb(skip=['stri*'], nosigint=True).set_trace()
     ...     string.capwords('FOO')
 
     >>> with PdbTestInput([
@@ -469,7 +469,7 @@
     >>> def skip_module():
     ...     def callback():
     ...         return None
-    ...     import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
+    ...     import pdb; pdb.Pdb(skip=['module_to_skip*'], nosigint=True).set_trace()
     ...     mod.foo_pony(callback)
 
     >>> with PdbTestInput([
@@ -510,7 +510,7 @@
     """Test that "continue" and "next" work properly in bottom frame (issue #5294).
 
     >>> def test_function():
-    ...     import pdb, sys; inst = pdb.Pdb()
+    ...     import pdb, sys; inst = pdb.Pdb(nosigint=True)
     ...     inst.set_trace()
     ...     inst.botframe = sys._getframe()  # hackery to get the right botframe
     ...     print(1)
@@ -550,7 +550,8 @@
 
 def pdb_invoke(method, arg):
     """Run pdb.method(arg)."""
-    import pdb; getattr(pdb, method)(arg)
+    import pdb
+    getattr(pdb.Pdb(nosigint=True), method)(arg)
 
 
 def test_pdb_run_with_incorrect_argument():

Modified: python/branches/py3k/Lib/test/test_zipimport_support.py
==============================================================================
--- python/branches/py3k/Lib/test/test_zipimport_support.py	(original)
+++ python/branches/py3k/Lib/test/test_zipimport_support.py	Sat Dec  4 18:11:36 2010
@@ -200,7 +200,7 @@
                         pass
 
                     import pdb
-                    pdb.runcall(f)
+                    pdb.Pdb(nosigint=True).runcall(f)
                     """)
         with temp_dir() as d:
             script_name = make_script(d, 'script', test_src)

From python-checkins at python.org  Sat Dec  4 18:12:41 2010
From: python-checkins at python.org (eric.smith)
Date: Sat,  4 Dec 2010 18:12:41 +0100 (CET)
Subject: [Python-checkins] r87052 - python/branches/py3k/Lib/test/support.py
Message-ID: <20101204171241.B922EEE9E2@mail.python.org>

Author: eric.smith
Date: Sat Dec  4 18:12:41 2010
New Revision: 87052

Log:
More issue #10624: Add requires_IEEE_754 to __all__.

Modified:
   python/branches/py3k/Lib/test/support.py

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Sat Dec  4 18:12:41 2010
@@ -42,7 +42,7 @@
     "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
     "run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
     "reap_children", "cpython_only", "check_impl_detail", "get_attribute",
-    "swap_item", "swap_attr"]
+    "swap_item", "swap_attr", "requires_IEEE_754"]
 
 
 class Error(Exception):

From python-checkins at python.org  Sat Dec  4 18:15:21 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat,  4 Dec 2010 18:15:21 +0100 (CET)
Subject: [Python-checkins] r87053 - in python/branches/release31-maint:
	Lib/test/regrtest.py Misc/ACKS Misc/NEWS
Message-ID: <20101204171521.8CB90F16A@mail.python.org>

Author: r.david.murray
Date: Sat Dec  4 18:15:21 2010
New Revision: 87053

Log:
Merged revisions 85086 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85086 | r.david.murray | 2010-09-28 21:08:05 -0400 (Tue, 28 Sep 2010) | 4 lines
  
  #7110: have regrtest print test failures and tracebacks to stderr not stdout.
  
  Patch by Sandro Tosi.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/regrtest.py
   python/branches/release31-maint/Misc/ACKS
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/test/regrtest.py
==============================================================================
--- python/branches/release31-maint/Lib/test/regrtest.py	(original)
+++ python/branches/release31-maint/Lib/test/regrtest.py	Sat Dec  4 18:15:21 2010
@@ -659,16 +659,16 @@
     except KeyboardInterrupt:
         raise
     except support.TestFailed as msg:
-        print("test", test, "failed --", msg)
-        sys.stdout.flush()
+        print("test", test, "failed --", msg, file=sys.stderr)
+        sys.stderr.flush()
         return 0
     except:
         type, value = sys.exc_info()[:2]
-        print("test", test, "crashed --", str(type) + ":", value)
-        sys.stdout.flush()
+        print("test", test, "crashed --", str(type) + ":", value, file=sys.stderr)
+        sys.stderr.flush()
         if verbose or debug:
-            traceback.print_exc(file=sys.stdout)
-            sys.stdout.flush()
+            traceback.print_exc(file=sys.stderr)
+            sys.stderr.flush()
         return 0
     else:
         if refleak:

Modified: python/branches/release31-maint/Misc/ACKS
==============================================================================
--- python/branches/release31-maint/Misc/ACKS	(original)
+++ python/branches/release31-maint/Misc/ACKS	Sat Dec  4 18:15:21 2010
@@ -784,6 +784,7 @@
 Frank J. Tobin
 R Lindsay Todd
 Bennett Todd
+Sandro Tosi
 Richard Townsend
 Laurence Tratt
 John Tromp

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sat Dec  4 18:15:21 2010
@@ -27,6 +27,12 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+Tests
+-----
+
+- Issue #7110: regrtest now sends test failure reports and single-failure
+  tracebacks to stderr rather than stdout.
+
 
 What's New in Python 3.1.3?
 ===========================

From python-checkins at python.org  Sat Dec  4 18:24:34 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat,  4 Dec 2010 18:24:34 +0100 (CET)
Subject: [Python-checkins] r87054 - in python/branches/py3k:
	Doc/library/sys.rst Lib/test/test_cmd_line.py Misc/NEWS
	Python/sysmodule.c
Message-ID: <20101204172434.3C90CEE986@mail.python.org>

Author: victor.stinner
Date: Sat Dec  4 18:24:33 2010
New Revision: 87054

Log:
Issue #10601: sys.displayhook uses 'backslashreplace' error handler on
UnicodeEncodeError.


Modified:
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Lib/test/test_cmd_line.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Sat Dec  4 18:24:33 2010
@@ -99,13 +99,39 @@
 
 .. function:: displayhook(value)
 
-   If *value* is not ``None``, this function prints it to ``sys.stdout``, and saves
-   it in ``builtins._``.
+   If *value* is not ``None``, this function prints ``repr(value)`` to
+   ``sys.stdout``, and saves *value* in ``builtins._``. If ``repr(value)`` is
+   not encodable to ``sys.stdout.encoding`` with ``sys.stdout.errors`` error
+   handler (which is probably ``'strict'``), encode it to
+   ``sys.stdout.encoding`` with ``'backslashreplace'`` error handler.
 
    ``sys.displayhook`` is called on the result of evaluating an :term:`expression`
    entered in an interactive Python session.  The display of these values can be
    customized by assigning another one-argument function to ``sys.displayhook``.
 
+   Pseudo-code::
+
+       def displayhook(value):
+           if value is None:
+               return
+           # Set '_' to None to avoid recursion
+           builtins._ = None
+           text = repr(value)
+           try:
+               sys.stdout.write(text)
+           except UnicodeEncodeError:
+               bytes = text.encode(sys.stdout.encoding, 'backslashreplace')
+               if hasattr(sys.stdout, 'buffer'):
+                   sys.stdout.buffer.write(bytes)
+               else:
+                   text = bytes.decode(sys.stdout.encoding, 'strict')
+                   sys.stdout.write(text)
+           sys.stdout.write("\n")
+           builtins._ = value
+
+   .. versionchanged:: 3.2
+      Use ``'backslashreplace'`` error handler on :exc:`UnicodeEncodeError`.
+
 
 .. function:: excepthook(type, value, traceback)
 

Modified: python/branches/py3k/Lib/test/test_cmd_line.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cmd_line.py	(original)
+++ python/branches/py3k/Lib/test/test_cmd_line.py	Sat Dec  4 18:24:33 2010
@@ -221,6 +221,24 @@
         self.assertIn(path1.encode('ascii'), out)
         self.assertIn(path2.encode('ascii'), out)
 
+    def test_displayhook_unencodable(self):
+        for encoding in ('ascii', 'latin1', 'utf8'):
+            env = os.environ.copy()
+            env['PYTHONIOENCODING'] = encoding
+            p = subprocess.Popen(
+                [sys.executable, '-i'],
+                stdin=subprocess.PIPE,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                env=env)
+            # non-ascii, surrogate, non-BMP printable, non-BMP unprintable
+            text = "a=\xe9 b=\uDC80 c=\U00010000 d=\U0010FFFF"
+            p.stdin.write(ascii(text).encode('ascii') + b"\n")
+            p.stdin.write(b'exit()\n')
+            data = kill_python(p)
+            escaped = repr(text).encode(encoding, 'backslashreplace')
+            self.assertIn(escaped, data)
+
 
 def test_main():
     test.support.run_unittest(CmdLineTest)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 18:24:33 2010
@@ -49,6 +49,9 @@
 Library
 -------
 
+- Issue #10601: sys.displayhook uses 'backslashreplace' error handler on
+  UnicodeEncodeError.
+
 - Add the "display" and "undisplay" pdb commands.
 
 - Issue #7245: Add a SIGINT handler in pdb that allows to break a program

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Sat Dec  4 18:24:33 2010
@@ -65,6 +65,68 @@
         return PyDict_SetItemString(sd, name, v);
 }
 
+/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace'
+   error handler. If sys.stdout has a buffer attribute, use
+   sys.stdout.buffer.write(encoded), otherwise redecode the string and use
+   sys.stdout.write(redecoded).
+
+   Helper function for sys_displayhook(). */
+static int
+sys_displayhook_unencodable(PyObject *outf, PyObject *o)
+{
+    PyObject *stdout_encoding = NULL;
+    PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
+    char *stdout_encoding_str;
+    int ret;
+
+    stdout_encoding = PyObject_GetAttrString(outf, "encoding");
+    if (stdout_encoding == NULL)
+        goto error;
+    stdout_encoding_str = _PyUnicode_AsString(stdout_encoding);
+    if (stdout_encoding_str == NULL)
+        goto error;
+
+    repr_str = PyObject_Repr(o);
+    if (repr_str == NULL)
+        goto error;
+    encoded = PyUnicode_AsEncodedString(repr_str,
+                                        stdout_encoding_str,
+                                        "backslashreplace");
+    Py_DECREF(repr_str);
+    if (encoded == NULL)
+        goto error;
+
+    buffer = PyObject_GetAttrString(outf, "buffer");
+    if (buffer) {
+        result = PyObject_CallMethod(buffer, "write", "(O)", encoded);
+        Py_DECREF(buffer);
+        Py_DECREF(encoded);
+        if (result == NULL)
+            goto error;
+        Py_DECREF(result);
+    }
+    else {
+        PyErr_Clear();
+        escaped_str = PyUnicode_FromEncodedObject(encoded,
+                                                  stdout_encoding_str,
+                                                  "strict");
+        Py_DECREF(encoded);
+        if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) {
+            Py_DECREF(escaped_str);
+            goto error;
+        }
+        Py_DECREF(escaped_str);
+    }
+    ret = 0;
+    goto finally;
+
+error:
+    ret = -1;
+finally:
+    Py_XDECREF(stdout_encoding);
+    return ret;
+}
+
 static PyObject *
 sys_displayhook(PyObject *self, PyObject *o)
 {
@@ -72,6 +134,7 @@
     PyInterpreterState *interp = PyThreadState_GET()->interp;
     PyObject *modules = interp->modules;
     PyObject *builtins = PyDict_GetItemString(modules, "builtins");
+    int err;
 
     if (builtins == NULL) {
         PyErr_SetString(PyExc_RuntimeError, "lost builtins module");
@@ -92,8 +155,19 @@
         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
         return NULL;
     }
-    if (PyFile_WriteObject(o, outf, 0) != 0)
-        return NULL;
+    if (PyFile_WriteObject(o, outf, 0) != 0) {
+        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
+            /* repr(o) is not encodable to sys.stdout.encoding with
+             * sys.stdout.errors error handler (which is probably 'strict') */
+            PyErr_Clear();
+            err = sys_displayhook_unencodable(outf, o);
+            if (err)
+                return NULL;
+        }
+        else {
+            return NULL;
+        }
+    }
     if (PyFile_WriteString("\n", outf) != 0)
         return NULL;
     if (PyObject_SetAttrString(builtins, "_", o) != 0)

From python-checkins at python.org  Sat Dec  4 18:24:47 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat,  4 Dec 2010 18:24:47 +0100 (CET)
Subject: [Python-checkins] r87055 - in python/branches/release27-maint:
	Lib/test/regrtest.py Misc/ACKS Misc/NEWS
Message-ID: <20101204172447.0D912EE9DF@mail.python.org>

Author: r.david.murray
Date: Sat Dec  4 18:24:46 2010
New Revision: 87055

Log:
Merged revisions 85086 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85086 | r.david.murray | 2010-09-28 21:08:05 -0400 (Tue, 28 Sep 2010) | 4 lines
  
  #7110: have regrtest print test failures and tracebacks to stderr not stdout.
  
  Patch by Sandro Tosi.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/test/regrtest.py
   python/branches/release27-maint/Misc/ACKS
   python/branches/release27-maint/Misc/NEWS

Modified: python/branches/release27-maint/Lib/test/regrtest.py
==============================================================================
--- python/branches/release27-maint/Lib/test/regrtest.py	(original)
+++ python/branches/release27-maint/Lib/test/regrtest.py	Sat Dec  4 18:24:46 2010
@@ -894,16 +894,16 @@
     except KeyboardInterrupt:
         raise
     except test_support.TestFailed, msg:
-        print "test", test, "failed --", msg
-        sys.stdout.flush()
+        print >>sys.stderr, "test", test, "failed --", msg
+        sys.stderr.flush()
         return FAILED, test_time
     except:
         type, value = sys.exc_info()[:2]
-        print "test", test, "crashed --", str(type) + ":", value
-        sys.stdout.flush()
+        print >>sys.stderr, "test", test, "crashed --", str(type) + ":", value
+        sys.stderr.flush()
         if verbose:
-            traceback.print_exc(file=sys.stdout)
-            sys.stdout.flush()
+            traceback.print_exc(file=sys.stderr)
+            sys.stderr.flush()
         return FAILED, test_time
     else:
         if refleak:

Modified: python/branches/release27-maint/Misc/ACKS
==============================================================================
--- python/branches/release27-maint/Misc/ACKS	(original)
+++ python/branches/release27-maint/Misc/ACKS	Sat Dec  4 18:24:46 2010
@@ -791,6 +791,7 @@
 R Lindsay Todd
 Bennett Todd
 Matias Torchinsky
+Sandro Tosi
 Richard Townsend
 Laurence Tratt
 John Tromp

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sat Dec  4 18:24:46 2010
@@ -24,6 +24,12 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+Tests
+-----
+
+- Issue #7110: regrtest now sends test failure reports and single-failure
+  tracebacks to stderr rather than stdout.
+
 
 What's New in Python 2.7.1?
 ===========================

From python-checkins at python.org  Sat Dec  4 18:31:49 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat,  4 Dec 2010 18:31:49 +0100 (CET)
Subject: [Python-checkins] r87056 - in python/branches/py3k: Lib/argparse.py
	Lib/test/test_argparse.py Misc/NEWS
Message-ID: <20101204173149.B69B7EE985@mail.python.org>

Author: eric.araujo
Date: Sat Dec  4 18:31:49 2010
New Revision: 87056

Log:
Use proper plural forms in argparse (#4391)


Modified:
   python/branches/py3k/Lib/argparse.py
   python/branches/py3k/Lib/test/test_argparse.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/argparse.py
==============================================================================
--- python/branches/py3k/Lib/argparse.py	(original)
+++ python/branches/py3k/Lib/argparse.py	Sat Dec  4 18:31:49 2010
@@ -88,7 +88,7 @@
 import sys as _sys
 import textwrap as _textwrap
 
-from gettext import gettext as _
+from gettext import gettext as _, ngettext
 
 
 def _callable(obj):
@@ -1438,7 +1438,9 @@
             conflict_handler(action, confl_optionals)
 
     def _handle_conflict_error(self, action, conflicting_actions):
-        message = _('conflicting option string(s): %s')
+        message = ngettext('conflicting option string: %s',
+                           'conflicting option strings: %s',
+                           len(conflicting_actions))
         conflict_string = ', '.join([option_string
                                      for option_string, action
                                      in conflicting_actions])
@@ -1995,7 +1997,9 @@
                 OPTIONAL: _('expected at most one argument'),
                 ONE_OR_MORE: _('expected at least one argument'),
             }
-            default = _('expected %s argument(s)') % action.nargs
+            default = ngettext('expected %s argument',
+                               'expected %s arguments',
+                               action.nargs) % action.nargs
             msg = nargs_errors.get(action.nargs, default)
             raise ArgumentError(action, msg)
 

Modified: python/branches/py3k/Lib/test/test_argparse.py
==============================================================================
--- python/branches/py3k/Lib/test/test_argparse.py	(original)
+++ python/branches/py3k/Lib/test/test_argparse.py	Sat Dec  4 18:31:49 2010
@@ -4315,7 +4315,7 @@
         items = [
             name
             for name, value in vars(argparse).items()
-            if not name.startswith("_")
+            if not (name.startswith("_") or name == 'ngettext')
             if not inspect.ismodule(value)
         ]
         self.assertEqual(sorted(items), sorted(argparse.__all__))

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 18:31:49 2010
@@ -49,6 +49,8 @@
 Library
 -------
 
+- Issue #4391: Use proper plural forms in argparse.
+
 - Issue #10601: sys.displayhook uses 'backslashreplace' error handler on
   UnicodeEncodeError.
 

From python-checkins at python.org  Sat Dec  4 18:48:19 2010
From: python-checkins at python.org (lukasz.langa)
Date: Sat,  4 Dec 2010 18:48:19 +0100 (CET)
Subject: [Python-checkins] r87057 - in python/branches/py3k/Lib:
	configparser.py test/test_cfgparser.py
Message-ID: <20101204174819.14541EE986@mail.python.org>

Author: lukasz.langa
Date: Sat Dec  4 18:48:18 2010
New Revision: 87057

Log:
configparser: mapping protocol access get() handles configparser-specific arguments as well


Modified:
   python/branches/py3k/Lib/configparser.py
   python/branches/py3k/Lib/test/test_cfgparser.py

Modified: python/branches/py3k/Lib/configparser.py
==============================================================================
--- python/branches/py3k/Lib/configparser.py	(original)
+++ python/branches/py3k/Lib/configparser.py	Sat Dec  4 18:48:18 2010
@@ -1195,12 +1195,6 @@
         """Creates a view on a section of the specified `name` in `parser`."""
         self._parser = parser
         self._name = name
-        self.getint = functools.partial(self._parser.getint,
-                                        self._name)
-        self.getfloat = functools.partial(self._parser.getfloat,
-                                          self._name)
-        self.getboolean = functools.partial(self._parser.getboolean,
-                                            self._name)
 
     def __repr__(self):
         return ''.format(self._name)
@@ -1231,6 +1225,22 @@
         # XXX does not break when underlying container state changed
         return self._parser.options(self._name).__iter__()
 
+    def get(self, option, fallback=None, *, raw=False, vars=None):
+        return self._parser.get(self._name, option, raw=raw, vars=vars,
+                                fallback=fallback)
+
+    def getint(self, option, fallback=None, *, raw=False, vars=None):
+        return self._parser.getint(self._name, option, raw=raw, vars=vars,
+                                   fallback=fallback)
+
+    def getfloat(self, option, fallback=None, *, raw=False, vars=None):
+        return self._parser.getfloat(self._name, option, raw=raw, vars=vars,
+                                     fallback=fallback)
+
+    def getboolean(self, option, fallback=None, *, raw=False, vars=None):
+        return self._parser.getboolean(self._name, option, raw=raw, vars=vars,
+                                       fallback=fallback)
+
     @property
     def parser(self):
         # The parser object of the proxy is read-only.

Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py	(original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py	Sat Dec  4 18:48:18 2010
@@ -160,6 +160,49 @@
            'this line is much, much longer than my editor\nlikes it.')
         if self.allow_no_value:
             eq(cf['NoValue']['option-without-value'], None)
+        # test vars= and fallback=
+        eq(cf['Foo Bar'].get('foo', 'baz'), 'bar1')
+        eq(cf['Foo Bar'].get('foo', fallback='baz'), 'bar1')
+        eq(cf['Foo Bar'].get('foo', vars={'foo': 'baz'}), 'baz')
+        with self.assertRaises(KeyError):
+            cf['No Such Foo Bar']['foo']
+        with self.assertRaises(KeyError):
+            cf['Foo Bar']['no-such-foo']
+        with self.assertRaises(KeyError):
+            cf['No Such Foo Bar'].get('foo', fallback='baz')
+        eq(cf['Foo Bar'].get('no-such-foo', 'baz'), 'baz')
+        eq(cf['Foo Bar'].get('no-such-foo', fallback='baz'), 'baz')
+        eq(cf['Spacey Bar'].get('foo', None), 'bar2')
+        eq(cf['Spacey Bar'].get('foo', fallback=None), 'bar2')
+        with self.assertRaises(KeyError):
+            cf['No Such Spacey Bar'].get('foo', None)
+        eq(cf['Types'].getint('int', 18), 42)
+        eq(cf['Types'].getint('int', fallback=18), 42)
+        eq(cf['Types'].getint('no-such-int', 18), 18)
+        eq(cf['Types'].getint('no-such-int', fallback=18), 18)
+        eq(cf['Types'].getint('no-such-int', "18"), "18") # sic!
+        eq(cf['Types'].getint('no-such-int', fallback="18"), "18") # sic!
+        self.assertAlmostEqual(cf['Types'].getfloat('float', 0.0), 0.44)
+        self.assertAlmostEqual(cf['Types'].getfloat('float',
+                                                    fallback=0.0), 0.44)
+        self.assertAlmostEqual(cf['Types'].getfloat('no-such-float', 0.0), 0.0)
+        self.assertAlmostEqual(cf['Types'].getfloat('no-such-float',
+                                                    fallback=0.0), 0.0)
+        eq(cf['Types'].getfloat('no-such-float', "0.0"), "0.0") # sic!
+        eq(cf['Types'].getfloat('no-such-float', fallback="0.0"), "0.0") # sic!
+        eq(cf['Types'].getboolean('boolean', True), False)
+        eq(cf['Types'].getboolean('boolean', fallback=True), False)
+        eq(cf['Types'].getboolean('no-such-boolean', "yes"), "yes") # sic!
+        eq(cf['Types'].getboolean('no-such-boolean', fallback="yes"),
+           "yes") # sic!
+        eq(cf['Types'].getboolean('no-such-boolean', True), True)
+        eq(cf['Types'].getboolean('no-such-boolean', fallback=True), True)
+        if self.allow_no_value:
+            eq(cf['NoValue'].get('option-without-value', False), None)
+            eq(cf['NoValue'].get('option-without-value', fallback=False), None)
+            eq(cf['NoValue'].get('no-such-option-without-value', False), False)
+            eq(cf['NoValue'].get('no-such-option-without-value',
+                      fallback=False), False)
 
         # Make sure the right things happen for remove_option();
         # added to include check for SourceForge bug #123324:

From python-checkins at python.org  Sat Dec  4 19:11:44 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Sat,  4 Dec 2010 19:11:44 +0100 (CET)
Subject: [Python-checkins] r87058 - in python/branches/py3k:
	Doc/library/subprocess.rst Lib/subprocess.py
Message-ID: <20101204181144.52835EE9C3@mail.python.org>

Author: gregory.p.smith
Date: Sat Dec  4 19:11:44 2010
New Revision: 87058

Log:
clarify the docs and new warning message.


Modified:
   python/branches/py3k/Doc/library/subprocess.rst
   python/branches/py3k/Lib/subprocess.py

Modified: python/branches/py3k/Doc/library/subprocess.rst
==============================================================================
--- python/branches/py3k/Doc/library/subprocess.rst	(original)
+++ python/branches/py3k/Doc/library/subprocess.rst	Sat Dec  4 19:11:44 2010
@@ -160,7 +160,7 @@
 
 .. versionchanged:: 3.2
    Callers should always specify a *close_fds* to avoid a DeprecationWarning.
-   The default value for this argument will be changing in Python 3.3.
+   The default behavior of this argument will be changing in Python 3.3.
 
    If *shell* is :const:`True`, the specified command will be executed through the
    shell.

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Sat Dec  4 19:11:44 2010
@@ -623,8 +623,8 @@
             # Notification for http://bugs.python.org/issue7213 & issue2320
             warnings.warn(
                     'The close_fds parameter was not specified.  Its default'
-                    ' will change from False to True in a future Python'
-                    ' version.  Most users should set it to True.  Please'
+                    ' behavior will change in a future Python version. '
+                    ' Most users should set it to True.  Please'
                     ' update your code explicitly set close_fds.',
                     DeprecationWarning)
 

From python-checkins at python.org  Sat Dec  4 19:36:03 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat,  4 Dec 2010 19:36:03 +0100 (CET)
Subject: [Python-checkins] r87059 - python/branches/py3k/setup.py
Message-ID: <20101204183603.53A6BEEA08@mail.python.org>

Author: antoine.pitrou
Date: Sat Dec  4 19:36:03 2010
New Revision: 87059

Log:
Silence compile error



Modified:
   python/branches/py3k/setup.py

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Sat Dec  4 19:36:03 2010
@@ -1579,9 +1579,10 @@
 ##         # Uncomment these lines if you want to play with xxmodule.c
 ##         ext = Extension('xx', ['xxmodule.c'])
 ##         self.extensions.append(ext)
-        ext = Extension('xxlimited', ['xxlimited.c'],
-                        define_macros=[('Py_LIMITED_API', 1)])
-        self.extensions.append(ext)
+        if 'd' not in sys.abiflags:
+            ext = Extension('xxlimited', ['xxlimited.c'],
+                            define_macros=[('Py_LIMITED_API', 1)])
+            self.extensions.append(ext)
 
         # XXX handle these, but how to detect?
         # *** Uncomment and edit for PIL (TkImaging) extension only:

From python-checkins at python.org  Sat Dec  4 20:01:30 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 20:01:30 +0100 (CET)
Subject: [Python-checkins] r87060 -
	python/branches/py3k/Lib/pydoc_data/topics.py
Message-ID: <20101204190130.6E1B6EE9BD@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 20:01:29 2010
New Revision: 87060

Log:
Update pydoc topics.

Modified:
   python/branches/py3k/Lib/pydoc_data/topics.py

Modified: python/branches/py3k/Lib/pydoc_data/topics.py
==============================================================================
--- python/branches/py3k/Lib/pydoc_data/topics.py	(original)
+++ python/branches/py3k/Lib/pydoc_data/topics.py	Sat Dec  4 20:01:29 2010
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Sat Nov 13 06:34:47 2010
+# Autogenerated by Sphinx on Sat Dec  4 19:58:44 2010
 topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n   assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n   if __debug__:\n      if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n   if __debug__:\n      if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names.  In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O).  The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime.  Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal.  The value for the built-in\nvariable is determined when the interpreter starts.\n',
  'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n   assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n   target_list     ::= target ("," target)* [","]\n   target          ::= identifier\n              | "(" target_list ")"\n              | "[" target_list "]"\n              | attributeref\n              | subscription\n              | slicing\n              | "*" target\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable.  The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n  that target.\n\n* If the target list is a comma-separated list of targets: The object\n  must be an iterable with the same number of items as there are\n  targets in the target list, and the items are assigned, from left to\n  right, to the corresponding targets. (This rule is relaxed as of\n  Python 1.5; in earlier versions, the object had to be a tuple.\n  Since strings are sequences, an assignment like ``a, b = "xy"`` is\n  now legal as long as the string has the right length.)\n\n  * If the target list contains one target prefixed with an asterisk,\n    called a "starred" target: The object must be a sequence with at\n    least as many items as there are targets in the target list, minus\n    one.  The first items of the sequence are assigned, from left to\n    right, to the targets before the starred target.  The final items\n    of the sequence are assigned to the targets after the starred\n    target.  A list of the remaining items in the sequence is then\n    assigned to the starred target (the list can be empty).\n\n  * Else: The object must be a sequence with the same number of items\n    as there are targets in the target list, and the items are\n    assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n  * If the name does not occur in a ``global`` or ``nonlocal``\n    statement in the current code block: the name is bound to the\n    object in the current local namespace.\n\n  * Otherwise: the name is bound to the object in the global namespace\n    or the outer namespace determined by ``nonlocal``, respectively.\n\n  The name is rebound if it was already bound.  This may cause the\n  reference count for the object previously bound to the name to reach\n  zero, causing the object to be deallocated and its destructor (if it\n  has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n  brackets: The object must be an iterable with the same number of\n  items as there are targets in the target list, and its items are\n  assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n  the reference is evaluated.  It should yield an object with\n  assignable attributes; if this is not the case, ``TypeError`` is\n  raised.  That object is then asked to assign the assigned object to\n  the given attribute; if it cannot perform the assignment, it raises\n  an exception (usually but not necessarily ``AttributeError``).\n\n  Note: If the object is a class instance and the attribute reference\n  occurs on both sides of the assignment operator, the RHS expression,\n  ``a.x`` can access either an instance attribute or (if no instance\n  attribute exists) a class attribute.  The LHS target ``a.x`` is\n  always set as an instance attribute, creating it if necessary.\n  Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n  same attribute: if the RHS expression refers to a class attribute,\n  the LHS creates a new instance attribute as the target of the\n  assignment:\n\n     class Cls:\n         x = 3             # class variable\n     inst = Cls()\n     inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3\n\n  This description does not necessarily apply to descriptor\n  attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n  reference is evaluated.  It should yield either a mutable sequence\n  object (such as a list) or a mapping object (such as a dictionary).\n  Next, the subscript expression is evaluated.\n\n  If the primary is a mutable sequence object (such as a list), the\n  subscript must yield an integer.  If it is negative, the sequence\'s\n  length is added to it.  The resulting value must be a nonnegative\n  integer less than the sequence\'s length, and the sequence is asked\n  to assign the assigned object to its item with that index.  If the\n  index is out of range, ``IndexError`` is raised (assignment to a\n  subscripted sequence cannot add new items to a list).\n\n  If the primary is a mapping object (such as a dictionary), the\n  subscript must have a type compatible with the mapping\'s key type,\n  and the mapping is then asked to create a key/datum pair which maps\n  the subscript to the assigned object.  This can either replace an\n  existing key/value pair with the same key value, or insert a new\n  key/value pair (if no key with the same value existed).\n\n  For user-defined objects, the ``__setitem__()`` method is called\n  with appropriate arguments.\n\n* If the target is a slicing: The primary expression in the reference\n  is evaluated.  It should yield a mutable sequence object (such as a\n  list).  The assigned object should be a sequence object of the same\n  type.  Next, the lower and upper bound expressions are evaluated,\n  insofar they are present; defaults are zero and the sequence\'s\n  length.  The bounds should evaluate to integers. If either bound is\n  negative, the sequence\'s length is added to it.  The resulting\n  bounds are clipped to lie between zero and the sequence\'s length,\n  inclusive.  Finally, the sequence object is asked to replace the\n  slice with the items of the assigned sequence.  The length of the\n  slice may be different from the length of the assigned sequence,\n  thus changing the length of the target sequence, if the object\n  allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe!  For instance, the\nfollowing program prints ``[0, 2]``:\n\n   x = [0, 1]\n   i = 0\n   i, x[i] = 1, 2\n   print(x)\n\nSee also:\n\n   **PEP 3132** - Extended Iterable Unpacking\n      The specification for the ``*target`` feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n   augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n   augtarget                 ::= identifier | attributeref | subscription | slicing\n   augop                     ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n             | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n',
  'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name.  See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them.  The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name.  For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``.  This transformation is independent of\nthe syntactical context in which the identifier is used.  If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen.  If the class name\nconsists only of underscores, no transformation is done.\n',
@@ -16,14 +16,14 @@
  'break': '\nThe ``break`` statement\n***********************\n\n   break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n',
  'callable-types': '\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n   ``x.__call__(arg1, arg2, ...)``.\n',
  'calls': '\nCalls\n*****\n\nA call calls a callable object (e.g., a function) with a possibly\nempty series of arguments:\n\n   call                 ::= primary "(" [argument_list [","] | comprehension] ")"\n   argument_list        ::= positional_arguments ["," keyword_arguments]\n                       ["," "*" expression] ["," keyword_arguments]\n                       ["," "**" expression]\n                     | keyword_arguments ["," "*" expression]\n                       ["," keyword_arguments] ["," "**" expression]\n                     | "*" expression ["," keyword_arguments] ["," "**" expression]\n                     | "**" expression\n   positional_arguments ::= expression ("," expression)*\n   keyword_arguments    ::= keyword_item ("," keyword_item)*\n   keyword_item         ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n``__call__()`` method are callable).  All argument expressions are\nevaluated before the call is attempted.  Please refer to section\n*Function definitions* for the syntax of formal parameter lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows.  First, a list of unfilled slots is\ncreated for the formal parameters.  If there are N positional\narguments, they are placed in the first N slots.  Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on).  If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot).  When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition.  (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.)  If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised.  Otherwise, the list of filled\nslots is used as the argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword.  In CPython, this is the case\nfor functions implemented in C that use ``PyArg_ParseTuple()`` to\nparse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to a sequence.  Elements from this\nsequence are treated as if they were additional positional arguments;\nif there are positional arguments *x1*,..., *xN*, and ``expression``\nevaluates to a sequence *y1*, ..., *yM*, this is equivalent to a call\nwith M+N positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the ``*expression`` syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow).  So:\n\n   >>> def f(a, b):\n   ...  print(a, b)\n   ...\n   >>> f(b=1, *(2,))\n   2 1\n   >>> f(a=1, *(2,))\n   Traceback (most recent call last):\n     File "", line 1, in ?\n   TypeError: f() got multiple values for keyword argument \'a\'\n   >>> f(1, *(2,))\n   1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments.  In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception.  How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n   The code block for the function is executed, passing it the\n   argument list.  The first thing the code block will do is bind the\n   formal parameters to the arguments; this is described in section\n   *Function definitions*.  When the code block executes a ``return``\n   statement, this specifies the return value of the function call.\n\na built-in function or method:\n   The result is up to the interpreter; see *Built-in Functions* for\n   the descriptions of built-in functions and methods.\n\na class object:\n   A new instance of that class is returned.\n\na class instance method:\n   The corresponding user-defined function is called, with an argument\n   list that is one longer than the argument list of the call: the\n   instance becomes the first argument.\n\na class instance:\n   The class must define a ``__call__()`` method; the effect is then\n   the same as if that method was called.\n',
- 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list [","] | comprehension] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with ``self.name = value``.  Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way.  Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results.  *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n   **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n   Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n    is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n    exception or the execution of a ``return``, ``continue``, or\n    ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n    body is transformed into the function\'s ``__doc__`` attribute and\n    therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s ``__doc__`` item and\n    therefore the class\'s *docstring*.\n',
+ 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list [","] | comprehension] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with ``self.name = value``.  Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way.  Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results.  *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n   **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n   Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n    is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n    exception or the execution of a ``return``, ``continue``, or\n    ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n    body is transformed into the function\'s ``__doc__`` attribute and\n    therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s ``__doc__`` item and\n    therefore the class\'s *docstring*.\n',
  'comparisons': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation.  Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n   comparison    ::= or_expr ( comp_operator or_expr )*\n   comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n                     | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects.  The objects need not have the same type.\nIf both are numbers, they are converted to a common type.  Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes.  You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n  are identical to themselves, ``x is x`` but are not equal to\n  themselves, ``x != x``.  Additionally, comparing any value to a\n  not-a-number value will return ``False``.  For example, both ``3 <\n  float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n  values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n  (the result of the built-in function ``ord()``) of their characters.\n  [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n  corresponding elements.  This means that to compare equal, each\n  element must compare equal and the two sequences must be of the same\n  type and have the same length.\n\n  If not equal, the sequences are ordered the same as their first\n  differing elements.  For example, ``[1,2,x] <= [1,2,y]`` has the\n  same value as ``x <= y``.  If the corresponding element does not\n  exist, the shorter sequence is ordered first (for example, ``[1,2] <\n  [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n  same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n  \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n  superset tests.  Those relations do not define total orderings (the\n  two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n  another, nor supersets of one another).  Accordingly, sets are not\n  appropriate arguments for functions which depend on total ordering.\n  For example, ``min()``, ``max()``, and ``sorted()`` produce\n  undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n  the same object; the choice whether one object is considered smaller\n  or larger than another one is made arbitrarily but consistently\n  within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison.  Most\nnumeric types can be compared with one another, but comparisons of\n``float`` and ``Decimal`` are not supported to avoid the inevitable\nconfusion arising from representation issues such as ``float(\'1.1\')``\nbeing inexactly represented and therefore not exactly equal to\n``Decimal(\'1.1\')`` which is.  When cross-type comparison is not\nsupported, the comparison method returns ``NotImplemented``.  This can\ncreate the illusion of non-transitivity between supported cross-type\ncomparisons and unsupported comparisons.  For example, ``Decimal(2) ==\n2`` and ``2 == float(2)`` but ``Decimal(2) != float(2)``.\n\nThe operators ``in`` and ``not in`` test for membership.  ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise.  ``x\nnot in s`` returns the negation of ``x in s``.  All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*.  An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``.  If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception.  (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object.  ``x is\nnot y`` yields the inverse truth value. [4]\n',
- 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way.  In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs.  ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code.  Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\'  A clause\nconsists of a header and a \'suite.\'  The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon.  A suite is a group of statements controlled by a\nclause.  A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines.  Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n   if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n   if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n   compound_stmt ::= if_stmt\n                     | while_stmt\n                     | for_stmt\n                     | try_stmt\n                     | with_stmt\n                     | funcdef\n                     | classdef\n   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n   statement     ::= stmt_list NEWLINE | compound_stmt\n   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``.  Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n``expression_list``.  The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop.  Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n  (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n   try_stmt  ::= try1_stmt | try2_stmt\n   try1_stmt ::= "try" ":" suite\n                 ("except" [expression ["as" target]] ":" suite)+\n                 ["else" ":" suite]\n                 ["finally" ":" suite]\n   try2_stmt ::= "try" ":" suite\n                 "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started.  This search inspects the except\nclauses in turn until one is found that matches the exception.  An\nexpression-less except clause, if present, must be last; it matches\nany exception.  For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception.  An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed.  All except\nclauses must have an executable block.  When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause.  This is as if\n\n   except E as N:\n       foo\n\nwas translated to\n\n   except E as N:\n       try:\n           foo\n       finally:\n           del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause.  Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler.  The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses.  If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted.  If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost.  The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n   value from ``__enter__()`` is assigned to it.\n\n   Note: The ``with`` statement guarantees that if the ``__enter__()``\n     method returns without an error, then ``__exit__()`` will always\n     be called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to ``__exit__()``. Otherwise,\n   three ``None`` arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the ``__exit__()`` method was false, the exception is\n   reraised.  If the return value was true, the exception is\n   suppressed, and execution continues with the statement following\n   the ``with`` statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from ``__exit__()`` is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n   **PEP 0343** - The "with" statement\n      The specification, background, and examples for the Python\n      ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      (  "*" [parameter] ("," defparameter)*\n                      [, "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call.  This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended.  A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple.  If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name.  Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``.  Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list.  These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code.  The presence of annotations does not change the\nsemantics of a function.  The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda forms,\ndescribed in section *Lambdas*.  Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form.  The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around.  Free variables used in the\nnested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list [","] | comprehension] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with ``self.name = value``.  Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way.  Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results.  *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n   **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n   Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n    is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n    exception or the execution of a ``return``, ``continue``, or\n    ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n    body is transformed into the function\'s ``__doc__`` attribute and\n    therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s ``__doc__`` item and\n    therefore the class\'s *docstring*.\n',
+ 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way.  In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs.  ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code.  Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\'  A clause\nconsists of a header and a \'suite.\'  The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon.  A suite is a group of statements controlled by a\nclause.  A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines.  Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n   if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n   if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n   compound_stmt ::= if_stmt\n                     | while_stmt\n                     | for_stmt\n                     | try_stmt\n                     | with_stmt\n                     | funcdef\n                     | classdef\n   suite         ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n   statement     ::= stmt_list NEWLINE | compound_stmt\n   stmt_list     ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``.  Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n``expression_list``.  The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop.  Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n  (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n   try_stmt  ::= try1_stmt | try2_stmt\n   try1_stmt ::= "try" ":" suite\n                 ("except" [expression ["as" target]] ":" suite)+\n                 ["else" ":" suite]\n                 ["finally" ":" suite]\n   try2_stmt ::= "try" ":" suite\n                 "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started.  This search inspects the except\nclauses in turn until one is found that matches the exception.  An\nexpression-less except clause, if present, must be last; it matches\nany exception.  For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception.  An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed.  All except\nclauses must have an executable block.  When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause.  This is as if\n\n   except E as N:\n       foo\n\nwas translated to\n\n   except E as N:\n       try:\n           foo\n       finally:\n           del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause.  Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler.  The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses.  If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted.  If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost.  The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n   with_stmt ::= "with" with_item ("," with_item)* ":" suite\n   with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n   is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n   value from ``__enter__()`` is assigned to it.\n\n   Note: The ``with`` statement guarantees that if the ``__enter__()``\n     method returns without an error, then ``__exit__()`` will always\n     be called. Thus, if an error occurs during the assignment to the\n     target list, it will be treated the same as an error occurring\n     within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked.  If an\n   exception caused the suite to be exited, its type, value, and\n   traceback are passed as arguments to ``__exit__()``. Otherwise,\n   three ``None`` arguments are supplied.\n\n   If the suite was exited due to an exception, and the return value\n   from the ``__exit__()`` method was false, the exception is\n   reraised.  If the return value was true, the exception is\n   suppressed, and execution continues with the statement following\n   the ``with`` statement.\n\n   If the suite was exited for any reason other than an exception, the\n   return value from ``__exit__()`` is ignored, and execution proceeds\n   at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n   with A() as a, B() as b:\n       suite\n\nis equivalent to\n\n   with A() as a:\n       with B() as b:\n           suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n   **PEP 0343** - The "with" statement\n      The specification, background, and examples for the Python\n      ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      (  "*" [parameter] ("," defparameter)*\n                      [, "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call.  This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended.  A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple.  If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name.  Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``.  Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list.  These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code.  The presence of annotations does not change the\nsemantics of a function.  The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda forms,\ndescribed in section *Lambdas*.  Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form.  The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around.  Free variables used in the\nnested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n   classdef    ::= [decorators] "class" classname [inheritance] ":" suite\n   inheritance ::= "(" [argument_list [","] | comprehension] ")"\n   classname   ::= identifier\n\nA class definition is an executable statement.  The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.  Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n   class Foo:\n       pass\n\nis equivalent to\n\n   class Foo(object):\n       pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.)  When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n   @f1(arg)\n   @f2\n   class Foo: pass\n\nis equivalent to\n\n   class Foo: pass\n   Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators.  The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances.  Instance attributes\ncan be set in a method with ``self.name = value``.  Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way.  Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results.  *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n   **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n   Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n    is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n    exception or the execution of a ``return``, ``continue``, or\n    ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n    body is transformed into the function\'s ``__doc__`` attribute and\n    therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n    body is transformed into the namespace\'s ``__doc__`` item and\n    therefore the class\'s *docstring*.\n',
  'context-managers': '\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code.  Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The ``with``\n   statement will bind this method\'s return value to the target(s)\n   specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be ``None``.\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that ``__exit__()`` methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also:\n\n   **PEP 0343** - The "with" statement\n      The specification, background, and examples for the Python\n      ``with`` statement.\n',
  'continue': '\nThe ``continue`` statement\n**************************\n\n   continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop.  It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n',
  'conversions': '\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works that way:\n\n* If either argument is a complex number, the other is converted to\n  complex;\n\n* otherwise, if either argument is a floating point number, the other\n  is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator).  Extensions must define their own\nconversion behavior.\n',
  'customization': '\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  ``__new__()`` is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of ``__new__()`` should be the new object instance (usually\n   an instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s ``__new__()`` method using\n   ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If ``__new__()`` returns an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will be invoked like\n   ``__init__(self[, ...])``, where *self* is the new instance and the\n   remaining arguments are the same as were passed to ``__new__()``.\n\n   If ``__new__()`` does not return an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will not be invoked.\n\n   ``__new__()`` is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called when the instance is created.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   ``__init__()`` method, the derived class\'s ``__init__()`` method,\n   if any, must explicitly call it to ensure proper initialization of\n   the base class part of the instance; for example:\n   ``BaseClass.__init__(self, [args...])``.  As a special constraint\n   on constructors, no value may be returned; doing so will cause a\n   ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a ``__del__()`` method,\n   the derived class\'s ``__del__()`` method, if any, must explicitly\n   call it to ensure proper deletion of the base class part of the\n   instance.  Note that it is possible (though not recommended!) for\n   the ``__del__()`` method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   ``__del__()`` methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n     decrements the reference count for ``x`` by one, and the latter\n     is only called when ``x``\'s reference count reaches zero.  Some\n     common situations that may prevent the reference count of an\n     object from going to zero include: circular references between\n     objects (e.g., a doubly-linked list or a tree data structure with\n     parent and child pointers); a reference to the object on the\n     stack frame of a function that caught an exception (the traceback\n     stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n     a reference to the object on the stack frame that raised an\n     unhandled exception in interactive mode (the traceback stored in\n     ``sys.last_traceback`` keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the latter two situations can be resolved by storing ``None`` in\n     ``sys.last_traceback``. Circular references which are garbage are\n     detected when the option cycle detector is enabled (it\'s on by\n     default), but can only be cleaned up if there are no Python-\n     level ``__del__()`` methods involved. Refer to the documentation\n     for the ``gc`` module for more information about how\n     ``__del__()`` methods are handled by the cycle detector,\n     particularly the description of the ``garbage`` value.\n\n   Warning: Due to the precarious circumstances under which ``__del__()``\n     methods are invoked, exceptions that occur during their execution\n     are ignored, and a warning is printed to ``sys.stderr`` instead.\n     Also, when ``__del__()`` is invoked in response to a module being\n     deleted (e.g., when execution of the program is done), other\n     globals referenced by the ``__del__()`` method may already have\n     been deleted or in the process of being torn down (e.g. the\n     import machinery shutting down).  For this reason, ``__del__()``\n     methods should do the absolute minimum needed to maintain\n     external invariants.  Starting with version 1.5, Python\n     guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n   Called by the ``repr()`` built-in function to compute the\n   "official" string representation of an object.  If at all possible,\n   this should look like a valid Python expression that could be used\n   to recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   ``<...some useful description...>`` should be returned. The return\n   value must be a string object. If a class defines ``__repr__()``\n   but not ``__str__()``, then ``__repr__()`` is also used when an\n   "informal" string representation of instances of that class is\n   required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by the ``str()`` built-in function and by the ``print()``\n   function to compute the "informal" string representation of an\n   object.  This differs from ``__repr__()`` in that it does not have\n   to be a valid Python expression: a more convenient or concise\n   representation may be used instead. The return value must be a\n   string object.\n\nobject.__format__(self, format_spec)\n\n   Called by the ``format()`` built-in function (and by extension, the\n   ``format()`` method of class ``str``) to produce a "formatted"\n   string representation of an object. The ``format_spec`` argument is\n   a string that contains a description of the formatting options\n   desired. The interpretation of the ``format_spec`` argument is up\n   to the type implementing ``__format__()``, however most classes\n   will either delegate formatting to one of the built-in types, or\n   use a similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n   ``x.__ge__(y)``.\n\n   A rich comparison method may return the singleton\n   ``NotImplemented`` if it does not implement the operation for a\n   given pair of arguments. By convention, ``False`` and ``True`` are\n   returned for a successful comparison. However, these methods can\n   return any value, so if the comparison operator is used in a\n   Boolean context (e.g., in the condition of an ``if`` statement),\n   Python will call ``bool()`` on the value to determine if the result\n   is true or false.\n\n   There are no implied relationships among the comparison operators.\n   The truth of ``x==y`` does not imply that ``x!=y`` is false.\n   Accordingly, when defining ``__eq__()``, one should also define\n   ``__ne__()`` so that the operators will behave as expected.  See\n   the paragraph on ``__hash__()`` for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n   other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n   reflection, and ``__eq__()`` and ``__ne__()`` are their own\n   reflection.\n\n   Arguments to rich comparison methods are never coerced.\n\n   To automatically generate ordering operations from a single root\n   operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n   Called by built-in function ``hash()`` and for operations on\n   members of hashed collections including ``set``, ``frozenset``, and\n   ``dict``.  ``__hash__()`` should return an integer.  The only\n   required property is that objects which compare equal have the same\n   hash value; it is advised to somehow mix together (e.g. using\n   exclusive or) the hash values for the components of the object that\n   also play a part in comparison of objects.\n\n   If a class does not define an ``__eq__()`` method it should not\n   define a ``__hash__()`` operation either; if it defines\n   ``__eq__()`` but not ``__hash__()``, its instances will not be\n   usable as items in hashable collections.  If a class defines\n   mutable objects and implements an ``__eq__()`` method, it should\n   not implement ``__hash__()``, since the implementation of hashable\n   collections requires that a key\'s hash value is immutable (if the\n   object\'s hash value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n   by default; with them, all objects compare unequal (except with\n   themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n   Classes which inherit a ``__hash__()`` method from a parent class\n   but change the meaning of ``__eq__()`` such that the hash value\n   returned is no longer appropriate (e.g. by switching to a value-\n   based concept of equality instead of the default identity based\n   equality) can explicitly flag themselves as being unhashable by\n   setting ``__hash__ = None`` in the class definition. Doing so means\n   that not only will instances of the class raise an appropriate\n   ``TypeError`` when a program attempts to retrieve their hash value,\n   but they will also be correctly identified as unhashable when\n   checking ``isinstance(obj, collections.Hashable)`` (unlike classes\n   which define their own ``__hash__()`` to explicitly raise\n   ``TypeError``).\n\n   If a class that overrides ``__eq__()`` needs to retain the\n   implementation of ``__hash__()`` from a parent class, the\n   interpreter must be told this explicitly by setting ``__hash__ =\n   .__hash__``. Otherwise the inheritance of\n   ``__hash__()`` will be blocked, just as if ``__hash__`` had been\n   explicitly set to ``None``.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   ``bool()``; should return ``False`` or ``True``.  When this method\n   is not defined, ``__len__()`` is called, if it is defined, and the\n   object is considered true if its result is nonzero.  If a class\n   defines neither ``__len__()`` nor ``__bool__()``, all its instances\n   are considered true.\n',
- 'debugger': '\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs.  It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame.  It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source.  The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> pdb.run(\'mymodule.test()\')\n   > (0)?()\n   (Pdb) continue\n   > (1)?()\n   (Pdb) continue\n   NameError: \'spam\'\n   > (1)?()\n   (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n   python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally.  After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program.  Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: ``pdb.py`` now accepts a ``-c`` option that\nexecutes commands as if given in a ``.pdbrc`` file, see *Debugger\nCommands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n   import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger.  You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``continue`` command.\n\nThe typical usage to inspect a crashed program is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> mymodule.test()\n   Traceback (most recent call last):\n     File "", line 1, in ?\n     File "./mymodule.py", line 4, in test\n       test2()\n     File "./mymodule.py", line 3, in test2\n       print(spam)\n   NameError: spam\n   >>> pdb.pm()\n   > ./mymodule.py(3)test2()\n   -> print(spam)\n   (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n   Execute the *statement* (given as a string or a code object) under\n   debugger control.  The debugger prompt appears before any code is\n   executed; you can set breakpoints and type ``continue``, or you can\n   step through the statement using ``step`` or ``next`` (all these\n   commands are explained below).  The optional *globals* and *locals*\n   arguments specify the environment in which the code is executed; by\n   default the dictionary of the module ``__main__`` is used.  (See\n   the explanation of the built-in ``exec()`` or ``eval()``\n   functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n   Evaluate the *expression* (given as a string or a code object)\n   under debugger control.  When ``runeval()`` returns, it returns the\n   value of the expression.  Otherwise this function is similar to\n   ``run()``.\n\npdb.runcall(function, *args, **kwds)\n\n   Call the *function* (a function or method object, not a string)\n   with the given arguments.  When ``runcall()`` returns, it returns\n   whatever the function call returned.  The debugger prompt appears\n   as soon as the function is entered.\n\npdb.set_trace()\n\n   Enter the debugger at the calling stack frame.  This is useful to\n   hard-code a breakpoint at a given point in a program, even if the\n   code is not otherwise being debugged (e.g. when an assertion\n   fails).\n\npdb.post_mortem(traceback=None)\n\n   Enter post-mortem debugging of the given *traceback* object.  If no\n   *traceback* is given, it uses the one of the exception that is\n   currently being handled (an exception must be being handled if the\n   default is to be used).\n\npdb.pm()\n\n   Enter post-mortem debugging of the traceback found in\n   ``sys.last_traceback``.\n\nThe ``run_*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname.  If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n   ``Pdb`` is the debugger class.\n\n   The *completekey*, *stdin* and *stdout* arguments are passed to the\n   underlying ``cmd.Cmd`` class; see the description there.\n\n   The *skip* argument, if given, must be an iterable of glob-style\n   module name patterns.  The debugger will not step into frames that\n   originate in a module that matches one of these patterns. [1]\n\n   Example call to enable tracing with *skip*:\n\n      import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n   New in version 3.1: The *skip* argument.\n\n   run(statement, globals=None, locals=None)\n   runeval(expression, globals=None, locals=None)\n   runcall(function, *args, **kwds)\n   set_trace()\n\n      See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below.  Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n``h(elp)`` means that either ``h`` or ``help`` can be used to enter\nthe help command (but not ``he`` or ``hel``, nor ``H`` or ``Help`` or\n``HELP``).  Arguments to commands must be separated by whitespace\n(spaces or tabs).  Optional arguments are enclosed in square brackets\n(``[]``) in the command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n(``|``).\n\nEntering a blank line repeats the last command entered.  Exception: if\nthe last command was a ``list`` command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged.  Python statements can also be prefixed with an exclamation\npoint (``!``).  This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*.  Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by\n``;;``.  (A single ``;`` is not used as it is the separator for\nmultiple commands in a line that is passed to the Python parser.)  No\nintelligence is applied to separating the commands; the input is split\nat the first ``;;`` pair, even if it is in the middle of a quoted\nstring.\n\nIf a file ``.pdbrc`` exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt.  This is particularly useful for aliases.  If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ``.pdbrc`` can now contain commands that\ncontinue debugging, such as ``continue`` or ``next``.  Previously,\nthese commands had no effect.\n\nh(elp) [command]\n\n   Without argument, print the list of available commands.  With a\n   *command* as argument, print help about that command.  ``help pdb``\n   displays the full documentation (the docstring of the ``pdb``\n   module).  Since the *command* argument must be an identifier,\n   ``help exec`` must be entered to get help on the ``!`` command.\n\nw(here)\n\n   Print a stack trace, with the most recent frame at the bottom.  An\n   arrow indicates the current frame, which determines the context of\n   most commands.\n\nd(own) [count]\n\n   Move the current frame *count* (default one) levels down in the\n   stack trace (to a newer frame).\n\nu(p) [count]\n\n   Move the current frame *count* (default one) levels up in the stack\n   trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n   With a *lineno* argument, set a break there in the current file.\n   With a *function* argument, set a break at the first executable\n   statement within that function.  The line number may be prefixed\n   with a filename and a colon, to specify a breakpoint in another\n   file (probably one that hasn\'t been loaded yet).  The file is\n   searched on ``sys.path``.  Note that each breakpoint is assigned a\n   number to which all the other breakpoint commands refer.\n\n   If a second argument is present, it is an expression which must\n   evaluate to true before the breakpoint is honored.\n\n   Without argument, list all breaks, including for each breakpoint,\n   the number of times that breakpoint has been hit, the current\n   ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n   Temporary breakpoint, which is removed automatically when it is\n   first hit. The arguments are the same as for ``break``.\n\ncl(ear) [bpnumber [bpnumber ...]]\n\n   With a space separated list of breakpoint numbers, clear those\n   breakpoints. Without argument, clear all breaks (but first ask\n   confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n   Disable the breakpoints given as a space separated list of\n   breakpoint numbers.  Disabling a breakpoint means it cannot cause\n   the program to stop execution, but unlike clearing a breakpoint, it\n   remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n   Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n   Set the ignore count for the given breakpoint number.  If count is\n   omitted, the ignore count is set to 0.  A breakpoint becomes active\n   when the ignore count is zero.  When non-zero, the count is\n   decremented each time the breakpoint is reached and the breakpoint\n   is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n   Set a new *condition* for the breakpoint, an expression which must\n   evaluate to true before the breakpoint is honored.  If *condition*\n   is absent, any existing condition is removed; i.e., the breakpoint\n   is made unconditional.\n\ncommands [bpnumber]\n\n   Specify a list of commands for breakpoint number *bpnumber*.  The\n   commands themselves appear on the following lines.  Type a line\n   containing just ``end`` to terminate the commands. An example:\n\n      (Pdb) commands 1\n      (com) print some_variable\n      (com) end\n      (Pdb)\n\n   To remove all commands from a breakpoint, type commands and follow\n   it immediately with ``end``; that is, give no commands.\n\n   With no *bpnumber* argument, commands refers to the last breakpoint\n   set.\n\n   You can use breakpoint commands to start your program up again.\n   Simply use the continue command, or step, or any other command that\n   resumes execution.\n\n   Specifying any command resuming execution (currently continue,\n   step, next, return, jump, quit and their abbreviations) terminates\n   the command list (as if that command was immediately followed by\n   end). This is because any time you resume execution (even with a\n   simple next or step), you may encounter another breakpoint--which\n   could have its own command list, leading to ambiguities about which\n   list to execute.\n\n   If you use the \'silent\' command in the command list, the usual\n   message about stopping at a breakpoint is not printed.  This may be\n   desirable for breakpoints that are to print a specific message and\n   then continue.  If none of the other commands print anything, you\n   see no sign that the breakpoint was reached.\n\ns(tep)\n\n   Execute the current line, stop at the first possible occasion\n   (either in a function that is called or on the next line in the\n   current function).\n\nn(ext)\n\n   Continue execution until the next line in the current function is\n   reached or it returns.  (The difference between ``next`` and\n   ``step`` is that ``step`` stops inside a called function, while\n   ``next`` executes called functions at (nearly) full speed, only\n   stopping at the next line in the current function.)\n\nunt(il) [lineno]\n\n   Without argument, continue execution until the line with a number\n   greater than the current one is reached.\n\n   With a line number, continue execution until a line with a number\n   greater or equal to that is reached.  In both cases, also stop when\n   the current frame returns.\n\n   Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n   Continue execution until the current function returns.\n\nc(ont(inue))\n\n   Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n   Set the next line that will be executed.  Only available in the\n   bottom-most frame.  This lets you jump back and execute code again,\n   or jump forward to skip code that you don\'t want to run.\n\n   It should be noted that not all jumps are allowed -- for instance\n   it is not possible to jump into the middle of a ``for`` loop or out\n   of a ``finally`` clause.\n\nl(ist) [first[, last]]\n\n   List source code for the current file.  Without arguments, list 11\n   lines around the current line or continue the previous listing.\n   With ``.`` as argument, list 11 lines around the current line.\n   With one argument, list 11 lines around at that line.  With two\n   arguments, list the given range; if the second argument is less\n   than the first, it is interpreted as a count.\n\n   The current line in the current frame is indicated by ``->``.  If\n   an exception is being debugged, the line where the exception was\n   originally raised or propagated is indicated by ``>>``, if it\n   differs from the current line.\n\n   New in version 3.2: The ``>>`` marker.\n\nll | longlist\n\n   List all source code for the current function or frame.\n   Interesting lines are marked as for ``list``.\n\n   New in version 3.2.\n\na(rgs)\n\n   Print the argument list of the current function.\n\np(rint) expression\n\n   Evaluate the *expression* in the current context and print its\n   value.\n\npp expression\n\n   Like the ``print`` command, except the value of the expression is\n   pretty-printed using the ``pprint`` module.\n\nwhatis expression\n\n   Print the type of the *expression*.\n\nsource expression\n\n   Try to get source code for the given object and display it.\n\n   New in version 3.2.\n\nalias [name [command]]\n\n   Create an alias called *name* that executes *command*.  The command\n   must *not* be enclosed in quotes.  Replaceable parameters can be\n   indicated by ``%1``, ``%2``, and so on, while ``%*`` is replaced by\n   all the parameters. If no command is given, the current alias for\n   *name* is shown. If no arguments are given, all aliases are listed.\n\n   Aliases may be nested and can contain anything that can be legally\n   typed at the pdb prompt.  Note that internal pdb commands *can* be\n   overridden by aliases.  Such a command is then hidden until the\n   alias is removed.  Aliasing is recursively applied to the first\n   word of the command line; all other words in the line are left\n   alone.\n\n   As an example, here are two useful aliases (especially when placed\n   in the ``.pdbrc`` file):\n\n      # Print instance variables (usage "pi classInst")\n      alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n      # Print instance variables in self\n      alias ps pi self\n\nunalias name\n\n   Delete the specified alias.\n\n! statement\n\n   Execute the (one-line) *statement* in the context of the current\n   stack frame. The exclamation point can be omitted unless the first\n   word of the statement resembles a debugger command.  To set a\n   global variable, you can prefix the assignment command with a\n   ``global`` statement on the same line, e.g.:\n\n      (Pdb) global list_options; list_options = [\'-l\']\n      (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n   Restart the debugged Python program.  If an argument is supplied,\n   it is split with ``shlex`` and the result is used as the new\n   ``sys.argv``. History, breakpoints, actions and debugger options\n   are preserved. ``restart`` is an alias for ``run``.\n\nq(uit)\n\n   Quit from the debugger.  The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module is\n    determined by the ``__name__`` in the frame globals.\n',
+ 'debugger': '\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs.  It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame.  It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source.  The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> pdb.run(\'mymodule.test()\')\n   > (0)?()\n   (Pdb) continue\n   > (1)?()\n   (Pdb) continue\n   NameError: \'spam\'\n   > (1)?()\n   (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n   python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally.  After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program.  Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: ``pdb.py`` now accepts a ``-c`` option that\nexecutes commands as if given in a ``.pdbrc`` file, see *Debugger\nCommands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n   import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger.  You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``continue`` command.\n\nThe typical usage to inspect a crashed program is:\n\n   >>> import pdb\n   >>> import mymodule\n   >>> mymodule.test()\n   Traceback (most recent call last):\n     File "", line 1, in ?\n     File "./mymodule.py", line 4, in test\n       test2()\n     File "./mymodule.py", line 3, in test2\n       print(spam)\n   NameError: spam\n   >>> pdb.pm()\n   > ./mymodule.py(3)test2()\n   -> print(spam)\n   (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n   Execute the *statement* (given as a string or a code object) under\n   debugger control.  The debugger prompt appears before any code is\n   executed; you can set breakpoints and type ``continue``, or you can\n   step through the statement using ``step`` or ``next`` (all these\n   commands are explained below).  The optional *globals* and *locals*\n   arguments specify the environment in which the code is executed; by\n   default the dictionary of the module ``__main__`` is used.  (See\n   the explanation of the built-in ``exec()`` or ``eval()``\n   functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n   Evaluate the *expression* (given as a string or a code object)\n   under debugger control.  When ``runeval()`` returns, it returns the\n   value of the expression.  Otherwise this function is similar to\n   ``run()``.\n\npdb.runcall(function, *args, **kwds)\n\n   Call the *function* (a function or method object, not a string)\n   with the given arguments.  When ``runcall()`` returns, it returns\n   whatever the function call returned.  The debugger prompt appears\n   as soon as the function is entered.\n\npdb.set_trace()\n\n   Enter the debugger at the calling stack frame.  This is useful to\n   hard-code a breakpoint at a given point in a program, even if the\n   code is not otherwise being debugged (e.g. when an assertion\n   fails).\n\npdb.post_mortem(traceback=None)\n\n   Enter post-mortem debugging of the given *traceback* object.  If no\n   *traceback* is given, it uses the one of the exception that is\n   currently being handled (an exception must be being handled if the\n   default is to be used).\n\npdb.pm()\n\n   Enter post-mortem debugging of the traceback found in\n   ``sys.last_traceback``.\n\nThe ``run_*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname.  If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n   ``Pdb`` is the debugger class.\n\n   The *completekey*, *stdin* and *stdout* arguments are passed to the\n   underlying ``cmd.Cmd`` class; see the description there.\n\n   The *skip* argument, if given, must be an iterable of glob-style\n   module name patterns.  The debugger will not step into frames that\n   originate in a module that matches one of these patterns. [1]\n\n   By default, Pdb sets a handler for the SIGINT signal (which is sent\n   when the user presses Ctrl-C on the console) when you give a\n   ``continue`` command. This allows you to break into the debugger\n   again by pressing Ctrl-C.  If you want Pdb not to touch the SIGINT\n   handler, set *nosigint* tot true.\n\n   Example call to enable tracing with *skip*:\n\n      import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n   New in version 3.1: The *skip* argument.\n\n   New in version 3.2: The *nosigint* argument.  Previously, a SIGINT\n   handler was never set by Pdb.\n\n   run(statement, globals=None, locals=None)\n   runeval(expression, globals=None, locals=None)\n   runcall(function, *args, **kwds)\n   set_trace()\n\n      See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below.  Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n``h(elp)`` means that either ``h`` or ``help`` can be used to enter\nthe help command (but not ``he`` or ``hel``, nor ``H`` or ``Help`` or\n``HELP``).  Arguments to commands must be separated by whitespace\n(spaces or tabs).  Optional arguments are enclosed in square brackets\n(``[]``) in the command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n(``|``).\n\nEntering a blank line repeats the last command entered.  Exception: if\nthe last command was a ``list`` command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged.  Python statements can also be prefixed with an exclamation\npoint (``!``).  This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*.  Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by\n``;;``.  (A single ``;`` is not used as it is the separator for\nmultiple commands in a line that is passed to the Python parser.)  No\nintelligence is applied to separating the commands; the input is split\nat the first ``;;`` pair, even if it is in the middle of a quoted\nstring.\n\nIf a file ``.pdbrc`` exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt.  This is particularly useful for aliases.  If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ``.pdbrc`` can now contain commands that\ncontinue debugging, such as ``continue`` or ``next``.  Previously,\nthese commands had no effect.\n\nh(elp) [command]\n\n   Without argument, print the list of available commands.  With a\n   *command* as argument, print help about that command.  ``help pdb``\n   displays the full documentation (the docstring of the ``pdb``\n   module).  Since the *command* argument must be an identifier,\n   ``help exec`` must be entered to get help on the ``!`` command.\n\nw(here)\n\n   Print a stack trace, with the most recent frame at the bottom.  An\n   arrow indicates the current frame, which determines the context of\n   most commands.\n\nd(own) [count]\n\n   Move the current frame *count* (default one) levels down in the\n   stack trace (to a newer frame).\n\nu(p) [count]\n\n   Move the current frame *count* (default one) levels up in the stack\n   trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n   With a *lineno* argument, set a break there in the current file.\n   With a *function* argument, set a break at the first executable\n   statement within that function.  The line number may be prefixed\n   with a filename and a colon, to specify a breakpoint in another\n   file (probably one that hasn\'t been loaded yet).  The file is\n   searched on ``sys.path``.  Note that each breakpoint is assigned a\n   number to which all the other breakpoint commands refer.\n\n   If a second argument is present, it is an expression which must\n   evaluate to true before the breakpoint is honored.\n\n   Without argument, list all breaks, including for each breakpoint,\n   the number of times that breakpoint has been hit, the current\n   ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n   Temporary breakpoint, which is removed automatically when it is\n   first hit. The arguments are the same as for ``break``.\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n   With a *filename:lineno* argument, clear all the breakpoints at\n   this line. With a space separated list of breakpoint numbers, clear\n   those breakpoints. Without argument, clear all breaks (but first\n   ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n   Disable the breakpoints given as a space separated list of\n   breakpoint numbers.  Disabling a breakpoint means it cannot cause\n   the program to stop execution, but unlike clearing a breakpoint, it\n   remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n   Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n   Set the ignore count for the given breakpoint number.  If count is\n   omitted, the ignore count is set to 0.  A breakpoint becomes active\n   when the ignore count is zero.  When non-zero, the count is\n   decremented each time the breakpoint is reached and the breakpoint\n   is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n   Set a new *condition* for the breakpoint, an expression which must\n   evaluate to true before the breakpoint is honored.  If *condition*\n   is absent, any existing condition is removed; i.e., the breakpoint\n   is made unconditional.\n\ncommands [bpnumber]\n\n   Specify a list of commands for breakpoint number *bpnumber*.  The\n   commands themselves appear on the following lines.  Type a line\n   containing just ``end`` to terminate the commands. An example:\n\n      (Pdb) commands 1\n      (com) print some_variable\n      (com) end\n      (Pdb)\n\n   To remove all commands from a breakpoint, type commands and follow\n   it immediately with ``end``; that is, give no commands.\n\n   With no *bpnumber* argument, commands refers to the last breakpoint\n   set.\n\n   You can use breakpoint commands to start your program up again.\n   Simply use the continue command, or step, or any other command that\n   resumes execution.\n\n   Specifying any command resuming execution (currently continue,\n   step, next, return, jump, quit and their abbreviations) terminates\n   the command list (as if that command was immediately followed by\n   end). This is because any time you resume execution (even with a\n   simple next or step), you may encounter another breakpoint--which\n   could have its own command list, leading to ambiguities about which\n   list to execute.\n\n   If you use the \'silent\' command in the command list, the usual\n   message about stopping at a breakpoint is not printed.  This may be\n   desirable for breakpoints that are to print a specific message and\n   then continue.  If none of the other commands print anything, you\n   see no sign that the breakpoint was reached.\n\ns(tep)\n\n   Execute the current line, stop at the first possible occasion\n   (either in a function that is called or on the next line in the\n   current function).\n\nn(ext)\n\n   Continue execution until the next line in the current function is\n   reached or it returns.  (The difference between ``next`` and\n   ``step`` is that ``step`` stops inside a called function, while\n   ``next`` executes called functions at (nearly) full speed, only\n   stopping at the next line in the current function.)\n\nunt(il) [lineno]\n\n   Without argument, continue execution until the line with a number\n   greater than the current one is reached.\n\n   With a line number, continue execution until a line with a number\n   greater or equal to that is reached.  In both cases, also stop when\n   the current frame returns.\n\n   Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n   Continue execution until the current function returns.\n\nc(ont(inue))\n\n   Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n   Set the next line that will be executed.  Only available in the\n   bottom-most frame.  This lets you jump back and execute code again,\n   or jump forward to skip code that you don\'t want to run.\n\n   It should be noted that not all jumps are allowed -- for instance\n   it is not possible to jump into the middle of a ``for`` loop or out\n   of a ``finally`` clause.\n\nl(ist) [first[, last]]\n\n   List source code for the current file.  Without arguments, list 11\n   lines around the current line or continue the previous listing.\n   With ``.`` as argument, list 11 lines around the current line.\n   With one argument, list 11 lines around at that line.  With two\n   arguments, list the given range; if the second argument is less\n   than the first, it is interpreted as a count.\n\n   The current line in the current frame is indicated by ``->``.  If\n   an exception is being debugged, the line where the exception was\n   originally raised or propagated is indicated by ``>>``, if it\n   differs from the current line.\n\n   New in version 3.2: The ``>>`` marker.\n\nll | longlist\n\n   List all source code for the current function or frame.\n   Interesting lines are marked as for ``list``.\n\n   New in version 3.2.\n\na(rgs)\n\n   Print the argument list of the current function.\n\np(rint) expression\n\n   Evaluate the *expression* in the current context and print its\n   value.\n\npp expression\n\n   Like the ``print`` command, except the value of the expression is\n   pretty-printed using the ``pprint`` module.\n\nwhatis expression\n\n   Print the type of the *expression*.\n\nsource expression\n\n   Try to get source code for the given object and display it.\n\n   New in version 3.2.\n\ndisplay [expression]\n\n   Display the value of the expression if it changed, each time\n   execution stops in the current frame.\n\n   Without expression, list all display expressions for the current\n   frame.\n\n   New in version 3.2.\n\nundisplay [expression]\n\n   Do not display the expression any more in the current frame.\n   Without expression, clear all display expressions for the current\n   frame.\n\n   New in version 3.2.\n\ninteract\n\n   Start an interative interpreter (using the ``code`` module) whose\n   global namespace contains all the (global and local) names found in\n   the current scope.\n\n   New in version 3.2.\n\nalias [name [command]]\n\n   Create an alias called *name* that executes *command*.  The command\n   must *not* be enclosed in quotes.  Replaceable parameters can be\n   indicated by ``%1``, ``%2``, and so on, while ``%*`` is replaced by\n   all the parameters. If no command is given, the current alias for\n   *name* is shown. If no arguments are given, all aliases are listed.\n\n   Aliases may be nested and can contain anything that can be legally\n   typed at the pdb prompt.  Note that internal pdb commands *can* be\n   overridden by aliases.  Such a command is then hidden until the\n   alias is removed.  Aliasing is recursively applied to the first\n   word of the command line; all other words in the line are left\n   alone.\n\n   As an example, here are two useful aliases (especially when placed\n   in the ``.pdbrc`` file):\n\n      # Print instance variables (usage "pi classInst")\n      alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n      # Print instance variables in self\n      alias ps pi self\n\nunalias name\n\n   Delete the specified alias.\n\n! statement\n\n   Execute the (one-line) *statement* in the context of the current\n   stack frame. The exclamation point can be omitted unless the first\n   word of the statement resembles a debugger command.  To set a\n   global variable, you can prefix the assignment command with a\n   ``global`` statement on the same line, e.g.:\n\n      (Pdb) global list_options; list_options = [\'-l\']\n      (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n   Restart the debugged Python program.  If an argument is supplied,\n   it is split with ``shlex`` and the result is used as the new\n   ``sys.argv``. History, breakpoints, actions and debugger options\n   are preserved. ``restart`` is an alias for ``run``.\n\nq(uit)\n\n   Quit from the debugger.  The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module is\n    determined by the ``__name__`` in the frame globals.\n',
  'del': '\nThe ``del`` statement\n*********************\n\n   del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather that spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block.  If the name is unbound, a\n``NameError`` exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2.\n',
  'dict': '\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n   dict_display       ::= "{" [key_datum_list | dict_comprehension] "}"\n   key_datum_list     ::= key_datum ("," key_datum)* [","]\n   key_datum          ::= expression ":" expression\n   dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum.  This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*.  (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.)  Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n',
  'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name.  An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names.  Names may be resolved in the local\nand global namespaces of the caller.  Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace.  [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace.  If only one namespace is\nspecified, it is used for both.\n',
@@ -33,14 +33,14 @@
  'exprlists': '\nExpression lists\n****************\n\n   expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple.  The\nlength of the tuple is the number of expressions in the list.  The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases.  A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n',
  'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n   floatnumber   ::= pointfloat | exponentfloat\n   pointfloat    ::= [intpart] fraction | intpart "."\n   exponentfloat ::= (intpart | pointfloat) exponent\n   intpart       ::= digit+\n   fraction      ::= "." digit+\n   exponent      ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, ``077e010`` is legal, and denotes the same\nnumber as ``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n   3.14    10.    .001    1e100    3.14e-10    0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n',
  'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n   for_stmt ::= "for" target_list "in" expression_list ":" suite\n                ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject.  An iterator is created for the result of the\n``expression_list``.  The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices.  Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted.  When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop.  Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n  (this can only occur for mutable sequences, i.e. lists).  An\n  internal counter is used to keep track of which item is used next,\n  and this is incremented on each iteration.  When this counter has\n  reached the length of the sequence the loop terminates.  This means\n  that if the suite deletes the current (or a previous) item from the\n  sequence, the next item will be skipped (since it gets the index of\n  the current item which has already been treated).  Likewise, if the\n  suite inserts an item in the sequence before the current item, the\n  current item will be treated again the next time through the loop.\n  This can lead to nasty bugs that can be avoided by making a\n  temporary copy using a slice of the whole sequence, e.g.,\n\n     for x in a[:]:\n         if x < 0: a.remove(x)\n',
- 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output.  If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n      replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n      field_name        ::= arg_name ("." attribute_name | "[" element_index "]")*\n      arg_name          ::= [identifier | integer]\n      attribute_name    ::= identifier\n      element_index     ::= integer | index_string\n      index_string      ::=  +\n      conversion        ::= "r" | "s" | "a"\n      format_spec       ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a  *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``.  These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword.  If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument.  If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n   "First, thou shalt count to {0}" # References first positional argument\n   "Bring me a {}"                  # Implicitly references the first positional argument\n   "From {} to {}"                  # Same as "From {0} to {1}"\n   "My quest is {name}"             # References keyword argument \'name\'\n   "Weight in tons {0.weight}"      # \'weight\' attribute of first positional arg\n   "Units destroyed: {players[0]}"  # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself.  However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting.  By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nThree conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, ``\'!r\'`` which calls ``repr()`` and ``\'!a\'``\nwhich calls ``ascii()``.\n\nSome examples:\n\n   "Harold\'s a clever {0!s}"        # Calls str() on the argument first\n   "Bring out the holy {name!r}"    # Calls repr() on the argument first\n   "More {!a}"                      # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on.  Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed.  The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*).  They can also be passed directly to the\nbuilt-in ``format()`` function.  Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n   format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n   fill        ::= \n   align       ::= "<" | ">" | "=" | "^"\n   sign        ::= "+" | "-" | " "\n   width       ::= integer\n   precision   ::= integer\n   type        ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'{\' or \'}\'.  The\npresence of a fill character is signaled by the character following\nit, which must be one of the alignment options.  If the second\ncharacter of *format_spec* is not a valid alignment option, then it is\nassumed that both the fill character and the alignment option are\nabsent.\n\nThe meaning of the various alignment options is as follows:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'<\'``   | Forces the field to be left-aligned within the available   |\n   |           | space (this is the default).                               |\n   +-----------+------------------------------------------------------------+\n   | ``\'>\'``   | Forces the field to be right-aligned within the available  |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n   | ``\'=\'``   | Forces the padding to be placed after the sign (if any)    |\n   |           | but before the digits.  This is used for printing fields   |\n   |           | in the form \'+000000120\'. This alignment option is only    |\n   |           | valid for numeric types.                                   |\n   +-----------+------------------------------------------------------------+\n   | ``\'^\'``   | Forces the field to be centered within the available       |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'+\'``   | indicates that a sign should be used for both positive as  |\n   |           | well as negative numbers.                                  |\n   +-----------+------------------------------------------------------------+\n   | ``\'-\'``   | indicates that a sign should be used only for negative     |\n   |           | numbers (this is the default behavior).                    |\n   +-----------+------------------------------------------------------------+\n   | space     | indicates that a leading space should be used on positive  |\n   |           | numbers, and a minus sign on negative numbers.             |\n   +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output.  If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 3.1: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width.  If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding.  This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'s\'``   | String format. This is the default type for strings and    |\n   |           | may be omitted.                                            |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as ``\'s\'``.                                       |\n   +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'b\'``   | Binary format. Outputs the number in base 2.               |\n   +-----------+------------------------------------------------------------+\n   | ``\'c\'``   | Character. Converts the integer to the corresponding       |\n   |           | unicode character before printing.                         |\n   +-----------+------------------------------------------------------------+\n   | ``\'d\'``   | Decimal Integer. Outputs the number in base 10.            |\n   +-----------+------------------------------------------------------------+\n   | ``\'o\'``   | Octal format. Outputs the number in base 8.                |\n   +-----------+------------------------------------------------------------+\n   | ``\'x\'``   | Hex format. Outputs the number in base 16, using lower-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'X\'``   | Hex format. Outputs the number in base 16, using upper-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'n\'``   | Number. This is the same as ``\'d\'``, except that it uses   |\n   |           | the current locale setting to insert the appropriate       |\n   |           | number separator characters.                               |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as ``\'d\'``.                                       |\n   +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'e\'``   | Exponent notation. Prints the number in scientific         |\n   |           | notation using the letter \'e\' to indicate the exponent.    |\n   +-----------+------------------------------------------------------------+\n   | ``\'E\'``   | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n   |           | case \'E\' as the separator character.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'f\'``   | Fixed point. Displays the number as a fixed-point number.  |\n   +-----------+------------------------------------------------------------+\n   | ``\'F\'``   | Fixed point. Same as ``\'f\'``, but converts ``nan`` to      |\n   |           | ``NAN`` and ``inf`` to ``INF``.                            |\n   +-----------+------------------------------------------------------------+\n   | ``\'g\'``   | General format.  For a given precision ``p >= 1``, this    |\n   |           | rounds the number to ``p`` significant digits and then     |\n   |           | formats the result in either fixed-point format or in      |\n   |           | scientific notation, depending on its magnitude.  The      |\n   |           | precise rules are as follows: suppose that the result      |\n   |           | formatted with presentation type ``\'e\'`` and precision     |\n   |           | ``p-1`` would have exponent ``exp``.  Then if ``-4 <= exp  |\n   |           | < p``, the number is formatted with presentation type      |\n   |           | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number   |\n   |           | is formatted with presentation type ``\'e\'`` and precision  |\n   |           | ``p-1``. In both cases insignificant trailing zeros are    |\n   |           | removed from the significand, and the decimal point is     |\n   |           | also removed if there are no remaining digits following    |\n   |           | it.  Positive and negative infinity, positive and negative |\n   |           | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n   |           | ``-0`` and ``nan`` respectively, regardless of the         |\n   |           | precision.  A precision of ``0`` is treated as equivalent  |\n   |           | to a precision of ``1``.                                   |\n   +-----------+------------------------------------------------------------+\n   | ``\'G\'``   | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n   |           | if the number gets too large. The representations of       |\n   |           | infinity and NaN are uppercased, too.                      |\n   +-----------+------------------------------------------------------------+\n   | ``\'n\'``   | Number. This is the same as ``\'g\'``, except that it uses   |\n   |           | the current locale setting to insert the appropriate       |\n   |           | number separator characters.                               |\n   +-----------+------------------------------------------------------------+\n   | ``\'%\'``   | Percentage. Multiplies the number by 100 and displays in   |\n   |           | fixed (``\'f\'``) format, followed by a percent sign.        |\n   +-----------+------------------------------------------------------------+\n   | None      | Similar to ``\'g\'``, except with at least one digit past    |\n   |           | the decimal point and a default precision of 12. This is   |\n   |           | intended to match ``str()``, except you can add the other  |\n   |           | format modifiers.                                          |\n   +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n   >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n   \'a, b, c\'\n   >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\')  # 3.1+ only\n   \'a, b, c\'\n   >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n   \'c, b, a\'\n   >>> \'{2}, {1}, {0}\'.format(*\'abc\')      # unpacking argument sequence\n   \'c, b, a\'\n   >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\')   # arguments\' indices can be repeated\n   \'abracadabra\'\n\nAccessing arguments by name:\n\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n   \'Coordinates: 37.24N, -115.81W\'\n   >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n   \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n   >>> c = 3-5j\n   >>> (\'The complex number {0} is formed from the real part {0.real} \'\n   ...  \'and the imaginary part {0.imag}.\').format(c)\n   \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n   >>> class Point:\n   ...     def __init__(self, x, y):\n   ...         self.x, self.y = x, y\n   ...     def __str__(self):\n   ...         return \'Point({self.x}, {self.y})\'.format(self=self)\n   ...\n   >>> str(Point(4, 2))\n   \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n   >>> coord = (3, 5)\n   >>> \'X: {0[0]};  Y: {0[1]}\'.format(coord)\n   \'X: 3;  Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n   >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n   "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n   >>> \'{:<30}\'.format(\'left aligned\')\n   \'left aligned                  \'\n   >>> \'{:>30}\'.format(\'right aligned\')\n   \'                 right aligned\'\n   >>> \'{:^30}\'.format(\'centered\')\n   \'           centered           \'\n   >>> \'{:*^30}\'.format(\'centered\')  # use \'*\' as a fill char\n   \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n   >>> \'{:+f}; {:+f}\'.format(3.14, -3.14)  # show it always\n   \'+3.140000; -3.140000\'\n   >>> \'{: f}; {: f}\'.format(3.14, -3.14)  # show a space for positive numbers\n   \' 3.140000; -3.140000\'\n   >>> \'{:-f}; {:-f}\'.format(3.14, -3.14)  # show only the minus -- same as \'{:f}; {:f}\'\n   \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n   >>> # format also supports binary numbers\n   >>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)\n   \'int: 42;  hex: 2a;  oct: 52;  bin: 101010\'\n   >>> # with 0x, 0o, or 0b as prefix:\n   >>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)\n   \'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n   >>> \'{:,}\'.format(1234567890)\n   \'1,234,567,890\'\n\nExpressing a percentage:\n\n   >>> points = 19\n   >>> total = 22\n   >>> \'Correct answers: {:.2%}.\'.format(points/total)\n   \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n   >>> import datetime\n   >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n   >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n   \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n   >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n   ...     \'{0:{align}{fill}16}\'.format(text, fill=align, align=align)\n   ...\n   \'left<<<<<<<<<<<<\'\n   \'^^^^^center^^^^^\'\n   \'>>>>>>>>>>>right\'\n   >>>\n   >>> octets = [192, 168, 0, 1]\n   >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n   \'C0A80001\'\n   >>> int(_, 16)\n   3232235521\n   >>>\n   >>> width = 5\n   >>> for num in range(5,12):\n   ...     for base in \'dXob\':\n   ...         print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n   ...     print()\n   ...\n       5     5     5   101\n       6     6     6   110\n       7     7     7   111\n       8     8    10  1000\n       9     9    11  1001\n      10     A    12  1010\n      11     B    13  1011\n',
+ 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output.  If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n      replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n      field_name        ::= arg_name ("." attribute_name | "[" element_index "]")*\n      arg_name          ::= [identifier | integer]\n      attribute_name    ::= identifier\n      element_index     ::= integer | index_string\n      index_string      ::=  +\n      conversion        ::= "r" | "s" | "a"\n      format_spec       ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a  *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``.  These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword.  If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument.  If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n   "First, thou shalt count to {0}" # References first positional argument\n   "Bring me a {}"                  # Implicitly references the first positional argument\n   "From {} to {}"                  # Same as "From {0} to {1}"\n   "My quest is {name}"             # References keyword argument \'name\'\n   "Weight in tons {0.weight}"      # \'weight\' attribute of first positional arg\n   "Units destroyed: {players[0]}"  # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself.  However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting.  By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nThree conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, ``\'!r\'`` which calls ``repr()`` and ``\'!a\'``\nwhich calls ``ascii()``.\n\nSome examples:\n\n   "Harold\'s a clever {0!s}"        # Calls str() on the argument first\n   "Bring out the holy {name!r}"    # Calls repr() on the argument first\n   "More {!a}"                      # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on.  Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed.  The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*).  They can also be passed directly to the\nbuilt-in ``format()`` function.  Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n   format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n   fill        ::= \n   align       ::= "<" | ">" | "=" | "^"\n   sign        ::= "+" | "-" | " "\n   width       ::= integer\n   precision   ::= integer\n   type        ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'{\' or \'}\'.  The\npresence of a fill character is signaled by the character following\nit, which must be one of the alignment options.  If the second\ncharacter of *format_spec* is not a valid alignment option, then it is\nassumed that both the fill character and the alignment option are\nabsent.\n\nThe meaning of the various alignment options is as follows:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'<\'``   | Forces the field to be left-aligned within the available   |\n   |           | space (this is the default).                               |\n   +-----------+------------------------------------------------------------+\n   | ``\'>\'``   | Forces the field to be right-aligned within the available  |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n   | ``\'=\'``   | Forces the padding to be placed after the sign (if any)    |\n   |           | but before the digits.  This is used for printing fields   |\n   |           | in the form \'+000000120\'. This alignment option is only    |\n   |           | valid for numeric types.                                   |\n   +-----------+------------------------------------------------------------+\n   | ``\'^\'``   | Forces the field to be centered within the available       |\n   |           | space.                                                     |\n   +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n   +-----------+------------------------------------------------------------+\n   | Option    | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'+\'``   | indicates that a sign should be used for both positive as  |\n   |           | well as negative numbers.                                  |\n   +-----------+------------------------------------------------------------+\n   | ``\'-\'``   | indicates that a sign should be used only for negative     |\n   |           | numbers (this is the default behavior).                    |\n   +-----------+------------------------------------------------------------+\n   | space     | indicates that a leading space should be used on positive  |\n   |           | numbers, and a minus sign on negative numbers.             |\n   +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option causes the "alternate form" to be used for the\nconversion.  The alternate form is defined differently for different\ntypes.  This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective ``\'0b\'``, ``\'0o\'``, or\n``\'0x\'`` to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for ``\'g\'`` and ``\'G\'``\nconversions, trailing zeros are not removed from the result.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 3.1: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width.  If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding.  This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'s\'``   | String format. This is the default type for strings and    |\n   |           | may be omitted.                                            |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as ``\'s\'``.                                       |\n   +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'b\'``   | Binary format. Outputs the number in base 2.               |\n   +-----------+------------------------------------------------------------+\n   | ``\'c\'``   | Character. Converts the integer to the corresponding       |\n   |           | unicode character before printing.                         |\n   +-----------+------------------------------------------------------------+\n   | ``\'d\'``   | Decimal Integer. Outputs the number in base 10.            |\n   +-----------+------------------------------------------------------------+\n   | ``\'o\'``   | Octal format. Outputs the number in base 8.                |\n   +-----------+------------------------------------------------------------+\n   | ``\'x\'``   | Hex format. Outputs the number in base 16, using lower-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'X\'``   | Hex format. Outputs the number in base 16, using upper-    |\n   |           | case letters for the digits above 9.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'n\'``   | Number. This is the same as ``\'d\'``, except that it uses   |\n   |           | the current locale setting to insert the appropriate       |\n   |           | number separator characters.                               |\n   +-----------+------------------------------------------------------------+\n   | None      | The same as ``\'d\'``.                                       |\n   +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n   +-----------+------------------------------------------------------------+\n   | Type      | Meaning                                                    |\n   +===========+============================================================+\n   | ``\'e\'``   | Exponent notation. Prints the number in scientific         |\n   |           | notation using the letter \'e\' to indicate the exponent.    |\n   +-----------+------------------------------------------------------------+\n   | ``\'E\'``   | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n   |           | case \'E\' as the separator character.                       |\n   +-----------+------------------------------------------------------------+\n   | ``\'f\'``   | Fixed point. Displays the number as a fixed-point number.  |\n   +-----------+------------------------------------------------------------+\n   | ``\'F\'``   | Fixed point. Same as ``\'f\'``, but converts ``nan`` to      |\n   |           | ``NAN`` and ``inf`` to ``INF``.                            |\n   +-----------+------------------------------------------------------------+\n   | ``\'g\'``   | General format.  For a given precision ``p >= 1``, this    |\n   |           | rounds the number to ``p`` significant digits and then     |\n   |           | formats the result in either fixed-point format or in      |\n   |           | scientific notation, depending on its magnitude.  The      |\n   |           | precise rules are as follows: suppose that the result      |\n   |           | formatted with presentation type ``\'e\'`` and precision     |\n   |           | ``p-1`` would have exponent ``exp``.  Then if ``-4 <= exp  |\n   |           | < p``, the number is formatted with presentation type      |\n   |           | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number   |\n   |           | is formatted with presentation type ``\'e\'`` and precision  |\n   |           | ``p-1``. In both cases insignificant trailing zeros are    |\n   |           | removed from the significand, and the decimal point is     |\n   |           | also removed if there are no remaining digits following    |\n   |           | it.  Positive and negative infinity, positive and negative |\n   |           | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n   |           | ``-0`` and ``nan`` respectively, regardless of the         |\n   |           | precision.  A precision of ``0`` is treated as equivalent  |\n   |           | to a precision of ``1``.                                   |\n   +-----------+------------------------------------------------------------+\n   | ``\'G\'``   | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n   |           | if the number gets too large. The representations of       |\n   |           | infinity and NaN are uppercased, too.                      |\n   +-----------+------------------------------------------------------------+\n   | ``\'n\'``   | Number. This is the same as ``\'g\'``, except that it uses   |\n   |           | the current locale setting to insert the appropriate       |\n   |           | number separator characters.                               |\n   +-----------+------------------------------------------------------------+\n   | ``\'%\'``   | Percentage. Multiplies the number by 100 and displays in   |\n   |           | fixed (``\'f\'``) format, followed by a percent sign.        |\n   +-----------+------------------------------------------------------------+\n   | None      | Similar to ``\'g\'``, except with at least one digit past    |\n   |           | the decimal point and a default precision of 12. This is   |\n   |           | intended to match ``str()``, except you can add the other  |\n   |           | format modifiers.                                          |\n   +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n   >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n   \'a, b, c\'\n   >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\')  # 3.1+ only\n   \'a, b, c\'\n   >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n   \'c, b, a\'\n   >>> \'{2}, {1}, {0}\'.format(*\'abc\')      # unpacking argument sequence\n   \'c, b, a\'\n   >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\')   # arguments\' indices can be repeated\n   \'abracadabra\'\n\nAccessing arguments by name:\n\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n   \'Coordinates: 37.24N, -115.81W\'\n   >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n   >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n   \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n   >>> c = 3-5j\n   >>> (\'The complex number {0} is formed from the real part {0.real} \'\n   ...  \'and the imaginary part {0.imag}.\').format(c)\n   \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n   >>> class Point:\n   ...     def __init__(self, x, y):\n   ...         self.x, self.y = x, y\n   ...     def __str__(self):\n   ...         return \'Point({self.x}, {self.y})\'.format(self=self)\n   ...\n   >>> str(Point(4, 2))\n   \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n   >>> coord = (3, 5)\n   >>> \'X: {0[0]};  Y: {0[1]}\'.format(coord)\n   \'X: 3;  Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n   >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n   "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n   >>> \'{:<30}\'.format(\'left aligned\')\n   \'left aligned                  \'\n   >>> \'{:>30}\'.format(\'right aligned\')\n   \'                 right aligned\'\n   >>> \'{:^30}\'.format(\'centered\')\n   \'           centered           \'\n   >>> \'{:*^30}\'.format(\'centered\')  # use \'*\' as a fill char\n   \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n   >>> \'{:+f}; {:+f}\'.format(3.14, -3.14)  # show it always\n   \'+3.140000; -3.140000\'\n   >>> \'{: f}; {: f}\'.format(3.14, -3.14)  # show a space for positive numbers\n   \' 3.140000; -3.140000\'\n   >>> \'{:-f}; {:-f}\'.format(3.14, -3.14)  # show only the minus -- same as \'{:f}; {:f}\'\n   \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n   >>> # format also supports binary numbers\n   >>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)\n   \'int: 42;  hex: 2a;  oct: 52;  bin: 101010\'\n   >>> # with 0x, 0o, or 0b as prefix:\n   >>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)\n   \'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n   >>> \'{:,}\'.format(1234567890)\n   \'1,234,567,890\'\n\nExpressing a percentage:\n\n   >>> points = 19\n   >>> total = 22\n   >>> \'Correct answers: {:.2%}.\'.format(points/total)\n   \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n   >>> import datetime\n   >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n   >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n   \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n   >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n   ...     \'{0:{align}{fill}16}\'.format(text, fill=align, align=align)\n   ...\n   \'left<<<<<<<<<<<<\'\n   \'^^^^^center^^^^^\'\n   \'>>>>>>>>>>>right\'\n   >>>\n   >>> octets = [192, 168, 0, 1]\n   >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n   \'C0A80001\'\n   >>> int(_, 16)\n   3232235521\n   >>>\n   >>> width = 5\n   >>> for num in range(5,12):\n   ...     for base in \'dXob\':\n   ...         print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n   ...     print()\n   ...\n       5     5     5   101\n       6     6     6   110\n       7     7     7   111\n       8     8    10  1000\n       9     9    11  1001\n      10     A    12  1010\n      11     B    13  1011\n',
  'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n   funcdef        ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n   decorators     ::= decorator+\n   decorator      ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n   dotted_name    ::= identifier ("." identifier)*\n   parameter_list ::= (defparameter ",")*\n                      (  "*" [parameter] ("," defparameter)*\n                      [, "**" parameter]\n                      | "**" parameter\n                      | defparameter [","] )\n   parameter      ::= identifier [":" expression]\n   defparameter   ::= parameter ["=" expression]\n   funcname       ::= identifier\n\nA function definition is an executable statement.  Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function).  This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition.  The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object.  Multiple decorators are applied in\nnested fashion. For example, the following code\n\n   @f1(arg)\n   @f2\n   def func(): pass\n\nis equivalent to\n\n   def func(): pass\n   func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted.  If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call.  This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended.  A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n   def whats_on_the_telly(penguin=None):\n       if penguin is None:\n           penguin = []\n       penguin.append("property of the zoo")\n       return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values.  If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple.  If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name.  Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``.  Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list.  These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code.  The presence of annotations does not change the\nsemantics of a function.  The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions.  This uses lambda forms,\ndescribed in section *Lambdas*.  Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form.  The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects.  A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around.  Free variables used in the\nnested function can access the local variables of the function\ncontaining the def.  See section *Naming and binding* for details.\n',
  'global': '\nThe ``global`` statement\n************************\n\n   global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block.  It means that the listed identifiers are to be\ninterpreted as globals.  It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in a string\nor code object supplied to the built-in ``exec()`` function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by ``global`` statements in\nthe code containing the function call.  The same applies to the\n``eval()`` and ``compile()`` functions.\n',
  'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings.  These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n   Not imported by ``from module import *``.  The special identifier\n   ``_`` is used in the interactive interpreter to store the result of\n   the last evaluation; it is stored in the ``builtins`` module.  When\n   not in interactive mode, ``_`` has no special meaning and is not\n   defined. See section *The import statement*.\n\n   Note: The name ``_`` is often used in conjunction with\n     internationalization; refer to the documentation for the\n     ``gettext`` module for more information on this convention.\n\n``__*__``\n   System-defined names. These names are defined by the interpreter\n   and its implementation (including the standard library).  Current\n   system names are discussed in the *Special method names* section\n   and elsewhere.  More will likely be defined in future versions of\n   Python.  *Any* use of ``__*__`` names, in any context, that does\n   not follow explicitly documented use, is subject to breakage\n   without warning.\n\n``__*``\n   Class-private names.  Names in this category, when used within the\n   context of a class definition, are re-written to use a mangled form\n   to help avoid name clashes between "private" attributes of base and\n   derived classes. See section *Identifiers (Names)*.\n',
  'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**).  For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length.  Case is significant.\n\n   identifier  ::= id_start id_continue*\n   id_start    ::= \n   id_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\nAll identifiers are converted into the normal form NFC while parsing;\ncomparison of identifiers is based on NFC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers.  They must\nbe spelled exactly as written here:\n\n   False      class      finally    is         return\n   None       continue   for        lambda     try\n   True       def        from       nonlocal   while\n   and        del        global     not        with\n   as         elif       if         or         yield\n   assert     else       import     pass\n   break      except     in         raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings.  These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n   Not imported by ``from module import *``.  The special identifier\n   ``_`` is used in the interactive interpreter to store the result of\n   the last evaluation; it is stored in the ``builtins`` module.  When\n   not in interactive mode, ``_`` has no special meaning and is not\n   defined. See section *The import statement*.\n\n   Note: The name ``_`` is often used in conjunction with\n     internationalization; refer to the documentation for the\n     ``gettext`` module for more information on this convention.\n\n``__*__``\n   System-defined names. These names are defined by the interpreter\n   and its implementation (including the standard library).  Current\n   system names are discussed in the *Special method names* section\n   and elsewhere.  More will likely be defined in future versions of\n   Python.  *Any* use of ``__*__`` names, in any context, that does\n   not follow explicitly documented use, is subject to breakage\n   without warning.\n\n``__*``\n   Class-private names.  Names in this category, when used within the\n   context of a class definition, are re-written to use a mangled form\n   to help avoid name clashes between "private" attributes of base and\n   derived classes. See section *Identifiers (Names)*.\n',
  'if': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n   if_stmt ::= "if" expression ":" suite\n               ( "elif" expression ":" suite )*\n               ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n',
  'imaginary': '\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n   imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range.  To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``.  Some examples of imaginary literals:\n\n   3.14j   10.j    10j     .001j   1e100j  3.14e-10j\n',
- 'import': '\nThe ``import`` statement\n************************\n\n   import_stmt     ::= "import" module ["as" name] ( "," module ["as" name] )*\n                   | "from" relative_module "import" identifier ["as" name]\n                   ( "," identifier ["as" name] )*\n                   | "from" relative_module "import" "(" identifier ["as" name]\n                   ( "," identifier ["as" name] )* [","] ")"\n                   | "from" module "import" "*"\n   module          ::= (identifier ".")* identifier\n   relative_module ::= "."* module | "."+\n   name            ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly. For a reference\nimplementation of step (1), see the ``importlib`` module.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import unless ``None`` is found in ``sys.modules``, in which case\n``ImportError`` is raised.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any.  If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound.  As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname".  If a name is not\nfound, ``ImportError`` is raised.  If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module.  The names given in ``__all__`` are all considered public\nand are required to exist.  If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope.  The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python.  The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language.  It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n   future_statement ::= "from" "__future__" "import" feature ["as" name]\n                        ("," feature ["as" name])*\n                        | "from" "__future__" "import" "(" feature ["as" name]\n                        ("," feature ["as" name])* [","] ")"\n   feature          ::= identifier\n   name             ::= identifier\n\nA future statement must appear near the top of the module.  The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``.  They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code.  It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently.  Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n   import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement.  This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session.  If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n   **PEP 236** - Back to the __future__\n      The original proposal for the __future__ mechanism.\n',
+ 'import': '\nThe ``import`` statement\n************************\n\n   import_stmt     ::= "import" module ["as" name] ( "," module ["as" name] )*\n                   | "from" relative_module "import" identifier ["as" name]\n                   ( "," identifier ["as" name] )*\n                   | "from" relative_module "import" "(" identifier ["as" name]\n                   ( "," identifier ["as" name] )* [","] ")"\n                   | "from" module "import" "*"\n   module          ::= (identifier ".")* identifier\n   relative_module ::= "."* module | "."+\n   name            ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly. For a reference\nimplementation of step (1), see the ``importlib`` module.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import unless ``None`` is found in ``sys.modules``, in which case\n``ImportError`` is raised.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any.  If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound.  As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname".  If a name is not\nfound, ``ImportError`` is raised.  If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module.  The names given in ``__all__`` are all considered public\nand are required to exist.  If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope.  The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python.  The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language.  It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n   future_statement ::= "from" "__future__" "import" feature ["as" name]\n                        ("," feature ["as" name])*\n                        | "from" "__future__" "import" "(" feature ["as" name]\n                        ("," feature ["as" name])* [","] ")"\n   feature          ::= identifier\n   name             ::= identifier\n\nA future statement must appear near the top of the module.  The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``.  They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code.  It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently.  Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n   import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement.  This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session.  If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n   **PEP 236** - Back to the __future__\n      The original proposal for the __future__ mechanism.\n',
  'in': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation.  Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n   comparison    ::= or_expr ( comp_operator or_expr )*\n   comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n                     | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects.  The objects need not have the same type.\nIf both are numbers, they are converted to a common type.  Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes.  You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n  are identical to themselves, ``x is x`` but are not equal to\n  themselves, ``x != x``.  Additionally, comparing any value to a\n  not-a-number value will return ``False``.  For example, both ``3 <\n  float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n  values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n  (the result of the built-in function ``ord()``) of their characters.\n  [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n  corresponding elements.  This means that to compare equal, each\n  element must compare equal and the two sequences must be of the same\n  type and have the same length.\n\n  If not equal, the sequences are ordered the same as their first\n  differing elements.  For example, ``[1,2,x] <= [1,2,y]`` has the\n  same value as ``x <= y``.  If the corresponding element does not\n  exist, the shorter sequence is ordered first (for example, ``[1,2] <\n  [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n  same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n  \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n  superset tests.  Those relations do not define total orderings (the\n  two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n  another, nor supersets of one another).  Accordingly, sets are not\n  appropriate arguments for functions which depend on total ordering.\n  For example, ``min()``, ``max()``, and ``sorted()`` produce\n  undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n  the same object; the choice whether one object is considered smaller\n  or larger than another one is made arbitrarily but consistently\n  within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison.  Most\nnumeric types can be compared with one another, but comparisons of\n``float`` and ``Decimal`` are not supported to avoid the inevitable\nconfusion arising from representation issues such as ``float(\'1.1\')``\nbeing inexactly represented and therefore not exactly equal to\n``Decimal(\'1.1\')`` which is.  When cross-type comparison is not\nsupported, the comparison method returns ``NotImplemented``.  This can\ncreate the illusion of non-transitivity between supported cross-type\ncomparisons and unsupported comparisons.  For example, ``Decimal(2) ==\n2`` and ``2 == float(2)`` but ``Decimal(2) != float(2)``.\n\nThe operators ``in`` and ``not in`` test for membership.  ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise.  ``x\nnot in s`` returns the negation of ``x in s``.  All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*.  An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``.  If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception.  (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object.  ``x is\nnot y`` yields the inverse truth value. [4]\n',
  'integers': '\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n   integer        ::= decimalinteger | octinteger | hexinteger | bininteger\n   decimalinteger ::= nonzerodigit digit* | "0"+\n   nonzerodigit   ::= "1"..."9"\n   digit          ::= "0"..."9"\n   octinteger     ::= "0" ("o" | "O") octdigit+\n   hexinteger     ::= "0" ("x" | "X") hexdigit+\n   bininteger     ::= "0" ("b" | "B") bindigit+\n   octdigit       ::= "0"..."7"\n   hexdigit       ::= digit | "a"..."f" | "A"..."F"\n   bindigit       ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n   7     2147483647                        0o177    0b100110111\n   3     79228162514264337593543950336     0o377    0x100000000\n         79228162514264337593543950336              0xdeadbeef\n',
  'lambda': '\nLambdas\n*******\n\n   lambda_form        ::= "lambda" [parameter_list]: expression\n   lambda_form_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda forms (lambda expressions) have the same syntactic position as\nexpressions.  They are a shorthand to create anonymous functions; the\nexpression ``lambda arguments: expression`` yields a function object.\nThe unnamed object behaves like a function object defined with\n\n   def (arguments):\n       return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda forms cannot contain\nstatements or annotations.\n',
@@ -50,7 +50,7 @@
  'numbers': "\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers.  There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n",
  'numeric-types': "\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``).  For instance, to evaluate the expression ``x + y``, where\n   *x* is an instance of a class that has an ``__add__()`` method,\n   ``x.__add__(y)`` is called.  The ``__divmod__()`` method should be\n   the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n   should not be related to ``__truediv__()``.  Note that\n   ``__pow__()`` should be defined to accept an optional third\n   argument if the ternary version of the built-in ``pow()`` function\n   is to be supported.\n\n   If one of those methods does not support the operation with the\n   supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``) with reflected (swapped) operands. These functions are only\n   called if the left operand does not support the corresponding\n   operation and the operands are of different types. [2]  For\n   instance, to evaluate the expression ``x - y``, where *y* is an\n   instance of a class that has an ``__rsub__()`` method,\n   ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n   *NotImplemented*.\n\n   Note that ternary ``pow()`` will not try calling ``__rpow__()``\n   (the coercion rules would become too complicated).\n\n   Note: If the right operand's type is a subclass of the left operand's\n     type and that subclass provides the reflected method for the\n     operation, this method will be called before the left operand's\n     non-reflected method.  This behavior allows subclasses to\n     override their ancestors' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n   These methods are called to implement the augmented arithmetic\n   assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n   ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``).  These methods\n   should attempt to do the operation in-place (modifying *self*) and\n   return the result (which could be, but does not have to be,\n   *self*).  If a specific method is not defined, the augmented\n   assignment falls back to the normal methods.  For instance, to\n   execute the statement ``x += y``, where *x* is an instance of a\n   class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n   called.  If *x* is an instance of a class that does not define a\n   ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n   considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n   Called to implement the unary arithmetic operations (``-``, ``+``,\n   ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n   Called to implement the built-in functions ``complex()``,\n   ``int()``, ``float()`` and ``round()``.  Should return a value of\n   the appropriate type.\n\nobject.__index__(self)\n\n   Called to implement ``operator.index()``.  Also called whenever\n   Python needs an integer object (such as in slicing, or in the\n   built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n   an integer.\n",
  'objects': '\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data.  All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value.  An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory.  The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype.  The ``type()`` function returns an object\'s type (which is an\nobject itself).  The *value* of some objects can change.  Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed.  So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected.  An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references.  See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change.\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows.  It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects.  The\n\'``try``...``finally``\' statement and the \'``with``\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries.  The references are part of a container\'s value.  In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied.  So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior.  Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed.  E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n',
- 'operator-summary': '\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding).  Operators in the same box have the same precedence.  Unless\nthe syntax is explicitly given, operators are binary.  Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator                                        | Description                           |\n+=================================================+=======================================+\n| ``lambda``                                      | Lambda expression                     |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else``                              | Conditional expression                |\n+-------------------------------------------------+---------------------------------------+\n| ``or``                                          | Boolean OR                            |\n+-------------------------------------------------+---------------------------------------+\n| ``and``                                         | Boolean AND                           |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x*                                     | Boolean NOT                           |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``,     | Comparisons, including membership     |\n| ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``==``    | tests and identity tests,             |\n+-------------------------------------------------+---------------------------------------+\n| ``|``                                           | Bitwise OR                            |\n+-------------------------------------------------+---------------------------------------+\n| ``^``                                           | Bitwise XOR                           |\n+-------------------------------------------------+---------------------------------------+\n| ``&``                                           | Bitwise AND                           |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>``                                  | Shifts                                |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-``                                    | Addition and subtraction              |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%``                     | Multiplication, division, remainder   |\n|                                                 | [5]                                   |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x``                          | Positive, negative, bitwise NOT       |\n+-------------------------------------------------+---------------------------------------+\n| ``**``                                          | Exponentiation [6]                    |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``,               | Subscription, slicing, call,          |\n| ``x(arguments...)``, ``x.attribute``            | attribute reference                   |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``,     | Binding or tuple display, list        |\n| ``{key:datum...}``,                             | display, dictionary display,          |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n    may not be true numerically due to roundoff.  For example, and\n    assuming a platform on which a Python float is an IEEE 754 double-\n    precision number, in order that ``-1e-100 % 1e100`` have the same\n    sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n    which is numerically exactly equal to ``1e100``.  Function\n    ``fmod()`` in the ``math`` module returns a result whose sign\n    matches the sign of the first argument instead, and so returns\n    ``-1e-100`` in this case. Which approach is more appropriate\n    depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n    possible for ``x//y`` to be one larger than ``(x-x%y)//y`` due to\n    rounding.  In such cases, Python returns the latter result, in\n    order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n    close to ``x``.\n\n[3] While comparisons between strings make sense at the byte level,\n    they may be counter-intuitive to users.  For example, the strings\n    ``"\\u00C7"`` and ``"\\u0327\\u0043"`` compare differently, even\n    though they both represent the same unicode character (LATIN\n    CAPITAL LETTER C WITH CEDILLA).  To compare strings in a human\n    recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] Due to automatic garbage-collection, free lists, and the dynamic\n    nature of descriptors, you may notice seemingly unusual behaviour\n    in certain uses of the ``is`` operator, like those involving\n    comparisons between instance methods, or constants.  Check their\n    documentation for more info.\n\n[5] The ``%`` is also used for string formatting; the same precedence\n    applies.\n\n[6] The power operator ``**`` binds less tightly than an arithmetic or\n    bitwise unary operator on its right, that is, ``2**-1`` is\n    ``0.5``.\n',
+ 'operator-summary': '\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding).  Operators in the same box have the same precedence.  Unless\nthe syntax is explicitly given, operators are binary.  Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator                                        | Description                           |\n+=================================================+=======================================+\n| ``lambda``                                      | Lambda expression                     |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else``                              | Conditional expression                |\n+-------------------------------------------------+---------------------------------------+\n| ``or``                                          | Boolean OR                            |\n+-------------------------------------------------+---------------------------------------+\n| ``and``                                         | Boolean AND                           |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x*                                     | Boolean NOT                           |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``,     | Comparisons, including membership     |\n| ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``==``    | tests and identity tests,             |\n+-------------------------------------------------+---------------------------------------+\n| ``|``                                           | Bitwise OR                            |\n+-------------------------------------------------+---------------------------------------+\n| ``^``                                           | Bitwise XOR                           |\n+-------------------------------------------------+---------------------------------------+\n| ``&``                                           | Bitwise AND                           |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>``                                  | Shifts                                |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-``                                    | Addition and subtraction              |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%``                     | Multiplication, division, remainder   |\n|                                                 | [5]                                   |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x``                          | Positive, negative, bitwise NOT       |\n+-------------------------------------------------+---------------------------------------+\n| ``**``                                          | Exponentiation [6]                    |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``,               | Subscription, slicing, call,          |\n| ``x(arguments...)``, ``x.attribute``            | attribute reference                   |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``,     | Binding or tuple display, list        |\n| ``{key:datum...}``, ``{expressions...}``        | display, dictionary display, set      |\n|                                                 | display                               |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n    may not be true numerically due to roundoff.  For example, and\n    assuming a platform on which a Python float is an IEEE 754 double-\n    precision number, in order that ``-1e-100 % 1e100`` have the same\n    sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n    which is numerically exactly equal to ``1e100``.  The function\n    ``math.fmod()`` returns a result whose sign matches the sign of\n    the first argument instead, and so returns ``-1e-100`` in this\n    case. Which approach is more appropriate depends on the\n    application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n    possible for ``x//y`` to be one larger than ``(x-x%y)//y`` due to\n    rounding.  In such cases, Python returns the latter result, in\n    order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n    close to ``x``.\n\n[3] While comparisons between strings make sense at the byte level,\n    they may be counter-intuitive to users.  For example, the strings\n    ``"\\u00C7"`` and ``"\\u0327\\u0043"`` compare differently, even\n    though they both represent the same unicode character (LATIN\n    CAPITAL LETTER C WITH CEDILLA).  To compare strings in a human\n    recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] Due to automatic garbage-collection, free lists, and the dynamic\n    nature of descriptors, you may notice seemingly unusual behaviour\n    in certain uses of the ``is`` operator, like those involving\n    comparisons between instance methods, or constants.  Check their\n    documentation for more info.\n\n[5] The ``%`` operator is also used for string formatting; the same\n    precedence applies.\n\n[6] The power operator ``**`` binds less tightly than an arithmetic or\n    bitwise unary operator on its right, that is, ``2**-1`` is\n    ``0.5``.\n',
  'pass': '\nThe ``pass`` statement\n**********************\n\n   pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n   def f(arg): pass    # a function that does nothing (yet)\n\n   class C: pass       # a class with no methods (yet)\n',
  'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right.  The\nsyntax is:\n\n   power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument.  The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n``10**2`` returns ``100``, but ``10**-2`` returns ``0.01``.\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``complex`` number. (In earlier versions it raised a\n``ValueError``.)\n',
  'raise': '\nThe ``raise`` statement\n***********************\n\n   raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope.  If no exception is active in\nthe current scope, a ``TypeError`` exception is raised indicating that\nthis is an error (if running under IDLE, a ``queue.Empty`` exception\nis raised instead).\n\nOtherwise, ``raise`` evaluates the first expression as the exception\nobject.  It must be either a subclass or an instance of\n``BaseException``. If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the ``__traceback__`` attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the ``with_traceback()`` exception method (which\nreturns the same exception instance, with its traceback set to its\nargument), like so:\n\n   raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe ``from`` clause is used for exception chaining: if given, the\nsecond *expression* must be another exception class or instance, which\nwill then be attached to the raised exception as the ``__cause__``\nattribute (which is writable).  If the raised exception is not\nhandled, both exceptions will be printed:\n\n   >>> try:\n   ...     print(1 / 0)\n   ... except Exception as exc:\n   ...     raise RuntimeError("Something bad happened") from exc\n   ...\n   Traceback (most recent call last):\n     File "", line 2, in \n   ZeroDivisionError: int division or modulo by zero\n\n   The above exception was the direct cause of the following exception:\n\n   Traceback (most recent call last):\n     File "", line 4, in \n   RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler: the previous exception is then attached as the\nnew exception\'s ``__context__`` attribute:\n\n   >>> try:\n   ...     print(1 / 0)\n   ... except:\n   ...     raise RuntimeError("Something bad happened")\n   ...\n   Traceback (most recent call last):\n     File "", line 2, in \n   ZeroDivisionError: int division or modulo by zero\n\n   During handling of the above exception, another exception occurred:\n\n   Traceback (most recent call last):\n     File "", line 4, in \n   RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n',
@@ -59,8 +59,8 @@
  'shifting': '\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n   shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments.  They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by ``pow(2,n)``.  A\nleft shift by *n* bits is defined as multiplication with ``pow(2,n)``.\n\nNote: In the current implementation, the right-hand operand is required to\n  be at most ``sys.maxsize``.  If the right-hand operand is larger\n  than ``sys.maxsize`` an ``OverflowError`` exception is raised.\n',
  'slicings': '\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list).  Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements.  The syntax for a\nslicing:\n\n   slicing      ::= primary "[" slice_list "]"\n   slice_list   ::= slice_item ("," slice_item)* [","]\n   slice_item   ::= expression | proper_slice\n   proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n   lower_bound  ::= expression\n   upper_bound  ::= expression\n   stride       ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing.  Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows.  The primary must evaluate\nto a mapping object, and it is indexed (using the same\n``__getitem__()`` method as normal subscription) with a key that is\nconstructed from the slice list, as follows.  If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key.  The conversion of a slice item that is an\nexpression is that expression.  The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n``start``, ``stop`` and ``step`` attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n',
  'specialattrs': "\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant.  Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n   A dictionary or other mapping object used to store an object's\n   (writable) attributes.\n\ninstance.__class__\n\n   The class to which a class instance belongs.\n\nclass.__bases__\n\n   The tuple of base classes of a class object.\n\nclass.__name__\n\n   The name of the class or type.\n\nThe following attributes are only supported by *new-style class*es.\n\nclass.__mro__\n\n   This attribute is a tuple of classes that are considered when\n   looking for base classes during method resolution.\n\nclass.mro()\n\n   This method can be overridden by a metaclass to customize the\n   method resolution order for its instances.  It is called at class\n   instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n   Each new-style class keeps a list of weak references to its\n   immediate subclasses.  This method returns a list of all those\n   references still alive. Example:\n\n      >>> int.__subclasses__()\n      []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n    the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n    ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n    operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n    tuple whose only element is the tuple to be formatted.\n",
- 'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators.  For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x,\ni)``.  Except where mentioned, attempts to execute an operation raise\nan exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled.  For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense.  (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  ``__new__()`` is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of ``__new__()`` should be the new object instance (usually\n   an instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s ``__new__()`` method using\n   ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If ``__new__()`` returns an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will be invoked like\n   ``__init__(self[, ...])``, where *self* is the new instance and the\n   remaining arguments are the same as were passed to ``__new__()``.\n\n   If ``__new__()`` does not return an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will not be invoked.\n\n   ``__new__()`` is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called when the instance is created.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   ``__init__()`` method, the derived class\'s ``__init__()`` method,\n   if any, must explicitly call it to ensure proper initialization of\n   the base class part of the instance; for example:\n   ``BaseClass.__init__(self, [args...])``.  As a special constraint\n   on constructors, no value may be returned; doing so will cause a\n   ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a ``__del__()`` method,\n   the derived class\'s ``__del__()`` method, if any, must explicitly\n   call it to ensure proper deletion of the base class part of the\n   instance.  Note that it is possible (though not recommended!) for\n   the ``__del__()`` method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   ``__del__()`` methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n     decrements the reference count for ``x`` by one, and the latter\n     is only called when ``x``\'s reference count reaches zero.  Some\n     common situations that may prevent the reference count of an\n     object from going to zero include: circular references between\n     objects (e.g., a doubly-linked list or a tree data structure with\n     parent and child pointers); a reference to the object on the\n     stack frame of a function that caught an exception (the traceback\n     stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n     a reference to the object on the stack frame that raised an\n     unhandled exception in interactive mode (the traceback stored in\n     ``sys.last_traceback`` keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the latter two situations can be resolved by storing ``None`` in\n     ``sys.last_traceback``. Circular references which are garbage are\n     detected when the option cycle detector is enabled (it\'s on by\n     default), but can only be cleaned up if there are no Python-\n     level ``__del__()`` methods involved. Refer to the documentation\n     for the ``gc`` module for more information about how\n     ``__del__()`` methods are handled by the cycle detector,\n     particularly the description of the ``garbage`` value.\n\n   Warning: Due to the precarious circumstances under which ``__del__()``\n     methods are invoked, exceptions that occur during their execution\n     are ignored, and a warning is printed to ``sys.stderr`` instead.\n     Also, when ``__del__()`` is invoked in response to a module being\n     deleted (e.g., when execution of the program is done), other\n     globals referenced by the ``__del__()`` method may already have\n     been deleted or in the process of being torn down (e.g. the\n     import machinery shutting down).  For this reason, ``__del__()``\n     methods should do the absolute minimum needed to maintain\n     external invariants.  Starting with version 1.5, Python\n     guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n   Called by the ``repr()`` built-in function to compute the\n   "official" string representation of an object.  If at all possible,\n   this should look like a valid Python expression that could be used\n   to recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   ``<...some useful description...>`` should be returned. The return\n   value must be a string object. If a class defines ``__repr__()``\n   but not ``__str__()``, then ``__repr__()`` is also used when an\n   "informal" string representation of instances of that class is\n   required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by the ``str()`` built-in function and by the ``print()``\n   function to compute the "informal" string representation of an\n   object.  This differs from ``__repr__()`` in that it does not have\n   to be a valid Python expression: a more convenient or concise\n   representation may be used instead. The return value must be a\n   string object.\n\nobject.__format__(self, format_spec)\n\n   Called by the ``format()`` built-in function (and by extension, the\n   ``format()`` method of class ``str``) to produce a "formatted"\n   string representation of an object. The ``format_spec`` argument is\n   a string that contains a description of the formatting options\n   desired. The interpretation of the ``format_spec`` argument is up\n   to the type implementing ``__format__()``, however most classes\n   will either delegate formatting to one of the built-in types, or\n   use a similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n   ``x.__ge__(y)``.\n\n   A rich comparison method may return the singleton\n   ``NotImplemented`` if it does not implement the operation for a\n   given pair of arguments. By convention, ``False`` and ``True`` are\n   returned for a successful comparison. However, these methods can\n   return any value, so if the comparison operator is used in a\n   Boolean context (e.g., in the condition of an ``if`` statement),\n   Python will call ``bool()`` on the value to determine if the result\n   is true or false.\n\n   There are no implied relationships among the comparison operators.\n   The truth of ``x==y`` does not imply that ``x!=y`` is false.\n   Accordingly, when defining ``__eq__()``, one should also define\n   ``__ne__()`` so that the operators will behave as expected.  See\n   the paragraph on ``__hash__()`` for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n   other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n   reflection, and ``__eq__()`` and ``__ne__()`` are their own\n   reflection.\n\n   Arguments to rich comparison methods are never coerced.\n\n   To automatically generate ordering operations from a single root\n   operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n   Called by built-in function ``hash()`` and for operations on\n   members of hashed collections including ``set``, ``frozenset``, and\n   ``dict``.  ``__hash__()`` should return an integer.  The only\n   required property is that objects which compare equal have the same\n   hash value; it is advised to somehow mix together (e.g. using\n   exclusive or) the hash values for the components of the object that\n   also play a part in comparison of objects.\n\n   If a class does not define an ``__eq__()`` method it should not\n   define a ``__hash__()`` operation either; if it defines\n   ``__eq__()`` but not ``__hash__()``, its instances will not be\n   usable as items in hashable collections.  If a class defines\n   mutable objects and implements an ``__eq__()`` method, it should\n   not implement ``__hash__()``, since the implementation of hashable\n   collections requires that a key\'s hash value is immutable (if the\n   object\'s hash value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n   by default; with them, all objects compare unequal (except with\n   themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n   Classes which inherit a ``__hash__()`` method from a parent class\n   but change the meaning of ``__eq__()`` such that the hash value\n   returned is no longer appropriate (e.g. by switching to a value-\n   based concept of equality instead of the default identity based\n   equality) can explicitly flag themselves as being unhashable by\n   setting ``__hash__ = None`` in the class definition. Doing so means\n   that not only will instances of the class raise an appropriate\n   ``TypeError`` when a program attempts to retrieve their hash value,\n   but they will also be correctly identified as unhashable when\n   checking ``isinstance(obj, collections.Hashable)`` (unlike classes\n   which define their own ``__hash__()`` to explicitly raise\n   ``TypeError``).\n\n   If a class that overrides ``__eq__()`` needs to retain the\n   implementation of ``__hash__()`` from a parent class, the\n   interpreter must be told this explicitly by setting ``__hash__ =\n   .__hash__``. Otherwise the inheritance of\n   ``__hash__()`` will be blocked, just as if ``__hash__`` had been\n   explicitly set to ``None``.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   ``bool()``; should return ``False`` or ``True``.  When this method\n   is not defined, ``__len__()`` is called, if it is defined, and the\n   object is considered true if its result is nonzero.  If a class\n   defines neither ``__len__()`` nor ``__bool__()``, all its instances\n   are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n   Called when an attribute lookup has not found the attribute in the\n   usual places (i.e. it is not an instance attribute nor is it found\n   in the class tree for ``self``).  ``name`` is the attribute name.\n   This method should return the (computed) attribute value or raise\n   an ``AttributeError`` exception.\n\n   Note that if the attribute is found through the normal mechanism,\n   ``__getattr__()`` is not called.  (This is an intentional asymmetry\n   between ``__getattr__()`` and ``__setattr__()``.) This is done both\n   for efficiency reasons and because otherwise ``__getattr__()``\n   would have no way to access other attributes of the instance.  Note\n   that at least for instance variables, you can fake total control by\n   not inserting any values in the instance attribute dictionary (but\n   instead inserting them in another object).  See the\n   ``__getattribute__()`` method below for a way to actually get total\n   control over attribute access.\n\nobject.__getattribute__(self, name)\n\n   Called unconditionally to implement attribute accesses for\n   instances of the class. If the class also defines\n   ``__getattr__()``, the latter will not be called unless\n   ``__getattribute__()`` either calls it explicitly or raises an\n   ``AttributeError``. This method should return the (computed)\n   attribute value or raise an ``AttributeError`` exception. In order\n   to avoid infinite recursion in this method, its implementation\n   should always call the base class method with the same name to\n   access any attributes it needs, for example,\n   ``object.__getattribute__(self, name)``.\n\n   Note: This method may still be bypassed when looking up special methods\n     as the result of implicit invocation via language syntax or\n     built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n   Called when an attribute assignment is attempted.  This is called\n   instead of the normal mechanism (i.e. store the value in the\n   instance dictionary). *name* is the attribute name, *value* is the\n   value to be assigned to it.\n\n   If ``__setattr__()`` wants to assign to an instance attribute, it\n   should call the base class method with the same name, for example,\n   ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n   Like ``__setattr__()`` but for attribute deletion instead of\n   assignment.  This should only be implemented if ``del obj.name`` is\n   meaningful for the object.\n\nobject.__dir__(self)\n\n   Called when ``dir()`` is called on the object.  A list must be\n   returned.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another class, known as the *owner* class.  In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n   Called to get the attribute of the owner class (class attribute\n   access) or of an instance of that class (instance attribute\n   access). *owner* is always the owner class, while *instance* is the\n   instance that the attribute was accessed through, or ``None`` when\n   the attribute is accessed through the *owner*.  This method should\n   return the (computed) attribute value or raise an\n   ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n   Called to set the attribute on an instance *instance* of the owner\n   class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n   Called to delete the attribute on an instance *instance* of the\n   owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol:  ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead.  Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n   The simplest and least common call is when user code directly\n   invokes a descriptor method:    ``x.__get__(a)``.\n\nInstance Binding\n   If binding to an object instance, ``a.x`` is transformed into the\n   call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n   If binding to a class, ``A.x`` is transformed into the call:\n   ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n   If ``a`` is an instance of ``super``, then the binding ``super(B,\n   obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n   ``A`` immediately preceding ``B`` and then invokes the descriptor\n   with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined.  A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary.  If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor.  Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method.  Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary.  In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors.  Accordingly, instances can\nredefine and override methods.  This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage.  This wastes space for objects having very few instance\nvariables.  The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable.  Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n   This class variable can be assigned a string, iterable, or sequence\n   of strings with variable names used by instances.  If defined in a\n   class, *__slots__* reserves space for the declared variables and\n   prevents the automatic creation of *__dict__* and *__weakref__* for\n   each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n  attribute of that class will always be accessible, so a *__slots__*\n  definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n  variables not listed in the *__slots__* definition.  Attempts to\n  assign to an unlisted variable name raises ``AttributeError``. If\n  dynamic assignment of new variables is desired, then add\n  ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n  declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n  *__slots__* do not support weak references to its instances. If weak\n  reference support is needed, then add ``\'__weakref__\'`` to the\n  sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n  descriptors (*Implementing Descriptors*) for each variable name.  As\n  a result, class attributes cannot be used to set default values for\n  instance variables defined by *__slots__*; otherwise, the class\n  attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n  where it is defined.  As a result, subclasses will have a *__dict__*\n  unless they also define *__slots__* (which must only contain names\n  of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n  variable defined by the base class slot is inaccessible (except by\n  retrieving its descriptor directly from the base class). This\n  renders the meaning of the program undefined.  In the future, a\n  check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n  "variable-length" built-in types such as ``int``, ``str`` and\n  ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n  also be used; however, in the future, special meaning may be\n  assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n  *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. A class\ndefinition is read into a separate namespace and the value of class\nname is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if a callable ``metaclass`` keyword\nargument is passed after the bases in the class definition, the\ncallable given will be called instead of ``type()``.  If other keyword\narguments are passed, they will also be passed to the metaclass.  This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n  role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties.  This example adds a new\nelement to the class dictionary before creating the class:\n\n   class metacls(type):\n       def __new__(mcs, name, bases, dict):\n           dict[\'foo\'] = \'metacls was here\'\n           return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\nIf the metaclass has a ``__prepare__()`` attribute (usually\nimplemented as a class or static method), it is called before the\nclass body is evaluated with the name of the class and a tuple of its\nbases for arguments.  It should return an object that supports the\nmapping interface that will be used to store the namespace of the\nclass.  The default is a plain dictionary.  This could be used, for\nexample, to keep track of the order that class attributes are declared\nin by returning an ordered dictionary.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If the ``metaclass`` keyword argument is passed with the bases, it\n  is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n  used.\n\n* Otherwise, the default metaclass (``type``) is used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n``collections.OrderedDict`` to remember the order that class members\nwere defined:\n\n   class OrderedClass(type):\n\n        @classmethod\n        def __prepare__(metacls, name, bases, **kwds):\n           return collections.OrderedDict()\n\n        def __new__(cls, name, bases, classdict):\n           result = type.__new__(cls, name, bases, dict(classdict))\n           result.members = tuple(classdict)\n           return result\n\n   class A(metaclass=OrderedClass):\n       def one(self): pass\n       def two(self): pass\n       def three(self): pass\n       def four(self): pass\n\n   >>> A.members\n   (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s ``__prepare__()`` method which returns an\nempty ``collections.OrderedDict``.  That mapping records the methods\nand attributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s ``__new__()`` method gets\ninvoked.  That method builds the new type and it saves the ordered\ndictionary keys in an attribute called ``members``.\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n   Return true if *instance* should be considered a (direct or\n   indirect) instance of *class*. If defined, called to implement\n   ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n   Return true if *subclass* should be considered a (direct or\n   indirect) subclass of *class*.  If defined, called to implement\n   ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass.  They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n   **PEP 3119** - Introducing Abstract Base Classes\n      Includes the specification for customizing ``isinstance()`` and\n      ``issubclass()`` behavior through ``__instancecheck__()`` and\n      ``__subclasscheck__()``, with motivation for this functionality\n      in the context of adding Abstract Base Classes (see the ``abc``\n      module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n   ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well.  The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items.  It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects.  The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects.  Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators.  It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values.  It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n   Called to implement the built-in function ``len()``.  Should return\n   the length of the object, an integer ``>=`` 0.  Also, an object\n   that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n   method returns zero is considered to be false in a Boolean context.\n\nNote: Slicing is done exclusively with the following three methods.  A\n  call like\n\n     a[1:2] = b\n\n  is translated to\n\n     a[slice(1, 2, None)] = b\n\n  and so forth.  Missing slice items are always filled in with\n  ``None``.\n\nobject.__getitem__(self, key)\n\n   Called to implement evaluation of ``self[key]``. For sequence\n   types, the accepted keys should be integers and slice objects.\n   Note that the special interpretation of negative indexes (if the\n   class wishes to emulate a sequence type) is up to the\n   ``__getitem__()`` method. If *key* is of an inappropriate type,\n   ``TypeError`` may be raised; if of a value outside the set of\n   indexes for the sequence (after any special interpretation of\n   negative values), ``IndexError`` should be raised. For mapping\n   types, if *key* is missing (not in the container), ``KeyError``\n   should be raised.\n\n   Note: ``for`` loops expect that an ``IndexError`` will be raised for\n     illegal indexes to allow proper detection of the end of the\n     sequence.\n\nobject.__setitem__(self, key, value)\n\n   Called to implement assignment to ``self[key]``.  Same note as for\n   ``__getitem__()``.  This should only be implemented for mappings if\n   the objects support changes to the values for keys, or if new keys\n   can be added, or for sequences if elements can be replaced.  The\n   same exceptions should be raised for improper *key* values as for\n   the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n   Called to implement deletion of ``self[key]``.  Same note as for\n   ``__getitem__()``.  This should only be implemented for mappings if\n   the objects support removal of keys, or for sequences if elements\n   can be removed from the sequence.  The same exceptions should be\n   raised for improper *key* values as for the ``__getitem__()``\n   method.\n\nobject.__iter__(self)\n\n   This method is called when an iterator is required for a container.\n   This method should return a new iterator object that can iterate\n   over all the objects in the container.  For mappings, it should\n   iterate over the keys of the container, and should also be made\n   available as the method ``keys()``.\n\n   Iterator objects also need to implement this method; they are\n   required to return themselves.  For more information on iterator\n   objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n   Called (if present) by the ``reversed()`` built-in to implement\n   reverse iteration.  It should return a new iterator object that\n   iterates over all the objects in the container in reverse order.\n\n   If the ``__reversed__()`` method is not provided, the\n   ``reversed()`` built-in will fall back to using the sequence\n   protocol (``__len__()`` and ``__getitem__()``).  Objects that\n   support the sequence protocol should only provide\n   ``__reversed__()`` if they can provide an implementation that is\n   more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence.  However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n   Called to implement membership test operators.  Should return true\n   if *item* is in *self*, false otherwise.  For mapping objects, this\n   should consider the keys of the mapping rather than the values or\n   the key-item pairs.\n\n   For objects that don\'t define ``__contains__()``, the membership\n   test first tries iteration via ``__iter__()``, then the old\n   sequence iteration protocol via ``__getitem__()``, see *this\n   section in the language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``).  For instance, to evaluate the expression ``x + y``, where\n   *x* is an instance of a class that has an ``__add__()`` method,\n   ``x.__add__(y)`` is called.  The ``__divmod__()`` method should be\n   the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n   should not be related to ``__truediv__()``.  Note that\n   ``__pow__()`` should be defined to accept an optional third\n   argument if the ternary version of the built-in ``pow()`` function\n   is to be supported.\n\n   If one of those methods does not support the operation with the\n   supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``) with reflected (swapped) operands. These functions are only\n   called if the left operand does not support the corresponding\n   operation and the operands are of different types. [2]  For\n   instance, to evaluate the expression ``x - y``, where *y* is an\n   instance of a class that has an ``__rsub__()`` method,\n   ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n   *NotImplemented*.\n\n   Note that ternary ``pow()`` will not try calling ``__rpow__()``\n   (the coercion rules would become too complicated).\n\n   Note: If the right operand\'s type is a subclass of the left operand\'s\n     type and that subclass provides the reflected method for the\n     operation, this method will be called before the left operand\'s\n     non-reflected method.  This behavior allows subclasses to\n     override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n   These methods are called to implement the augmented arithmetic\n   assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n   ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``).  These methods\n   should attempt to do the operation in-place (modifying *self*) and\n   return the result (which could be, but does not have to be,\n   *self*).  If a specific method is not defined, the augmented\n   assignment falls back to the normal methods.  For instance, to\n   execute the statement ``x += y``, where *x* is an instance of a\n   class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n   called.  If *x* is an instance of a class that does not define a\n   ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n   considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n   Called to implement the unary arithmetic operations (``-``, ``+``,\n   ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n   Called to implement the built-in functions ``complex()``,\n   ``int()``, ``float()`` and ``round()``.  Should return a value of\n   the appropriate type.\n\nobject.__index__(self)\n\n   Called to implement ``operator.index()``.  Also called whenever\n   Python needs an integer object (such as in slicing, or in the\n   built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n   an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code.  Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The ``with``\n   statement will bind this method\'s return value to the target(s)\n   specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be ``None``.\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that ``__exit__()`` methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also:\n\n   **PEP 0343** - The "with" statement\n      The specification, background, and examples for the Python\n      ``with`` statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary.  That behaviour is the reason why\nthe following code raises an exception:\n\n   >>> class C(object):\n   ...     pass\n   ...\n   >>> c = C()\n   >>> c.__len__ = lambda: 5\n   >>> len(c)\n   Traceback (most recent call last):\n     File "", line 1, in \n   TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n   >>> 1 .__hash__() == hash(1)\n   True\n   >>> int.__hash__() == hash(int)\n   Traceback (most recent call last):\n     File "", line 1, in \n   TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n   >>> type(1).__hash__(1) == hash(1)\n   True\n   >>> type(int).__hash__(int) == hash(int)\n   True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n   >>> class Meta(type):\n   ...    def __getattribute__(*args):\n   ...       print("Metaclass getattribute invoked")\n   ...       return type.__getattribute__(*args)\n   ...\n   >>> class C(object, metaclass=Meta):\n   ...     def __len__(self):\n   ...         return 10\n   ...     def __getattribute__(*args):\n   ...         print("Class getattribute invoked")\n   ...         return object.__getattribute__(*args)\n   ...\n   >>> c = C()\n   >>> c.__len__()                 # Explicit lookup via instance\n   Class getattribute invoked\n   10\n   >>> type(c).__len__(c)          # Explicit lookup via type\n   Metaclass getattribute invoked\n   10\n   >>> len(c)                      # Implicit lookup\n   10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n    certain controlled conditions. It generally isn\'t a good idea\n    though, since it can lead to some very strange behaviour if it is\n    handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n    reflected method (such as ``__add__()``) fails the operation is\n    not supported, which is why the reflected method is not called.\n',
- 'string-methods': '\nString Methods\n**************\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is ``\'utf-8\'``. *errors* may be given to set a different\n   error handling scheme. The default for *errors* is ``\'strict\'``,\n   meaning that encoding errors raise a ``UnicodeError``. Other\n   possible values are ``\'ignore\'``, ``\'replace\'``,\n   ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return ``True`` if the string ends with the specified *suffix*,\n   otherwise return ``False``.  *suffix* can also be a tuple of\n   suffixes to look for.  With optional *start*, test beginning at\n   that position.  With optional *end*, stop comparing at that\n   position.\n\nstr.expandtabs([tabsize])\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  The column number is reset to zero after each\n   newline occurring in the string. If *tabsize* is not given, a tab\n   size of ``8`` characters is assumed.  This doesn\'t understand other\n   non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found, such that *sub* is contained in the slice ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces ``{}``.  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to ``str.format(**mapping)``, except that ``mapping`` is\n   used directly and not copied to a ``dict`` .  This is useful if for\n   example ``mapping`` is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like ``find()``, but raise ``ValueError`` when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters include digit characters, and all characters that that\n   can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n   INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n   Return true if all cased characters in the string are lowercase and\n   there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when ``repr()`` is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters in the string are uppercase and\n   there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A ``TypeError`` will be raised if there are\n   any non-string values in *seq*, including ``bytes`` objects.  The\n   separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space).  The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.lower()\n\n   Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.lstrip()\n   \'spacious   \'\n   >>> \'www.example.com\'.lstrip(\'cmowz.\')\n   \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   ``str.translate()``.\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n   is not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space). The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   ``None``, any whitespace string is a separator.  Except for\n   splitting from the right, ``rsplit()`` behaves like ``split()``\n   which is described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.rstrip()\n   \'   spacious\'\n   >>> \'mississippi\'.rstrip(\'ipz\')\n   \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most ``maxsplit+1``\n   elements).  If *maxsplit* is not specified, then there is no limit\n   on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``).  The *sep*\n   argument may consist of multiple characters (for example,\n   ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n   an empty string with a specified separator returns ``[\'\']``.\n\n   If *sep* is not specified or is ``None``, a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a ``None`` separator returns\n   ``[]``.\n\n   For example, ``\' 1  2   3  \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n   and ``\'  1  2   3  \'.split(None, 1)`` returns ``[\'1\', \'2   3  \']``.\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n   Return ``True`` if string starts with the *prefix*, otherwise\n   return ``False``. *prefix* can also be a tuple of prefixes to look\n   for.  With optional *start*, test string beginning at that\n   position.  With optional *end*, stop comparing string at that\n   position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or ``None``, the\n   *chars* argument defaults to removing whitespace. The *chars*\n   argument is not a prefix or suffix; rather, all combinations of its\n   values are stripped:\n\n   >>> \'   spacious   \'.strip()\n   \'spacious\'\n   >>> \'www.example.com\'.strip(\'cmowz.\')\n   \'example\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa.\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n              return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n                            lambda mo: mo.group(0)[0].upper() +\n                                       mo.group(0)[1:].lower(),\n                            s)\n\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n   Return a copy of the *s* where all characters have been mapped\n   through the *map* which must be a dictionary of Unicode ordinals\n   (integers) to Unicode ordinals, strings or ``None``.  Unmapped\n   characters are left untouched. Characters mapped to ``None`` are\n   deleted.\n\n   You can use ``str.maketrans()`` to create a translation map from\n   character-to-character mappings in different formats.\n\n   Note: An even more flexible approach is to create a custom character\n     mapping codec using the ``codecs`` module (see\n     ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n   Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n   Return the numeric string left filled with zeros in a string of\n   length *width*.  A sign prefix is handled correctly.  The original\n   string is returned if *width* is less than ``len(s)``.\n',
+ 'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators.  For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x,\ni)``.  Except where mentioned, attempts to execute an operation raise\nan exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled.  For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense.  (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n   Called to create a new instance of class *cls*.  ``__new__()`` is a\n   static method (special-cased so you need not declare it as such)\n   that takes the class of which an instance was requested as its\n   first argument.  The remaining arguments are those passed to the\n   object constructor expression (the call to the class).  The return\n   value of ``__new__()`` should be the new object instance (usually\n   an instance of *cls*).\n\n   Typical implementations create a new instance of the class by\n   invoking the superclass\'s ``__new__()`` method using\n   ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n   arguments and then modifying the newly-created instance as\n   necessary before returning it.\n\n   If ``__new__()`` returns an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will be invoked like\n   ``__init__(self[, ...])``, where *self* is the new instance and the\n   remaining arguments are the same as were passed to ``__new__()``.\n\n   If ``__new__()`` does not return an instance of *cls*, then the new\n   instance\'s ``__init__()`` method will not be invoked.\n\n   ``__new__()`` is intended mainly to allow subclasses of immutable\n   types (like int, str, or tuple) to customize instance creation.  It\n   is also commonly overridden in custom metaclasses in order to\n   customize class creation.\n\nobject.__init__(self[, ...])\n\n   Called when the instance is created.  The arguments are those\n   passed to the class constructor expression.  If a base class has an\n   ``__init__()`` method, the derived class\'s ``__init__()`` method,\n   if any, must explicitly call it to ensure proper initialization of\n   the base class part of the instance; for example:\n   ``BaseClass.__init__(self, [args...])``.  As a special constraint\n   on constructors, no value may be returned; doing so will cause a\n   ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n   Called when the instance is about to be destroyed.  This is also\n   called a destructor.  If a base class has a ``__del__()`` method,\n   the derived class\'s ``__del__()`` method, if any, must explicitly\n   call it to ensure proper deletion of the base class part of the\n   instance.  Note that it is possible (though not recommended!) for\n   the ``__del__()`` method to postpone destruction of the instance by\n   creating a new reference to it.  It may then be called at a later\n   time when this new reference is deleted.  It is not guaranteed that\n   ``__del__()`` methods are called for objects that still exist when\n   the interpreter exits.\n\n   Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n     decrements the reference count for ``x`` by one, and the latter\n     is only called when ``x``\'s reference count reaches zero.  Some\n     common situations that may prevent the reference count of an\n     object from going to zero include: circular references between\n     objects (e.g., a doubly-linked list or a tree data structure with\n     parent and child pointers); a reference to the object on the\n     stack frame of a function that caught an exception (the traceback\n     stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n     a reference to the object on the stack frame that raised an\n     unhandled exception in interactive mode (the traceback stored in\n     ``sys.last_traceback`` keeps the stack frame alive).  The first\n     situation can only be remedied by explicitly breaking the cycles;\n     the latter two situations can be resolved by storing ``None`` in\n     ``sys.last_traceback``. Circular references which are garbage are\n     detected when the option cycle detector is enabled (it\'s on by\n     default), but can only be cleaned up if there are no Python-\n     level ``__del__()`` methods involved. Refer to the documentation\n     for the ``gc`` module for more information about how\n     ``__del__()`` methods are handled by the cycle detector,\n     particularly the description of the ``garbage`` value.\n\n   Warning: Due to the precarious circumstances under which ``__del__()``\n     methods are invoked, exceptions that occur during their execution\n     are ignored, and a warning is printed to ``sys.stderr`` instead.\n     Also, when ``__del__()`` is invoked in response to a module being\n     deleted (e.g., when execution of the program is done), other\n     globals referenced by the ``__del__()`` method may already have\n     been deleted or in the process of being torn down (e.g. the\n     import machinery shutting down).  For this reason, ``__del__()``\n     methods should do the absolute minimum needed to maintain\n     external invariants.  Starting with version 1.5, Python\n     guarantees that globals whose name begins with a single\n     underscore are deleted from their module before other globals are\n     deleted; if no other references to such globals exist, this may\n     help in assuring that imported modules are still available at the\n     time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n   Called by the ``repr()`` built-in function to compute the\n   "official" string representation of an object.  If at all possible,\n   this should look like a valid Python expression that could be used\n   to recreate an object with the same value (given an appropriate\n   environment).  If this is not possible, a string of the form\n   ``<...some useful description...>`` should be returned. The return\n   value must be a string object. If a class defines ``__repr__()``\n   but not ``__str__()``, then ``__repr__()`` is also used when an\n   "informal" string representation of instances of that class is\n   required.\n\n   This is typically used for debugging, so it is important that the\n   representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n   Called by the ``str()`` built-in function and by the ``print()``\n   function to compute the "informal" string representation of an\n   object.  This differs from ``__repr__()`` in that it does not have\n   to be a valid Python expression: a more convenient or concise\n   representation may be used instead. The return value must be a\n   string object.\n\nobject.__format__(self, format_spec)\n\n   Called by the ``format()`` built-in function (and by extension, the\n   ``format()`` method of class ``str``) to produce a "formatted"\n   string representation of an object. The ``format_spec`` argument is\n   a string that contains a description of the formatting options\n   desired. The interpretation of the ``format_spec`` argument is up\n   to the type implementing ``__format__()``, however most classes\n   will either delegate formatting to one of the built-in types, or\n   use a similar formatting option syntax.\n\n   See *Format Specification Mini-Language* for a description of the\n   standard formatting syntax.\n\n   The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n   These are the so-called "rich comparison" methods. The\n   correspondence between operator symbols and method names is as\n   follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n   ``x.__ge__(y)``.\n\n   A rich comparison method may return the singleton\n   ``NotImplemented`` if it does not implement the operation for a\n   given pair of arguments. By convention, ``False`` and ``True`` are\n   returned for a successful comparison. However, these methods can\n   return any value, so if the comparison operator is used in a\n   Boolean context (e.g., in the condition of an ``if`` statement),\n   Python will call ``bool()`` on the value to determine if the result\n   is true or false.\n\n   There are no implied relationships among the comparison operators.\n   The truth of ``x==y`` does not imply that ``x!=y`` is false.\n   Accordingly, when defining ``__eq__()``, one should also define\n   ``__ne__()`` so that the operators will behave as expected.  See\n   the paragraph on ``__hash__()`` for some important notes on\n   creating *hashable* objects which support custom comparison\n   operations and are usable as dictionary keys.\n\n   There are no swapped-argument versions of these methods (to be used\n   when the left argument does not support the operation but the right\n   argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n   other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n   reflection, and ``__eq__()`` and ``__ne__()`` are their own\n   reflection.\n\n   Arguments to rich comparison methods are never coerced.\n\n   To automatically generate ordering operations from a single root\n   operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n   Called by built-in function ``hash()`` and for operations on\n   members of hashed collections including ``set``, ``frozenset``, and\n   ``dict``.  ``__hash__()`` should return an integer.  The only\n   required property is that objects which compare equal have the same\n   hash value; it is advised to somehow mix together (e.g. using\n   exclusive or) the hash values for the components of the object that\n   also play a part in comparison of objects.\n\n   If a class does not define an ``__eq__()`` method it should not\n   define a ``__hash__()`` operation either; if it defines\n   ``__eq__()`` but not ``__hash__()``, its instances will not be\n   usable as items in hashable collections.  If a class defines\n   mutable objects and implements an ``__eq__()`` method, it should\n   not implement ``__hash__()``, since the implementation of hashable\n   collections requires that a key\'s hash value is immutable (if the\n   object\'s hash value changes, it will be in the wrong hash bucket).\n\n   User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n   by default; with them, all objects compare unequal (except with\n   themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n   Classes which inherit a ``__hash__()`` method from a parent class\n   but change the meaning of ``__eq__()`` such that the hash value\n   returned is no longer appropriate (e.g. by switching to a value-\n   based concept of equality instead of the default identity based\n   equality) can explicitly flag themselves as being unhashable by\n   setting ``__hash__ = None`` in the class definition. Doing so means\n   that not only will instances of the class raise an appropriate\n   ``TypeError`` when a program attempts to retrieve their hash value,\n   but they will also be correctly identified as unhashable when\n   checking ``isinstance(obj, collections.Hashable)`` (unlike classes\n   which define their own ``__hash__()`` to explicitly raise\n   ``TypeError``).\n\n   If a class that overrides ``__eq__()`` needs to retain the\n   implementation of ``__hash__()`` from a parent class, the\n   interpreter must be told this explicitly by setting ``__hash__ =\n   .__hash__``. Otherwise the inheritance of\n   ``__hash__()`` will be blocked, just as if ``__hash__`` had been\n   explicitly set to ``None``.\n\nobject.__bool__(self)\n\n   Called to implement truth value testing and the built-in operation\n   ``bool()``; should return ``False`` or ``True``.  When this method\n   is not defined, ``__len__()`` is called, if it is defined, and the\n   object is considered true if its result is nonzero.  If a class\n   defines neither ``__len__()`` nor ``__bool__()``, all its instances\n   are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n   Called when an attribute lookup has not found the attribute in the\n   usual places (i.e. it is not an instance attribute nor is it found\n   in the class tree for ``self``).  ``name`` is the attribute name.\n   This method should return the (computed) attribute value or raise\n   an ``AttributeError`` exception.\n\n   Note that if the attribute is found through the normal mechanism,\n   ``__getattr__()`` is not called.  (This is an intentional asymmetry\n   between ``__getattr__()`` and ``__setattr__()``.) This is done both\n   for efficiency reasons and because otherwise ``__getattr__()``\n   would have no way to access other attributes of the instance.  Note\n   that at least for instance variables, you can fake total control by\n   not inserting any values in the instance attribute dictionary (but\n   instead inserting them in another object).  See the\n   ``__getattribute__()`` method below for a way to actually get total\n   control over attribute access.\n\nobject.__getattribute__(self, name)\n\n   Called unconditionally to implement attribute accesses for\n   instances of the class. If the class also defines\n   ``__getattr__()``, the latter will not be called unless\n   ``__getattribute__()`` either calls it explicitly or raises an\n   ``AttributeError``. This method should return the (computed)\n   attribute value or raise an ``AttributeError`` exception. In order\n   to avoid infinite recursion in this method, its implementation\n   should always call the base class method with the same name to\n   access any attributes it needs, for example,\n   ``object.__getattribute__(self, name)``.\n\n   Note: This method may still be bypassed when looking up special methods\n     as the result of implicit invocation via language syntax or\n     built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n   Called when an attribute assignment is attempted.  This is called\n   instead of the normal mechanism (i.e. store the value in the\n   instance dictionary). *name* is the attribute name, *value* is the\n   value to be assigned to it.\n\n   If ``__setattr__()`` wants to assign to an instance attribute, it\n   should call the base class method with the same name, for example,\n   ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n   Like ``__setattr__()`` but for attribute deletion instead of\n   assignment.  This should only be implemented if ``del obj.name`` is\n   meaningful for the object.\n\nobject.__dir__(self)\n\n   Called when ``dir()`` is called on the object.  A list must be\n   returned.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another class, known as the *owner* class.  In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n   Called to get the attribute of the owner class (class attribute\n   access) or of an instance of that class (instance attribute\n   access). *owner* is always the owner class, while *instance* is the\n   instance that the attribute was accessed through, or ``None`` when\n   the attribute is accessed through the *owner*.  This method should\n   return the (computed) attribute value or raise an\n   ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n   Called to set the attribute on an instance *instance* of the owner\n   class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n   Called to delete the attribute on an instance *instance* of the\n   owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol:  ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead.  Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n   The simplest and least common call is when user code directly\n   invokes a descriptor method:    ``x.__get__(a)``.\n\nInstance Binding\n   If binding to an object instance, ``a.x`` is transformed into the\n   call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n   If binding to a class, ``A.x`` is transformed into the call:\n   ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n   If ``a`` is an instance of ``super``, then the binding ``super(B,\n   obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n   ``A`` immediately preceding ``B`` and then invokes the descriptor\n   with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined.  A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary.  If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor.  Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method.  Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary.  In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors.  Accordingly, instances can\nredefine and override methods.  This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage.  This wastes space for objects having very few instance\nvariables.  The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable.  Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n   This class variable can be assigned a string, iterable, or sequence\n   of strings with variable names used by instances.  If defined in a\n   class, *__slots__* reserves space for the declared variables and\n   prevents the automatic creation of *__dict__* and *__weakref__* for\n   each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n  attribute of that class will always be accessible, so a *__slots__*\n  definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n  variables not listed in the *__slots__* definition.  Attempts to\n  assign to an unlisted variable name raises ``AttributeError``. If\n  dynamic assignment of new variables is desired, then add\n  ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n  declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n  *__slots__* do not support weak references to its instances. If weak\n  reference support is needed, then add ``\'__weakref__\'`` to the\n  sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n  descriptors (*Implementing Descriptors*) for each variable name.  As\n  a result, class attributes cannot be used to set default values for\n  instance variables defined by *__slots__*; otherwise, the class\n  attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n  where it is defined.  As a result, subclasses will have a *__dict__*\n  unless they also define *__slots__* (which must only contain names\n  of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n  variable defined by the base class slot is inaccessible (except by\n  retrieving its descriptor directly from the base class). This\n  renders the meaning of the program undefined.  In the future, a\n  check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n  "variable-length" built-in types such as ``int``, ``str`` and\n  ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n  also be used; however, in the future, special meaning may be\n  assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n  *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. A class\ndefinition is read into a separate namespace and the value of class\nname is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if a callable ``metaclass`` keyword\nargument is passed after the bases in the class definition, the\ncallable given will be called instead of ``type()``.  If other keyword\narguments are passed, they will also be passed to the metaclass.  This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n  role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties.  This example adds a new\nelement to the class dictionary before creating the class:\n\n   class metacls(type):\n       def __new__(mcs, name, bases, dict):\n           dict[\'foo\'] = \'metacls was here\'\n           return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\nIf the metaclass has a ``__prepare__()`` attribute (usually\nimplemented as a class or static method), it is called before the\nclass body is evaluated with the name of the class and a tuple of its\nbases for arguments.  It should return an object that supports the\nmapping interface that will be used to store the namespace of the\nclass.  The default is a plain dictionary.  This could be used, for\nexample, to keep track of the order that class attributes are declared\nin by returning an ordered dictionary.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If the ``metaclass`` keyword argument is passed with the bases, it\n  is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n  used.\n\n* Otherwise, the default metaclass (``type``) is used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n``collections.OrderedDict`` to remember the order that class members\nwere defined:\n\n   class OrderedClass(type):\n\n        @classmethod\n        def __prepare__(metacls, name, bases, **kwds):\n           return collections.OrderedDict()\n\n        def __new__(cls, name, bases, classdict):\n           result = type.__new__(cls, name, bases, dict(classdict))\n           result.members = tuple(classdict)\n           return result\n\n   class A(metaclass=OrderedClass):\n       def one(self): pass\n       def two(self): pass\n       def three(self): pass\n       def four(self): pass\n\n   >>> A.members\n   (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s ``__prepare__()`` method which returns an\nempty ``collections.OrderedDict``.  That mapping records the methods\nand attributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s ``__new__()`` method gets\ninvoked.  That method builds the new type and it saves the ordered\ndictionary keys in an attribute called ``members``.\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n   Return true if *instance* should be considered a (direct or\n   indirect) instance of *class*. If defined, called to implement\n   ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n   Return true if *subclass* should be considered a (direct or\n   indirect) subclass of *class*.  If defined, called to implement\n   ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass.  They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n   **PEP 3119** - Introducing Abstract Base Classes\n      Includes the specification for customizing ``isinstance()`` and\n      ``issubclass()`` behavior through ``__instancecheck__()`` and\n      ``__subclasscheck__()``, with motivation for this functionality\n      in the context of adding Abstract Base Classes (see the ``abc``\n      module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n   Called when the instance is "called" as a function; if this method\n   is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n   ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well.  The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items.  It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects.  The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects.  Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators.  It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values.  It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n   Called to implement the built-in function ``len()``.  Should return\n   the length of the object, an integer ``>=`` 0.  Also, an object\n   that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n   method returns zero is considered to be false in a Boolean context.\n\nNote: Slicing is done exclusively with the following three methods.  A\n  call like\n\n     a[1:2] = b\n\n  is translated to\n\n     a[slice(1, 2, None)] = b\n\n  and so forth.  Missing slice items are always filled in with\n  ``None``.\n\nobject.__getitem__(self, key)\n\n   Called to implement evaluation of ``self[key]``. For sequence\n   types, the accepted keys should be integers and slice objects.\n   Note that the special interpretation of negative indexes (if the\n   class wishes to emulate a sequence type) is up to the\n   ``__getitem__()`` method. If *key* is of an inappropriate type,\n   ``TypeError`` may be raised; if of a value outside the set of\n   indexes for the sequence (after any special interpretation of\n   negative values), ``IndexError`` should be raised. For mapping\n   types, if *key* is missing (not in the container), ``KeyError``\n   should be raised.\n\n   Note: ``for`` loops expect that an ``IndexError`` will be raised for\n     illegal indexes to allow proper detection of the end of the\n     sequence.\n\nobject.__setitem__(self, key, value)\n\n   Called to implement assignment to ``self[key]``.  Same note as for\n   ``__getitem__()``.  This should only be implemented for mappings if\n   the objects support changes to the values for keys, or if new keys\n   can be added, or for sequences if elements can be replaced.  The\n   same exceptions should be raised for improper *key* values as for\n   the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n   Called to implement deletion of ``self[key]``.  Same note as for\n   ``__getitem__()``.  This should only be implemented for mappings if\n   the objects support removal of keys, or for sequences if elements\n   can be removed from the sequence.  The same exceptions should be\n   raised for improper *key* values as for the ``__getitem__()``\n   method.\n\nobject.__iter__(self)\n\n   This method is called when an iterator is required for a container.\n   This method should return a new iterator object that can iterate\n   over all the objects in the container.  For mappings, it should\n   iterate over the keys of the container, and should also be made\n   available as the method ``keys()``.\n\n   Iterator objects also need to implement this method; they are\n   required to return themselves.  For more information on iterator\n   objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n   Called (if present) by the ``reversed()`` built-in to implement\n   reverse iteration.  It should return a new iterator object that\n   iterates over all the objects in the container in reverse order.\n\n   If the ``__reversed__()`` method is not provided, the\n   ``reversed()`` built-in will fall back to using the sequence\n   protocol (``__len__()`` and ``__getitem__()``).  Objects that\n   support the sequence protocol should only provide\n   ``__reversed__()`` if they can provide an implementation that is\n   more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence.  However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n   Called to implement membership test operators.  Should return true\n   if *item* is in *self*, false otherwise.  For mapping objects, this\n   should consider the keys of the mapping rather than the values or\n   the key-item pairs.\n\n   For objects that don\'t define ``__contains__()``, the membership\n   test first tries iteration via ``__iter__()``, then the old\n   sequence iteration protocol via ``__getitem__()``, see *this\n   section in the language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``).  For instance, to evaluate the expression ``x + y``, where\n   *x* is an instance of a class that has an ``__add__()`` method,\n   ``x.__add__(y)`` is called.  The ``__divmod__()`` method should be\n   the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n   should not be related to ``__truediv__()``.  Note that\n   ``__pow__()`` should be defined to accept an optional third\n   argument if the ternary version of the built-in ``pow()`` function\n   is to be supported.\n\n   If one of those methods does not support the operation with the\n   supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n   These methods are called to implement the binary arithmetic\n   operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n   ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n   ``|``) with reflected (swapped) operands. These functions are only\n   called if the left operand does not support the corresponding\n   operation and the operands are of different types. [2]  For\n   instance, to evaluate the expression ``x - y``, where *y* is an\n   instance of a class that has an ``__rsub__()`` method,\n   ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n   *NotImplemented*.\n\n   Note that ternary ``pow()`` will not try calling ``__rpow__()``\n   (the coercion rules would become too complicated).\n\n   Note: If the right operand\'s type is a subclass of the left operand\'s\n     type and that subclass provides the reflected method for the\n     operation, this method will be called before the left operand\'s\n     non-reflected method.  This behavior allows subclasses to\n     override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n   These methods are called to implement the augmented arithmetic\n   assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n   ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``).  These methods\n   should attempt to do the operation in-place (modifying *self*) and\n   return the result (which could be, but does not have to be,\n   *self*).  If a specific method is not defined, the augmented\n   assignment falls back to the normal methods.  For instance, to\n   execute the statement ``x += y``, where *x* is an instance of a\n   class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n   called.  If *x* is an instance of a class that does not define a\n   ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n   considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n   Called to implement the unary arithmetic operations (``-``, ``+``,\n   ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n   Called to implement the built-in functions ``complex()``,\n   ``int()``, ``float()`` and ``round()``.  Should return a value of\n   the appropriate type.\n\nobject.__index__(self)\n\n   Called to implement ``operator.index()``.  Also called whenever\n   Python needs an integer object (such as in slicing, or in the\n   built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n   an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code.  Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n   Enter the runtime context related to this object. The ``with``\n   statement will bind this method\'s return value to the target(s)\n   specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n   Exit the runtime context related to this object. The parameters\n   describe the exception that caused the context to be exited. If the\n   context was exited without an exception, all three arguments will\n   be ``None``.\n\n   If an exception is supplied, and the method wishes to suppress the\n   exception (i.e., prevent it from being propagated), it should\n   return a true value. Otherwise, the exception will be processed\n   normally upon exit from this method.\n\n   Note that ``__exit__()`` methods should not reraise the passed-in\n   exception; this is the caller\'s responsibility.\n\nSee also:\n\n   **PEP 0343** - The "with" statement\n      The specification, background, and examples for the Python\n      ``with`` statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary.  That behaviour is the reason why\nthe following code raises an exception:\n\n   >>> class C:\n   ...     pass\n   ...\n   >>> c = C()\n   >>> c.__len__ = lambda: 5\n   >>> len(c)\n   Traceback (most recent call last):\n     File "", line 1, in \n   TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n   >>> 1 .__hash__() == hash(1)\n   True\n   >>> int.__hash__() == hash(int)\n   Traceback (most recent call last):\n     File "", line 1, in \n   TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n   >>> type(1).__hash__(1) == hash(1)\n   True\n   >>> type(int).__hash__(int) == hash(int)\n   True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n   >>> class Meta(type):\n   ...    def __getattribute__(*args):\n   ...       print("Metaclass getattribute invoked")\n   ...       return type.__getattribute__(*args)\n   ...\n   >>> class C(object, metaclass=Meta):\n   ...     def __len__(self):\n   ...         return 10\n   ...     def __getattribute__(*args):\n   ...         print("Class getattribute invoked")\n   ...         return object.__getattribute__(*args)\n   ...\n   >>> c = C()\n   >>> c.__len__()                 # Explicit lookup via instance\n   Class getattribute invoked\n   10\n   >>> type(c).__len__(c)          # Explicit lookup via type\n   Metaclass getattribute invoked\n   10\n   >>> len(c)                      # Implicit lookup\n   10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n    certain controlled conditions. It generally isn\'t a good idea\n    though, since it can lead to some very strange behaviour if it is\n    handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n    reflected method (such as ``__add__()``) fails the operation is\n    not supported, which is why the reflected method is not called.\n',
+ 'string-methods': '\nString Methods\n**************\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is ``\'utf-8\'``. *errors* may be given to set a different\n   error handling scheme. The default for *errors* is ``\'strict\'``,\n   meaning that encoding errors raise a ``UnicodeError``. Other\n   possible values are ``\'ignore\'``, ``\'replace\'``,\n   ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return ``True`` if the string ends with the specified *suffix*,\n   otherwise return ``False``.  *suffix* can also be a tuple of\n   suffixes to look for.  With optional *start*, test beginning at\n   that position.  With optional *end*, stop comparing at that\n   position.\n\nstr.expandtabs([tabsize])\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  The column number is reset to zero after each\n   newline occurring in the string. If *tabsize* is not given, a tab\n   size of ``8`` characters is assumed.  This doesn\'t understand other\n   non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found, such that *sub* is contained in the slice ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces ``{}``.  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to ``str.format(**mapping)``, except that ``mapping`` is\n   used directly and not copied to a ``dict`` .  This is useful if for\n   example ``mapping`` is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like ``find()``, but raise ``ValueError`` when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters include digit characters, and all characters that that\n   can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n   INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n   Return true if all cased characters in the string are lowercase and\n   there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when ``repr()`` is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters in the string are uppercase and\n   there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A ``TypeError`` will be raised if there are\n   any non-string values in *seq*, including ``bytes`` objects.  The\n   separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space).  The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.lower()\n\n   Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.lstrip()\n   \'spacious   \'\n   >>> \'www.example.com\'.lstrip(\'cmowz.\')\n   \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   ``str.translate()``.\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n   is not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space). The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   ``None``, any whitespace string is a separator.  Except for\n   splitting from the right, ``rsplit()`` behaves like ``split()``\n   which is described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.rstrip()\n   \'   spacious\'\n   >>> \'mississippi\'.rstrip(\'ipz\')\n   \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most ``maxsplit+1``\n   elements).  If *maxsplit* is not specified, then there is no limit\n   on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``).  The *sep*\n   argument may consist of multiple characters (for example,\n   ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n   an empty string with a specified separator returns ``[\'\']``.\n\n   If *sep* is not specified or is ``None``, a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a ``None`` separator returns\n   ``[]``.\n\n   For example, ``\' 1  2   3  \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n   and ``\'  1  2   3  \'.split(None, 1)`` returns ``[\'1\', \'2   3  \']``.\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n   Return ``True`` if string starts with the *prefix*, otherwise\n   return ``False``. *prefix* can also be a tuple of prefixes to look\n   for.  With optional *start*, test string beginning at that\n   position.  With optional *end*, stop comparing string at that\n   position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or ``None``, the\n   *chars* argument defaults to removing whitespace. The *chars*\n   argument is not a prefix or suffix; rather, all combinations of its\n   values are stripped:\n\n   >>> \'   spacious   \'.strip()\n   \'spacious\'\n   >>> \'www.example.com\'.strip(\'cmowz.\')\n   \'example\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa.\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n              return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n                            lambda mo: mo.group(0)[0].upper() +\n                                       mo.group(0)[1:].lower(),\n                            s)\n\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.transform(encoding, errors=\'strict\')\n\n   Return an encoded version of the string.  In contrast to\n   ``encode()``, this method works with codecs that provide string-to-\n   string mappings, and not string-to-bytes mappings.  ``transform()``\n   therefore returns a string object.\n\n   The codecs that can be used with this method are listed in\n   *Standard Encodings*.\n\n   New in version 3.2.\n\nstr.translate(map)\n\n   Return a copy of the *s* where all characters have been mapped\n   through the *map* which must be a dictionary of Unicode ordinals\n   (integers) to Unicode ordinals, strings or ``None``.  Unmapped\n   characters are left untouched. Characters mapped to ``None`` are\n   deleted.\n\n   You can use ``str.maketrans()`` to create a translation map from\n   character-to-character mappings in different formats.\n\n   Note: An even more flexible approach is to create a custom character\n     mapping codec using the ``codecs`` module (see\n     ``encodings.cp1251`` for an example).\n\nstr.untransform(encoding, errors=\'strict\')\n\n   Return a decoded version of the string.  This provides the reverse\n   operation of ``transform()``.\n\n   New in version 3.2.\n\nstr.upper()\n\n   Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n   Return the numeric string left filled with zeros in a string of\n   length *width*.  A sign prefix is handled correctly.  The original\n   string is returned if *width* is less than ``len(s)``.\n',
  'strings': '\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n   stringliteral   ::= [stringprefix](shortstring | longstring)\n   stringprefix    ::= "r" | "R"\n   shortstring     ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n   longstring      ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n   shortstringitem ::= shortstringchar | stringescapeseq\n   longstringitem  ::= longstringchar | stringescapeseq\n   shortstringchar ::= \n   longstringchar  ::= \n   stringescapeseq ::= "\\" \n\n   bytesliteral   ::= bytesprefix(shortbytes | longbytes)\n   bytesprefix    ::= "b" | "B" | "br" | "Br" | "bR" | "BR"\n   shortbytes     ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n   longbytes      ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n   shortbytesitem ::= shortbyteschar | bytesescapeseq\n   longbytesitem  ::= longbyteschar | bytesescapeseq\n   shortbyteschar ::= \n   longbyteschar  ::= \n   bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the ``stringprefix`` or\n``bytesprefix`` and the rest of the literal. The source character set\nis defined by the encoding declaration; it is UTF-8 if no encoding\ndeclaration is given in the source file; see section *Encoding\ndeclarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes (``\'``) or double quotes (``"``).  They can also be\nenclosed in matching groups of three single or double quotes (these\nare generally referred to as *triple-quoted strings*).  The backslash\n(``\\``) character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with ``\'b\'`` or ``\'B\'``; they\nproduce an instance of the ``bytes`` type instead of the ``str`` type.\nThey may only contain ASCII characters; bytes with a numeric value of\n128 or greater must be expressed with escapes.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter ``\'r\'`` or ``\'R\'``; such strings are called *raw strings* and\ntreat backslashes as literal characters.  As a result, in string\nliterals, ``\'\\U\'`` and ``\'\\u\'`` escapes in raw strings are not treated\nspecially.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string.  (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C.  The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| ``\\newline``      | Backslash and newline ignored     |         |\n+-------------------+-----------------------------------+---------+\n| ``\\\\``            | Backslash (``\\``)                 |         |\n+-------------------+-----------------------------------+---------+\n| ``\\\'``            | Single quote (``\'``)              |         |\n+-------------------+-----------------------------------+---------+\n| ``\\"``            | Double quote (``"``)              |         |\n+-------------------+-----------------------------------+---------+\n| ``\\a``            | ASCII Bell (BEL)                  |         |\n+-------------------+-----------------------------------+---------+\n| ``\\b``            | ASCII Backspace (BS)              |         |\n+-------------------+-----------------------------------+---------+\n| ``\\f``            | ASCII Formfeed (FF)               |         |\n+-------------------+-----------------------------------+---------+\n| ``\\n``            | ASCII Linefeed (LF)               |         |\n+-------------------+-----------------------------------+---------+\n| ``\\r``            | ASCII Carriage Return (CR)        |         |\n+-------------------+-----------------------------------+---------+\n| ``\\t``            | ASCII Horizontal Tab (TAB)        |         |\n+-------------------+-----------------------------------+---------+\n| ``\\v``            | ASCII Vertical Tab (VT)           |         |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo``          | Character with octal value *ooo*  | (1,3)   |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh``          | Character with hex value *hh*     | (2,3)   |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence   | Meaning                           | Notes   |\n+===================+===================================+=========+\n| ``\\N{name}``      | Character named *name* in the     |         |\n|                   | Unicode database                  |         |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx``        | Character with 16-bit hex value   | (4)     |\n|                   | *xxxx*                            |         |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx``    | Character with 32-bit hex value   | (5)     |\n|                   | *xxxxxxxx*                        |         |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the byte\n   with the given value. In a string literal, these escapes denote a\n   Unicode character with the given value.\n\n4. Individual code units which form parts of a surrogate pair can be\n   encoded using this escape sequence.  Exactly four hex digits are\n   required.\n\n5. Any Unicode character can be encoded this way, but characters\n   outside the Basic Multilingual Plane (BMP) will be encoded using a\n   surrogate pair if Python is compiled to use 16-bit code units (the\n   default).  Exactly eight hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*.  (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.)  It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw string, string quotes can be escaped with a backslash,\nbut the backslash remains in the string; for example, ``r"\\""`` is a\nvalid string literal consisting of two characters: a backslash and a\ndouble quote; ``r"\\"`` is not a valid string literal (even a raw\nstring cannot end in an odd number of backslashes).  Specifically, *a\nraw string cannot end in a single backslash* (since the backslash\nwould escape the following quote character).  Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n',
  'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n   subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription,\ne.g. a list or dictionary.  User-defined objects can support\nsubscription by defining a ``__getitem__()`` method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey.  (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a ``__getitem__()``\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that ``x[-1]`` selects the last item of\n``x``).  The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero). Since the support\nfor negative indices and slicing occurs in the object\'s\n``__getitem__()`` method, subclasses overriding this method will need\nto explicitly add that support.\n\nA string\'s items are characters.  A character is not a separate data\ntype but a string of exactly one character.\n',
  'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0.0``, ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n  ``__bool__()`` or ``__len__()`` method, when that method returns the\n  integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n",
@@ -70,7 +70,7 @@
  'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects.  There is currently only one standard\nmapping type, the *dictionary*.  (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values.  Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys.  Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry.  (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n   Return a new dictionary initialized from an optional positional\n   argument or from a set of keyword arguments.  If no arguments are\n   given, return a new empty dictionary.  If the positional argument\n   *arg* is a mapping object, return a dictionary mapping the same\n   keys to the same values as does the mapping object.  Otherwise the\n   positional argument must be a sequence, a container that supports\n   iteration, or an iterator object.  The elements of the argument\n   must each also be of one of those kinds, and each must in turn\n   contain exactly two objects.  The first is used as a key in the new\n   dictionary, and the second as the key\'s value.  If a given key is\n   seen more than once, the last value associated with it is retained\n   in the new dictionary.\n\n   If keyword arguments are given, the keywords themselves with their\n   associated values are added as items to the dictionary.  If a key\n   is specified both in the positional argument and as a keyword\n   argument, the value associated with the keyword is retained in the\n   dictionary.  For example, these all return a dictionary equal to\n   ``{"one": 1, "two": 2}``:\n\n   * ``dict(one=1, two=2)``\n\n   * ``dict({\'one\': 1, \'two\': 2})``\n\n   * ``dict(zip((\'one\', \'two\'), (1, 2)))``\n\n   * ``dict([[\'two\', 2], [\'one\', 1]])``\n\n   The first example only works for keys that are valid Python\n   identifiers; the others work with any valid keys.\n\n   These are the operations that dictionaries support (and therefore,\n   custom mapping types should support too):\n\n   len(d)\n\n      Return the number of items in the dictionary *d*.\n\n   d[key]\n\n      Return the item of *d* with key *key*.  Raises a ``KeyError`` if\n      *key* is not in the map.\n\n      If a subclass of dict defines a method ``__missing__()``, if the\n      key *key* is not present, the ``d[key]`` operation calls that\n      method with the key *key* as argument.  The ``d[key]`` operation\n      then returns or raises whatever is returned or raised by the\n      ``__missing__(key)`` call if the key is not present. No other\n      operations or methods invoke ``__missing__()``. If\n      ``__missing__()`` is not defined, ``KeyError`` is raised.\n      ``__missing__()`` must be a method; it cannot be an instance\n      variable. For an example, see ``collections.defaultdict``.\n\n   d[key] = value\n\n      Set ``d[key]`` to *value*.\n\n   del d[key]\n\n      Remove ``d[key]`` from *d*.  Raises a ``KeyError`` if *key* is\n      not in the map.\n\n   key in d\n\n      Return ``True`` if *d* has a key *key*, else ``False``.\n\n   key not in d\n\n      Equivalent to ``not key in d``.\n\n   iter(d)\n\n      Return an iterator over the keys of the dictionary.  This is a\n      shortcut for ``iter(d.keys())``.\n\n   clear()\n\n      Remove all items from the dictionary.\n\n   copy()\n\n      Return a shallow copy of the dictionary.\n\n   classmethod fromkeys(seq[, value])\n\n      Create a new dictionary with keys from *seq* and values set to\n      *value*.\n\n      ``fromkeys()`` is a class method that returns a new dictionary.\n      *value* defaults to ``None``.\n\n   get(key[, default])\n\n      Return the value for *key* if *key* is in the dictionary, else\n      *default*. If *default* is not given, it defaults to ``None``,\n      so that this method never raises a ``KeyError``.\n\n   items()\n\n      Return a new view of the dictionary\'s items (``(key, value)``\n      pairs).  See below for documentation of view objects.\n\n   keys()\n\n      Return a new view of the dictionary\'s keys.  See below for\n      documentation of view objects.\n\n   pop(key[, default])\n\n      If *key* is in the dictionary, remove it and return its value,\n      else return *default*.  If *default* is not given and *key* is\n      not in the dictionary, a ``KeyError`` is raised.\n\n   popitem()\n\n      Remove and return an arbitrary ``(key, value)`` pair from the\n      dictionary.\n\n      ``popitem()`` is useful to destructively iterate over a\n      dictionary, as often used in set algorithms.  If the dictionary\n      is empty, calling ``popitem()`` raises a ``KeyError``.\n\n   setdefault(key[, default])\n\n      If *key* is in the dictionary, return its value.  If not, insert\n      *key* with a value of *default* and return *default*.  *default*\n      defaults to ``None``.\n\n   update([other])\n\n      Update the dictionary with the key/value pairs from *other*,\n      overwriting existing keys.  Return ``None``.\n\n      ``update()`` accepts either another dictionary object or an\n      iterable of key/value pairs (as tuples or other iterables of\n      length two).  If keyword arguments are specified, the dictionary\n      is then updated with those key/value pairs: ``d.update(red=1,\n      blue=2)``.\n\n   values()\n\n      Return a new view of the dictionary\'s values.  See below for\n      documentation of view objects.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*.  They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n   Return the number of entries in the dictionary.\n\niter(dictview)\n\n   Return an iterator over the keys, values or items (represented as\n   tuples of ``(key, value)``) in the dictionary.\n\n   Keys and values are iterated over in an arbitrary order which is\n   non-random, varies across Python implementations, and depends on\n   the dictionary\'s history of insertions and deletions. If keys,\n   values and items views are iterated over with no intervening\n   modifications to the dictionary, the order of items will directly\n   correspond.  This allows the creation of ``(value, key)`` pairs\n   using ``zip()``: ``pairs = zip(d.values(), d.keys())``.  Another\n   way to create the same list is ``pairs = [(v, k) for (k, v) in\n   d.items()]``.\n\n   Iterating views while adding or deleting entries in the dictionary\n   may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n   Return ``True`` if *x* is in the underlying dictionary\'s keys,\n   values or items (in the latter case, *x* should be a ``(key,\n   value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that ``(key, value)`` pairs are unique\nand hashable, then the items view is also set-like.  (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class ``collections.Set`` are available (for example, ``==``,\n``<``, or ``^``).\n\nAn example of dictionary view usage:\n\n   >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n   >>> keys = dishes.keys()\n   >>> values = dishes.values()\n\n   >>> # iteration\n   >>> n = 0\n   >>> for val in values:\n   ...     n += val\n   >>> print(n)\n   504\n\n   >>> # keys and values are iterated over in the same order\n   >>> list(keys)\n   [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n   >>> list(values)\n   [2, 1, 1, 500]\n\n   >>> # view objects are dynamic and reflect dict changes\n   >>> del dishes[\'eggs\']\n   >>> del dishes[\'sausage\']\n   >>> list(keys)\n   [\'spam\', \'bacon\']\n\n   >>> # set operations\n   >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n   {\'bacon\'}\n   >>> keys ^ {\'sausage\', \'juice\'}\n   {\'juice\', \'eggs\', \'bacon\', \'spam\'}\n',
  'typesmethods': "\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods.  Built-in methods are described\nwith the types that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the\n``self`` argument to the argument list.  Bound methods have two\nspecial read-only attributes: ``m.__self__`` is the object on which\nthe method operates, and ``m.__func__`` is the function implementing\nthe method.  Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely\nequivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,\narg-n)``.\n\nLike function objects, bound method objects support getting arbitrary\nattributes.  However, since method attributes are actually stored on\nthe underlying function object (``meth.__func__``), setting method\nattributes on bound methods is disallowed.  Attempting to set a method\nattribute results in a ``TypeError`` being raised.  In order to set a\nmethod attribute, you need to explicitly set it on the underlying\nfunction object:\n\n   class C:\n       def method(self):\n           pass\n\n   c = C()\n   c.method.__func__.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n",
  'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to.  (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``).  Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````.  If loaded from a file, they are written as\n````.\n",
- 'typesseq': '\nSequence Types --- ``str``, ``bytes``, ``bytearray``, ``list``, ``tuple``, ``range``\n************************************************************************************\n\nThere are six sequence types: strings, byte sequences (``bytes``\nobjects), byte arrays (``bytearray`` objects), lists, tuples, and\nrange objects.  For other containers see the built in ``dict`` and\n``set`` classes, and the ``collections`` module.\n\nStrings contain Unicode characters.  Their literals are written in\nsingle or double quotes: ``\'xyzzy\'``, ``"frobozz"``.  See *String and\nBytes literals* for more about string literals.  In addition to the\nfunctionality described here, there are also string-specific methods\ndescribed in the *String Methods* section.\n\nBytes and bytearray objects contain single bytes -- the former is\nimmutable while the latter is a mutable sequence.  Bytes objects can\nbe constructed the constructor, ``bytes()``, and from literals; use a\n``b`` prefix with normal string syntax: ``b\'xyzzy\'``.  To construct\nbyte arrays, use the ``bytearray()`` function.\n\nWhile string objects are sequences of characters (represented by\nstrings of length 1), bytes and bytearray objects are sequences of\n*integers* (between 0 and 255), representing the ASCII value of single\nbytes.  That means that for a bytes or bytearray object *b*, ``b[0]``\nwill be an integer, while ``b[0:1]`` will be a bytes or bytearray\nobject of length 1.  The representation of bytes objects uses the\nliteral format (``b\'...\'``) since it is generally more useful than\ne.g. ``bytes([50, 19, 100])``.  You can always convert a bytes object\ninto a list of integers using ``list(b)``.\n\nAlso, while in previous Python versions, byte strings and Unicode\nstrings could be exchanged for each other rather freely (barring\nencoding issues), strings and bytes are now completely separate\nconcepts.  There\'s no implicit en-/decoding if you pass an object of\nthe wrong type.  A string always compares unequal to a bytes or\nbytearray object.\n\nLists are constructed with square brackets, separating items with\ncommas: ``[a, b, c]``.  Tuples are constructed by the comma operator\n(not within square brackets), with or without enclosing parentheses,\nbut an empty tuple must have the enclosing parentheses, such as ``a,\nb, c`` or ``()``.  A single item tuple must have a trailing comma,\nsuch as ``(d,)``.\n\nObjects of type range are created using the ``range()`` function.\nThey don\'t support slicing, concatenation or repetition, and using\n``in``, ``not in``, ``min()`` or ``max()`` on them is inefficient.\n\nMost sequence types support the following operations.  The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations.  The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority).  In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation          | Result                           | Notes      |\n+====================+==================================+============+\n| ``x in s``         | ``True`` if an item of *s* is    | (1)        |\n|                    | equal to *x*, else ``False``     |            |\n+--------------------+----------------------------------+------------+\n| ``x not in s``     | ``False`` if an item of *s* is   | (1)        |\n|                    | equal to *x*, else ``True``      |            |\n+--------------------+----------------------------------+------------+\n| ``s + t``          | the concatenation of *s* and *t* | (6)        |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s``   | *n* shallow copies of *s*        | (2)        |\n|                    | concatenated                     |            |\n+--------------------+----------------------------------+------------+\n| ``s[i]``           | *i*\'th item of *s*, origin 0     | (3)        |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]``         | slice of *s* from *i* to *j*     | (3)(4)     |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]``       | slice of *s* from *i* to *j*     | (3)(5)     |\n|                    | with step *k*                    |            |\n+--------------------+----------------------------------+------------+\n| ``len(s)``         | length of *s*                    |            |\n+--------------------+----------------------------------+------------+\n| ``min(s)``         | smallest item of *s*             |            |\n+--------------------+----------------------------------+------------+\n| ``max(s)``         | largest item of *s*              |            |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons.  In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements.  This means that to compare equal, every element must\ncompare equal and the two sequences must be of the same type and have\nthe same length.  (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string object, the ``in`` and ``not in`` operations\n   act like a substring test.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n   empty sequence of the same type as *s*).  Note also that the copies\n   are shallow; nested structures are not copied.  This often haunts\n   new Python programmers; consider:\n\n   >>> lists = [[]] * 3\n   >>> lists\n   [[], [], []]\n   >>> lists[0].append(3)\n   >>> lists\n   [[3], [3], [3]]\n\n   What has happened is that ``[[]]`` is a one-element list containing\n   an empty list, so all three elements of ``[[]] * 3`` are (pointers\n   to) this single empty list.  Modifying any of the elements of\n   ``lists`` modifies this single list. You can create a list of\n   different lists this way:\n\n   >>> lists = [[] for i in range(3)]\n   >>> lists[0].append(3)\n   >>> lists[1].append(5)\n   >>> lists[2].append(7)\n   >>> lists\n   [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n   string: ``len(s) + i`` or ``len(s) + j`` is substituted.  But note\n   that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n   items with index *k* such that ``i <= k < j``.  If *i* or *j* is\n   greater than ``len(s)``, use ``len(s)``.  If *i* is omitted or\n   ``None``, use ``0``.  If *j* is omitted or ``None``, use\n   ``len(s)``.  If *i* is greater than or equal to *j*, the slice is\n   empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n   sequence of items with index  ``x = i + n*k`` such that ``0 <= n <\n   (j-i)/k``.  In other words, the indices are ``i``, ``i+k``,\n   ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n   never including *j*).  If *i* or *j* is greater than ``len(s)``,\n   use ``len(s)``.  If *i* or *j* are omitted or ``None``, they become\n   "end" values (which end depends on the sign of *k*).  Note, *k*\n   cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n   some Python implementations such as CPython can usually perform an\n   in-place optimization for assignments of the form ``s = s + t`` or\n   ``s += t``.  When applicable, this optimization makes quadratic\n   run-time much less likely.  This optimization is both version and\n   implementation dependent.  For performance sensitive code, it is\n   preferable to use the ``str.join()`` method which assures\n   consistent linear concatenation performance across versions and\n   implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is ``\'utf-8\'``. *errors* may be given to set a different\n   error handling scheme. The default for *errors* is ``\'strict\'``,\n   meaning that encoding errors raise a ``UnicodeError``. Other\n   possible values are ``\'ignore\'``, ``\'replace\'``,\n   ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return ``True`` if the string ends with the specified *suffix*,\n   otherwise return ``False``.  *suffix* can also be a tuple of\n   suffixes to look for.  With optional *start*, test beginning at\n   that position.  With optional *end*, stop comparing at that\n   position.\n\nstr.expandtabs([tabsize])\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  The column number is reset to zero after each\n   newline occurring in the string. If *tabsize* is not given, a tab\n   size of ``8`` characters is assumed.  This doesn\'t understand other\n   non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found, such that *sub* is contained in the slice ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces ``{}``.  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to ``str.format(**mapping)``, except that ``mapping`` is\n   used directly and not copied to a ``dict`` .  This is useful if for\n   example ``mapping`` is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like ``find()``, but raise ``ValueError`` when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters include digit characters, and all characters that that\n   can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n   INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n   Return true if all cased characters in the string are lowercase and\n   there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when ``repr()`` is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters in the string are uppercase and\n   there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A ``TypeError`` will be raised if there are\n   any non-string values in *seq*, including ``bytes`` objects.  The\n   separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space).  The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.lower()\n\n   Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.lstrip()\n   \'spacious   \'\n   >>> \'www.example.com\'.lstrip(\'cmowz.\')\n   \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   ``str.translate()``.\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n   is not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space). The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   ``None``, any whitespace string is a separator.  Except for\n   splitting from the right, ``rsplit()`` behaves like ``split()``\n   which is described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.rstrip()\n   \'   spacious\'\n   >>> \'mississippi\'.rstrip(\'ipz\')\n   \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most ``maxsplit+1``\n   elements).  If *maxsplit* is not specified, then there is no limit\n   on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``).  The *sep*\n   argument may consist of multiple characters (for example,\n   ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n   an empty string with a specified separator returns ``[\'\']``.\n\n   If *sep* is not specified or is ``None``, a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a ``None`` separator returns\n   ``[]``.\n\n   For example, ``\' 1  2   3  \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n   and ``\'  1  2   3  \'.split(None, 1)`` returns ``[\'1\', \'2   3  \']``.\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n   Return ``True`` if string starts with the *prefix*, otherwise\n   return ``False``. *prefix* can also be a tuple of prefixes to look\n   for.  With optional *start*, test string beginning at that\n   position.  With optional *end*, stop comparing string at that\n   position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or ``None``, the\n   *chars* argument defaults to removing whitespace. The *chars*\n   argument is not a prefix or suffix; rather, all combinations of its\n   values are stripped:\n\n   >>> \'   spacious   \'.strip()\n   \'spacious\'\n   >>> \'www.example.com\'.strip(\'cmowz.\')\n   \'example\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa.\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n              return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n                            lambda mo: mo.group(0)[0].upper() +\n                                       mo.group(0)[1:].lower(),\n                            s)\n\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n   Return a copy of the *s* where all characters have been mapped\n   through the *map* which must be a dictionary of Unicode ordinals\n   (integers) to Unicode ordinals, strings or ``None``.  Unmapped\n   characters are left untouched. Characters mapped to ``None`` are\n   deleted.\n\n   You can use ``str.maketrans()`` to create a translation map from\n   character-to-character mappings in different formats.\n\n   Note: An even more flexible approach is to create a custom character\n     mapping codec using the ``codecs`` module (see\n     ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n   Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n   Return the numeric string left filled with zeros in a string of\n   length *width*.  A sign prefix is handled correctly.  The original\n   string is returned if *width* is less than ``len(s)``.\n\n\nOld String Formatting Operations\n================================\n\nNote: The formatting operations described here are obsolete and may go\n  away in future versions of Python.  Use the new *String Formatting*\n  in new code.\n\nString objects have one unique built-in operation: the ``%`` operator\n(modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given ``format % values`` (where *format* is\na string), ``%`` conversion specifications in *format* are replaced\nwith zero or more elements of *values*. The effect is similar to the\nusing ``sprintf()`` in the C language.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4]  Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n   characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n   conversion types.\n\n4. Minimum field width (optional).  If specified as an ``\'*\'``\n   (asterisk), the actual width is read from the next element of the\n   tuple in *values*, and the object to convert comes after the\n   minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n   precision.  If specified as ``\'*\'`` (an asterisk), the actual width\n   is read from the next element of the tuple in *values*, and the\n   value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print(\'%(language)s has %(number)03d quote types.\' %\n...       {\'language\': "Python", "number": 2})\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag      | Meaning                                                               |\n+===========+=======================================================================+\n| ``\'#\'``   | The value conversion will use the "alternate form" (where defined     |\n|           | below).                                                               |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'``   | The conversion will be zero padded for numeric values.                |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'``   | The converted value is left adjusted (overrides the ``\'0\'``           |\n|           | conversion if both are given).                                        |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'``   | (a space) A blank should be left before a positive number (or empty   |\n|           | string) produced by a signed conversion.                              |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'``   | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion     |\n|           | (overrides a "space" flag).                                           |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion   | Meaning                                               | Notes   |\n+==============+=======================================================+=========+\n| ``\'d\'``      | Signed integer decimal.                               |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'``      | Signed integer decimal.                               |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'``      | Signed octal value.                                   | (1)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'``      | Obsolete type -- it is identical to ``\'d\'``.          | (7)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'``      | Signed hexadecimal (lowercase).                       | (2)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'``      | Signed hexadecimal (uppercase).                       | (2)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'``      | Floating point exponential format (lowercase).        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'``      | Floating point exponential format (uppercase).        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'``      | Floating point decimal format.                        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'``      | Floating point decimal format.                        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'``      | Floating point format. Uses lowercase exponential     | (4)     |\n|              | format if exponent is less than -4 or not less than   |         |\n|              | precision, decimal format otherwise.                  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'``      | Floating point format. Uses uppercase exponential     | (4)     |\n|              | format if exponent is less than -4 or not less than   |         |\n|              | precision, decimal format otherwise.                  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'``      | Single character (accepts integer or single character |         |\n|              | string).                                              |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'``      | String (converts any Python object using ``repr()``). | (5)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'``      | String (converts any Python object using ``str()``).  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'``      | No argument is converted, results in a ``\'%\'``        |         |\n|              | character in the result.                              |         |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n   between left-hand padding and the formatting of the number if the\n   leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n   on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n   between left-hand padding and the formatting of the number if the\n   leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n   point, even if no digits follow it.\n\n   The precision determines the number of digits after the decimal\n   point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n   point, and trailing zeroes are not removed as they would otherwise\n   be.\n\n   The precision determines the number of significant digits before\n   and after the decimal point and defaults to 6.\n\n5. The precision determines the maximal number of characters used.\n\n1. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 3.1: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nRange Type\n==========\n\nThe ``range`` type is an immutable sequence which is commonly used for\nlooping.  The advantage of the ``range`` type is that an ``range``\nobject will always take the same amount of memory, no matter the size\nof the range it represents.  There are no consistent performance\nadvantages.\n\nRange objects have relatively little behavior: they support indexing,\niteration, the ``len()`` function, and the following methods.\n\nrange.count(x)\n\n   Return the number of *i*\'s for which ``s[i] == x``.  Normally the\n   result will be 0 or 1, but it could be greater if *x* defines an\n   unusual equality function.\n\n      New in version 3.2.\n\nrange.index(x)\n\n   Return the smallest *i* such that ``s[i] == x``.  Raises\n   ``ValueError`` when *x* is not in the range.\n\n      New in version 3.2.\n\n\nMutable Sequence Types\n======================\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object.  Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| ``s[i] = x``                   | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t``                 | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]``                 | same as ``s[i:j] = []``          |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t``               | the elements of ``s[i:j:k]`` are | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]``               | removes the elements of          |                       |\n|                                | ``s[i:j:k]`` from the list       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)``                | same as ``s[len(s):len(s)] =     |                       |\n|                                | [x]``                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)``                | same as ``s[len(s):len(s)] = x`` | (2)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)``                 | return number of *i*\'s for which |                       |\n|                                | ``s[i] == x``                    |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])``       | return smallest *k* such that    | (3)                   |\n|                                | ``s[k] == x`` and ``i <= k < j`` |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)``             | same as ``s[i:i] = [x]``         | (4)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])``                 | same as ``x = s[i]; del s[i];    | (5)                   |\n|                                | return x``                       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)``                | same as ``del s[s.index(x)]``    | (3)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()``                | reverses the items of *s* in     | (6)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])``   | sort the items of *s* in place   | (6), (7), (8)         |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n   index is passed as the second or third parameter to the ``index()``\n   method, the sequence length is added, as for slice indices.  If it\n   is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n   ``insert()`` method, the sequence length is added, as for slice\n   indices.  If it is still negative, it is truncated to zero, as for\n   slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n   the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n   place for economy of space when sorting or reversing a large\n   sequence.  To remind you that they operate by side effect, they\n   don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n   comparisons.  Each must be specified as a keyword argument.\n\n   *key* specifies a function of one argument that is used to extract\n   a comparison key from each list element: ``key=str.lower``.  The\n   default value is ``None``. Use ``functools.cmp_to_key()`` to\n   convert an old-style *cmp* function to a *key* function.\n\n   *reverse* is a boolean value.  If set to ``True``, then the list\n   elements are sorted as if each comparison were reversed.\n\n   The ``sort()`` method is guaranteed to be stable.  A sort is stable\n   if it guarantees not to change the relative order of elements that\n   compare equal --- this is helpful for sorting in multiple passes\n   (for example, sort by department, then by salary grade).\n\n   **CPython implementation detail:** While a list is being sorted,\n   the effect of attempting to mutate, or even inspect, the list is\n   undefined.  The C implementation of Python makes the list appear\n   empty for the duration, and raises ``ValueError`` if it can detect\n   that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n\n\nBytes and Byte Array Methods\n============================\n\nBytes and bytearray objects, being "strings of bytes", have all\nmethods found on strings, with the exception of ``encode()``,\n``format()`` and ``isidentifier()``, which do not make sense with\nthese types.  For converting the objects to strings, they have a\n``decode()`` method.\n\nWherever one of these methods needs to interpret the bytes as\ncharacters (e.g. the ``is...()`` methods), the ASCII character set is\nassumed.\n\nNote: The methods on bytes and bytearray objects don\'t accept strings as\n  their arguments, just as the methods on strings don\'t accept bytes\n  as their arguments.  For example, you have to write\n\n     a = "abc"\n     b = a.replace("a", "f")\n\n  and\n\n     a = b"abc"\n     b = a.replace(b"a", b"f")\n\nbytes.decode(encoding="utf-8", errors="strict")\nbytearray.decode(encoding="utf-8", errors="strict")\n\n   Return a string decoded from the given bytes.  Default encoding is\n   ``\'utf-8\'``. *errors* may be given to set a different error\n   handling scheme.  The default for *errors* is ``\'strict\'``, meaning\n   that encoding errors raise a ``UnicodeError``.  Other possible\n   values are ``\'ignore\'``, ``\'replace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Added support for keyword arguments.\n\nThe bytes and bytearray types have an additional class method:\n\nclassmethod bytes.fromhex(string)\nclassmethod bytearray.fromhex(string)\n\n   This ``bytes`` class method returns a bytes or bytearray object,\n   decoding the given string object.  The string must contain two\n   hexadecimal digits per byte, spaces are ignored.\n\n   >>> bytes.fromhex(\'f0 f1f2  \')\n   b\'\\xf0\\xf1\\xf2\'\n\nThe maketrans and translate methods differ in semantics from the\nversions available on strings:\n\nbytes.translate(table[, delete])\nbytearray.translate(table[, delete])\n\n   Return a copy of the bytes or bytearray object where all bytes\n   occurring in the optional argument *delete* are removed, and the\n   remaining bytes have been mapped through the given translation\n   table, which must be a bytes object of length 256.\n\n   You can use the ``bytes.maketrans()`` method to create a\n   translation table.\n\n   Set the *table* argument to ``None`` for translations that only\n   delete characters:\n\n      >>> b\'read this short text\'.translate(None, b\'aeiou\')\n      b\'rd ths shrt txt\'\n\nstatic bytes.maketrans(from, to)\nstatic bytearray.maketrans(from, to)\n\n   This static method returns a translation table usable for\n   ``bytes.translate()`` that will map each character in *from* into\n   the character at the same position in *to*; *from* and *to* must be\n   bytes objects and have the same length.\n\n   New in version 3.1.\n',
+ 'typesseq': '\nSequence Types --- ``str``, ``bytes``, ``bytearray``, ``list``, ``tuple``, ``range``\n************************************************************************************\n\nThere are six sequence types: strings, byte sequences (``bytes``\nobjects), byte arrays (``bytearray`` objects), lists, tuples, and\nrange objects.  For other containers see the built in ``dict`` and\n``set`` classes, and the ``collections`` module.\n\nStrings contain Unicode characters.  Their literals are written in\nsingle or double quotes: ``\'xyzzy\'``, ``"frobozz"``.  See *String and\nBytes literals* for more about string literals.  In addition to the\nfunctionality described here, there are also string-specific methods\ndescribed in the *String Methods* section.\n\nBytes and bytearray objects contain single bytes -- the former is\nimmutable while the latter is a mutable sequence.  Bytes objects can\nbe constructed the constructor, ``bytes()``, and from literals; use a\n``b`` prefix with normal string syntax: ``b\'xyzzy\'``.  To construct\nbyte arrays, use the ``bytearray()`` function.\n\nWhile string objects are sequences of characters (represented by\nstrings of length 1), bytes and bytearray objects are sequences of\n*integers* (between 0 and 255), representing the ASCII value of single\nbytes.  That means that for a bytes or bytearray object *b*, ``b[0]``\nwill be an integer, while ``b[0:1]`` will be a bytes or bytearray\nobject of length 1.  The representation of bytes objects uses the\nliteral format (``b\'...\'``) since it is generally more useful than\ne.g. ``bytes([50, 19, 100])``.  You can always convert a bytes object\ninto a list of integers using ``list(b)``.\n\nAlso, while in previous Python versions, byte strings and Unicode\nstrings could be exchanged for each other rather freely (barring\nencoding issues), strings and bytes are now completely separate\nconcepts.  There\'s no implicit en-/decoding if you pass an object of\nthe wrong type.  A string always compares unequal to a bytes or\nbytearray object.\n\nLists are constructed with square brackets, separating items with\ncommas: ``[a, b, c]``.  Tuples are constructed by the comma operator\n(not within square brackets), with or without enclosing parentheses,\nbut an empty tuple must have the enclosing parentheses, such as ``a,\nb, c`` or ``()``.  A single item tuple must have a trailing comma,\nsuch as ``(d,)``.\n\nObjects of type range are created using the ``range()`` function.\nThey don\'t support slicing, concatenation or repetition, and using\n``in``, ``not in``, ``min()`` or ``max()`` on them is inefficient.\n\nMost sequence types support the following operations.  The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations.  The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority).  In the table,\n*s* and *t* are sequences of the same type; *n*, *i*, *j* and *k* are\nintegers.\n\n+--------------------+----------------------------------+------------+\n| Operation          | Result                           | Notes      |\n+====================+==================================+============+\n| ``x in s``         | ``True`` if an item of *s* is    | (1)        |\n|                    | equal to *x*, else ``False``     |            |\n+--------------------+----------------------------------+------------+\n| ``x not in s``     | ``False`` if an item of *s* is   | (1)        |\n|                    | equal to *x*, else ``True``      |            |\n+--------------------+----------------------------------+------------+\n| ``s + t``          | the concatenation of *s* and *t* | (6)        |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s``   | *n* shallow copies of *s*        | (2)        |\n|                    | concatenated                     |            |\n+--------------------+----------------------------------+------------+\n| ``s[i]``           | *i*\'th item of *s*, origin 0     | (3)        |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]``         | slice of *s* from *i* to *j*     | (3)(4)     |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]``       | slice of *s* from *i* to *j*     | (3)(5)     |\n|                    | with step *k*                    |            |\n+--------------------+----------------------------------+------------+\n| ``len(s)``         | length of *s*                    |            |\n+--------------------+----------------------------------+------------+\n| ``min(s)``         | smallest item of *s*             |            |\n+--------------------+----------------------------------+------------+\n| ``max(s)``         | largest item of *s*              |            |\n+--------------------+----------------------------------+------------+\n| ``s.index(i)``     | index of the first occurence of  |            |\n|                    | *i* in *s*                       |            |\n+--------------------+----------------------------------+------------+\n| ``s.count(i)``     | total number of occurences of    |            |\n|                    | *i* in *s*                       |            |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons.  In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements.  This means that to compare equal, every element must\ncompare equal and the two sequences must be of the same type and have\nthe same length.  (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string object, the ``in`` and ``not in`` operations\n   act like a substring test.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n   empty sequence of the same type as *s*).  Note also that the copies\n   are shallow; nested structures are not copied.  This often haunts\n   new Python programmers; consider:\n\n   >>> lists = [[]] * 3\n   >>> lists\n   [[], [], []]\n   >>> lists[0].append(3)\n   >>> lists\n   [[3], [3], [3]]\n\n   What has happened is that ``[[]]`` is a one-element list containing\n   an empty list, so all three elements of ``[[]] * 3`` are (pointers\n   to) this single empty list.  Modifying any of the elements of\n   ``lists`` modifies this single list. You can create a list of\n   different lists this way:\n\n   >>> lists = [[] for i in range(3)]\n   >>> lists[0].append(3)\n   >>> lists[1].append(5)\n   >>> lists[2].append(7)\n   >>> lists\n   [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n   string: ``len(s) + i`` or ``len(s) + j`` is substituted.  But note\n   that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n   items with index *k* such that ``i <= k < j``.  If *i* or *j* is\n   greater than ``len(s)``, use ``len(s)``.  If *i* is omitted or\n   ``None``, use ``0``.  If *j* is omitted or ``None``, use\n   ``len(s)``.  If *i* is greater than or equal to *j*, the slice is\n   empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n   sequence of items with index  ``x = i + n*k`` such that ``0 <= n <\n   (j-i)/k``.  In other words, the indices are ``i``, ``i+k``,\n   ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n   never including *j*).  If *i* or *j* is greater than ``len(s)``,\n   use ``len(s)``.  If *i* or *j* are omitted or ``None``, they become\n   "end" values (which end depends on the sign of *k*).  Note, *k*\n   cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n   some Python implementations such as CPython can usually perform an\n   in-place optimization for assignments of the form ``s = s + t`` or\n   ``s += t``.  When applicable, this optimization makes quadratic\n   run-time much less likely.  This optimization is both version and\n   implementation dependent.  For performance sensitive code, it is\n   preferable to use the ``str.join()`` method which assures\n   consistent linear concatenation performance across versions and\n   implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n   Return a copy of the string with its first character capitalized\n   and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n   Return centered in a string of length *width*. Padding is done\n   using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n   Return the number of non-overlapping occurrences of substring *sub*\n   in the range [*start*, *end*].  Optional arguments *start* and\n   *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n   Return an encoded version of the string as a bytes object. Default\n   encoding is ``\'utf-8\'``. *errors* may be given to set a different\n   error handling scheme. The default for *errors* is ``\'strict\'``,\n   meaning that encoding errors raise a ``UnicodeError``. Other\n   possible values are ``\'ignore\'``, ``\'replace\'``,\n   ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n   Return ``True`` if the string ends with the specified *suffix*,\n   otherwise return ``False``.  *suffix* can also be a tuple of\n   suffixes to look for.  With optional *start*, test beginning at\n   that position.  With optional *end*, stop comparing at that\n   position.\n\nstr.expandtabs([tabsize])\n\n   Return a copy of the string where all tab characters are replaced\n   by one or more spaces, depending on the current column and the\n   given tab size.  The column number is reset to zero after each\n   newline occurring in the string. If *tabsize* is not given, a tab\n   size of ``8`` characters is assumed.  This doesn\'t understand other\n   non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n   Return the lowest index in the string where substring *sub* is\n   found, such that *sub* is contained in the slice ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n   Perform a string formatting operation.  The string on which this\n   method is called can contain literal text or replacement fields\n   delimited by braces ``{}``.  Each replacement field contains either\n   the numeric index of a positional argument, or the name of a\n   keyword argument.  Returns a copy of the string where each\n   replacement field is replaced with the string value of the\n   corresponding argument.\n\n   >>> "The sum of 1 + 2 is {0}".format(1+2)\n   \'The sum of 1 + 2 is 3\'\n\n   See *Format String Syntax* for a description of the various\n   formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n   Similar to ``str.format(**mapping)``, except that ``mapping`` is\n   used directly and not copied to a ``dict`` .  This is useful if for\n   example ``mapping`` is a dict subclass:\n\n   >>> class Default(dict):\n   ...     def __missing__(self, key):\n   ...         return key\n   ...\n   >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n   \'Guido was born in country\'\n\n   New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n   Like ``find()``, but raise ``ValueError`` when the substring is not\n   found.\n\nstr.isalnum()\n\n   Return true if all characters in the string are alphanumeric and\n   there is at least one character, false otherwise.\n\nstr.isalpha()\n\n   Return true if all characters in the string are alphabetic and\n   there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n   Return true if all characters in the string are decimal characters\n   and there is at least one character, false otherwise. Decimal\n   characters include digit characters, and all characters that that\n   can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n   INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n   Return true if all characters in the string are digits and there is\n   at least one character, false otherwise.\n\nstr.isidentifier()\n\n   Return true if the string is a valid identifier according to the\n   language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n   Return true if all cased characters in the string are lowercase and\n   there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n   Return true if all characters in the string are numeric characters,\n   and there is at least one character, false otherwise. Numeric\n   characters include digit characters, and all characters that have\n   the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n   ONE FIFTH.\n\nstr.isprintable()\n\n   Return true if all characters in the string are printable or the\n   string is empty, false otherwise.  Nonprintable characters are\n   those characters defined in the Unicode character database as\n   "Other" or "Separator", excepting the ASCII space (0x20) which is\n   considered printable.  (Note that printable characters in this\n   context are those which should not be escaped when ``repr()`` is\n   invoked on a string.  It has no bearing on the handling of strings\n   written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n   Return true if there are only whitespace characters in the string\n   and there is at least one character, false otherwise.\n\nstr.istitle()\n\n   Return true if the string is a titlecased string and there is at\n   least one character, for example uppercase characters may only\n   follow uncased characters and lowercase characters only cased ones.\n   Return false otherwise.\n\nstr.isupper()\n\n   Return true if all cased characters in the string are uppercase and\n   there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n   Return a string which is the concatenation of the strings in the\n   *iterable* *iterable*.  A ``TypeError`` will be raised if there are\n   any non-string values in *seq*, including ``bytes`` objects.  The\n   separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n   Return the string left justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space).  The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.lower()\n\n   Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n   Return a copy of the string with leading characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a prefix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.lstrip()\n   \'spacious   \'\n   >>> \'www.example.com\'.lstrip(\'cmowz.\')\n   \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n   This static method returns a translation table usable for\n   ``str.translate()``.\n\n   If there is only one argument, it must be a dictionary mapping\n   Unicode ordinals (integers) or characters (strings of length 1) to\n   Unicode ordinals, strings (of arbitrary lengths) or None.\n   Character keys will then be converted to ordinals.\n\n   If there are two arguments, they must be strings of equal length,\n   and in the resulting dictionary, each character in x will be mapped\n   to the character at the same position in y.  If there is a third\n   argument, it must be a string, whose characters will be mapped to\n   None in the result.\n\nstr.partition(sep)\n\n   Split the string at the first occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing the string itself, followed by\n   two empty strings.\n\nstr.replace(old, new[, count])\n\n   Return a copy of the string with all occurrences of substring *old*\n   replaced by *new*.  If the optional argument *count* is given, only\n   the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n   Return the highest index in the string where substring *sub* is\n   found, such that *sub* is contained within ``s[start:end]``.\n   Optional arguments *start* and *end* are interpreted as in slice\n   notation.  Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n   Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n   is not found.\n\nstr.rjust(width[, fillchar])\n\n   Return the string right justified in a string of length *width*.\n   Padding is done using the specified *fillchar* (default is a\n   space). The original string is returned if *width* is less than\n   ``len(s)``.\n\nstr.rpartition(sep)\n\n   Split the string at the last occurrence of *sep*, and return a\n   3-tuple containing the part before the separator, the separator\n   itself, and the part after the separator.  If the separator is not\n   found, return a 3-tuple containing two empty strings, followed by\n   the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n   are done, the *rightmost* ones.  If *sep* is not specified or\n   ``None``, any whitespace string is a separator.  Except for\n   splitting from the right, ``rsplit()`` behaves like ``split()``\n   which is described in detail below.\n\nstr.rstrip([chars])\n\n   Return a copy of the string with trailing characters removed.  The\n   *chars* argument is a string specifying the set of characters to be\n   removed.  If omitted or ``None``, the *chars* argument defaults to\n   removing whitespace.  The *chars* argument is not a suffix; rather,\n   all combinations of its values are stripped:\n\n   >>> \'   spacious   \'.rstrip()\n   \'   spacious\'\n   >>> \'mississippi\'.rstrip(\'ipz\')\n   \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n   Return a list of the words in the string, using *sep* as the\n   delimiter string.  If *maxsplit* is given, at most *maxsplit*\n   splits are done (thus, the list will have at most ``maxsplit+1``\n   elements).  If *maxsplit* is not specified, then there is no limit\n   on the number of splits (all possible splits are made).\n\n   If *sep* is given, consecutive delimiters are not grouped together\n   and are deemed to delimit empty strings (for example,\n   ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``).  The *sep*\n   argument may consist of multiple characters (for example,\n   ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n   an empty string with a specified separator returns ``[\'\']``.\n\n   If *sep* is not specified or is ``None``, a different splitting\n   algorithm is applied: runs of consecutive whitespace are regarded\n   as a single separator, and the result will contain no empty strings\n   at the start or end if the string has leading or trailing\n   whitespace.  Consequently, splitting an empty string or a string\n   consisting of just whitespace with a ``None`` separator returns\n   ``[]``.\n\n   For example, ``\' 1  2   3  \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n   and ``\'  1  2   3  \'.split(None, 1)`` returns ``[\'1\', \'2   3  \']``.\n\nstr.splitlines([keepends])\n\n   Return a list of the lines in the string, breaking at line\n   boundaries.  Line breaks are not included in the resulting list\n   unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n   Return ``True`` if string starts with the *prefix*, otherwise\n   return ``False``. *prefix* can also be a tuple of prefixes to look\n   for.  With optional *start*, test string beginning at that\n   position.  With optional *end*, stop comparing string at that\n   position.\n\nstr.strip([chars])\n\n   Return a copy of the string with the leading and trailing\n   characters removed. The *chars* argument is a string specifying the\n   set of characters to be removed. If omitted or ``None``, the\n   *chars* argument defaults to removing whitespace. The *chars*\n   argument is not a prefix or suffix; rather, all combinations of its\n   values are stripped:\n\n   >>> \'   spacious   \'.strip()\n   \'spacious\'\n   >>> \'www.example.com\'.strip(\'cmowz.\')\n   \'example\'\n\nstr.swapcase()\n\n   Return a copy of the string with uppercase characters converted to\n   lowercase and vice versa.\n\nstr.title()\n\n   Return a titlecased version of the string where words start with an\n   uppercase character and the remaining characters are lowercase.\n\n   The algorithm uses a simple language-independent definition of a\n   word as groups of consecutive letters.  The definition works in\n   many contexts but it means that apostrophes in contractions and\n   possessives form word boundaries, which may not be the desired\n   result:\n\n      >>> "they\'re bill\'s friends from the UK".title()\n      "They\'Re Bill\'S Friends From The Uk"\n\n   A workaround for apostrophes can be constructed using regular\n   expressions:\n\n      >>> import re\n      >>> def titlecase(s):\n              return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n                            lambda mo: mo.group(0)[0].upper() +\n                                       mo.group(0)[1:].lower(),\n                            s)\n\n      >>> titlecase("they\'re bill\'s friends.")\n      "They\'re Bill\'s Friends."\n\nstr.transform(encoding, errors=\'strict\')\n\n   Return an encoded version of the string.  In contrast to\n   ``encode()``, this method works with codecs that provide string-to-\n   string mappings, and not string-to-bytes mappings.  ``transform()``\n   therefore returns a string object.\n\n   The codecs that can be used with this method are listed in\n   *Standard Encodings*.\n\n   New in version 3.2.\n\nstr.translate(map)\n\n   Return a copy of the *s* where all characters have been mapped\n   through the *map* which must be a dictionary of Unicode ordinals\n   (integers) to Unicode ordinals, strings or ``None``.  Unmapped\n   characters are left untouched. Characters mapped to ``None`` are\n   deleted.\n\n   You can use ``str.maketrans()`` to create a translation map from\n   character-to-character mappings in different formats.\n\n   Note: An even more flexible approach is to create a custom character\n     mapping codec using the ``codecs`` module (see\n     ``encodings.cp1251`` for an example).\n\nstr.untransform(encoding, errors=\'strict\')\n\n   Return a decoded version of the string.  This provides the reverse\n   operation of ``transform()``.\n\n   New in version 3.2.\n\nstr.upper()\n\n   Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n   Return the numeric string left filled with zeros in a string of\n   length *width*.  A sign prefix is handled correctly.  The original\n   string is returned if *width* is less than ``len(s)``.\n\n\nOld String Formatting Operations\n================================\n\nNote: The formatting operations described here are obsolete and may go\n  away in future versions of Python.  Use the new *String Formatting*\n  in new code.\n\nString objects have one unique built-in operation: the ``%`` operator\n(modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given ``format % values`` (where *format* is\na string), ``%`` conversion specifications in *format* are replaced\nwith zero or more elements of *values*. The effect is similar to the\nusing ``sprintf()`` in the C language.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4]  Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n   characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n   conversion types.\n\n4. Minimum field width (optional).  If specified as an ``\'*\'``\n   (asterisk), the actual width is read from the next element of the\n   tuple in *values*, and the object to convert comes after the\n   minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n   precision.  If specified as ``\'*\'`` (an asterisk), the actual width\n   is read from the next element of the tuple in *values*, and the\n   value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print(\'%(language)s has %(number)03d quote types.\' %\n...       {\'language\': "Python", "number": 2})\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag      | Meaning                                                               |\n+===========+=======================================================================+\n| ``\'#\'``   | The value conversion will use the "alternate form" (where defined     |\n|           | below).                                                               |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'``   | The conversion will be zero padded for numeric values.                |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'``   | The converted value is left adjusted (overrides the ``\'0\'``           |\n|           | conversion if both are given).                                        |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'``   | (a space) A blank should be left before a positive number (or empty   |\n|           | string) produced by a signed conversion.                              |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'``   | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion     |\n|           | (overrides a "space" flag).                                           |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion   | Meaning                                               | Notes   |\n+==============+=======================================================+=========+\n| ``\'d\'``      | Signed integer decimal.                               |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'``      | Signed integer decimal.                               |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'``      | Signed octal value.                                   | (1)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'``      | Obsolete type -- it is identical to ``\'d\'``.          | (7)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'``      | Signed hexadecimal (lowercase).                       | (2)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'``      | Signed hexadecimal (uppercase).                       | (2)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'``      | Floating point exponential format (lowercase).        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'``      | Floating point exponential format (uppercase).        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'``      | Floating point decimal format.                        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'``      | Floating point decimal format.                        | (3)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'``      | Floating point format. Uses lowercase exponential     | (4)     |\n|              | format if exponent is less than -4 or not less than   |         |\n|              | precision, decimal format otherwise.                  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'``      | Floating point format. Uses uppercase exponential     | (4)     |\n|              | format if exponent is less than -4 or not less than   |         |\n|              | precision, decimal format otherwise.                  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'``      | Single character (accepts integer or single character |         |\n|              | string).                                              |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'``      | String (converts any Python object using ``repr()``). | (5)     |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'``      | String (converts any Python object using ``str()``).  |         |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'``      | No argument is converted, results in a ``\'%\'``        |         |\n|              | character in the result.                              |         |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n   between left-hand padding and the formatting of the number if the\n   leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n   on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n   between left-hand padding and the formatting of the number if the\n   leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n   point, even if no digits follow it.\n\n   The precision determines the number of digits after the decimal\n   point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n   point, and trailing zeroes are not removed as they would otherwise\n   be.\n\n   The precision determines the number of significant digits before\n   and after the decimal point and defaults to 6.\n\n5. The precision determines the maximal number of characters used.\n\n1. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 3.1: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nRange Type\n==========\n\nThe ``range`` type is an immutable sequence which is commonly used for\nlooping.  The advantage of the ``range`` type is that an ``range``\nobject will always take the same amount of memory, no matter the size\nof the range it represents.\n\nRange objects have relatively little behavior: they support indexing,\ncontains, iteration, the ``len()`` function, and the following\nmethods:\n\nrange.count(x)\n\n   Return the number of *i*\'s for which ``s[i] == x``.\n\n      New in version 3.2.\n\nrange.index(x)\n\n   Return the smallest *i* such that ``s[i] == x``.  Raises\n   ``ValueError`` when *x* is not in the range.\n\n      New in version 3.2.\n\n\nMutable Sequence Types\n======================\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object.  Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| ``s[i] = x``                   | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t``                 | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]``                 | same as ``s[i:j] = []``          |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t``               | the elements of ``s[i:j:k]`` are | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]``               | removes the elements of          |                       |\n|                                | ``s[i:j:k]`` from the list       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)``                | same as ``s[len(s):len(s)] =     |                       |\n|                                | [x]``                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)``                | same as ``s[len(s):len(s)] = x`` | (2)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)``                 | return number of *i*\'s for which |                       |\n|                                | ``s[i] == x``                    |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])``       | return smallest *k* such that    | (3)                   |\n|                                | ``s[k] == x`` and ``i <= k < j`` |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)``             | same as ``s[i:i] = [x]``         | (4)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])``                 | same as ``x = s[i]; del s[i];    | (5)                   |\n|                                | return x``                       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)``                | same as ``del s[s.index(x)]``    | (3)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()``                | reverses the items of *s* in     | (6)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])``   | sort the items of *s* in place   | (6), (7), (8)         |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n   index is passed as the second or third parameter to the ``index()``\n   method, the sequence length is added, as for slice indices.  If it\n   is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n   ``insert()`` method, the sequence length is added, as for slice\n   indices.  If it is still negative, it is truncated to zero, as for\n   slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n   the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n   place for economy of space when sorting or reversing a large\n   sequence.  To remind you that they operate by side effect, they\n   don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n   comparisons.  Each must be specified as a keyword argument.\n\n   *key* specifies a function of one argument that is used to extract\n   a comparison key from each list element: ``key=str.lower``.  The\n   default value is ``None``. Use ``functools.cmp_to_key()`` to\n   convert an old-style *cmp* function to a *key* function.\n\n   *reverse* is a boolean value.  If set to ``True``, then the list\n   elements are sorted as if each comparison were reversed.\n\n   The ``sort()`` method is guaranteed to be stable.  A sort is stable\n   if it guarantees not to change the relative order of elements that\n   compare equal --- this is helpful for sorting in multiple passes\n   (for example, sort by department, then by salary grade).\n\n   **CPython implementation detail:** While a list is being sorted,\n   the effect of attempting to mutate, or even inspect, the list is\n   undefined.  The C implementation of Python makes the list appear\n   empty for the duration, and raises ``ValueError`` if it can detect\n   that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n\n\nBytes and Byte Array Methods\n============================\n\nBytes and bytearray objects, being "strings of bytes", have all\nmethods found on strings, with the exception of ``encode()``,\n``format()`` and ``isidentifier()``, which do not make sense with\nthese types.  For converting the objects to strings, they have a\n``decode()`` method.\n\nWherever one of these methods needs to interpret the bytes as\ncharacters (e.g. the ``is...()`` methods), the ASCII character set is\nassumed.\n\nNote: The methods on bytes and bytearray objects don\'t accept strings as\n  their arguments, just as the methods on strings don\'t accept bytes\n  as their arguments.  For example, you have to write\n\n     a = "abc"\n     b = a.replace("a", "f")\n\n  and\n\n     a = b"abc"\n     b = a.replace(b"a", b"f")\n\nbytes.decode(encoding="utf-8", errors="strict")\nbytearray.decode(encoding="utf-8", errors="strict")\n\n   Return a string decoded from the given bytes.  Default encoding is\n   ``\'utf-8\'``. *errors* may be given to set a different error\n   handling scheme.  The default for *errors* is ``\'strict\'``, meaning\n   that encoding errors raise a ``UnicodeError``.  Other possible\n   values are ``\'ignore\'``, ``\'replace\'`` and any other name\n   registered via ``codecs.register_error()``, see section *Codec Base\n   Classes*. For a list of possible encodings, see section *Standard\n   Encodings*.\n\n   Changed in version 3.1: Added support for keyword arguments.\n\nThe bytes and bytearray types have an additional class method:\n\nclassmethod bytes.fromhex(string)\nclassmethod bytearray.fromhex(string)\n\n   This ``bytes`` class method returns a bytes or bytearray object,\n   decoding the given string object.  The string must contain two\n   hexadecimal digits per byte, spaces are ignored.\n\n   >>> bytes.fromhex(\'f0 f1f2  \')\n   b\'\\xf0\\xf1\\xf2\'\n\nThe maketrans and translate methods differ in semantics from the\nversions available on strings:\n\nbytes.transform(encoding, errors=\'strict\')\nbytearray.transform(encoding, errors=\'strict\')\n\n   Return an encoded version of the bytes object.  In contrast to\n   ``encode()``, this method works with codecs that provide bytes-to-\n   bytes mappings, and not string-to-bytes mappings.  ``transform()``\n   therefore returns a bytes or bytearray object.\n\n   The codecs that can be used with this method are listed in\n   *Standard Encodings*.\n\n   New in version 3.2.\n\nbytes.translate(table[, delete])\nbytearray.translate(table[, delete])\n\n   Return a copy of the bytes or bytearray object where all bytes\n   occurring in the optional argument *delete* are removed, and the\n   remaining bytes have been mapped through the given translation\n   table, which must be a bytes object of length 256.\n\n   You can use the ``bytes.maketrans()`` method to create a\n   translation table.\n\n   Set the *table* argument to ``None`` for translations that only\n   delete characters:\n\n      >>> b\'read this short text\'.translate(None, b\'aeiou\')\n      b\'rd ths shrt txt\'\n\nbytes.untransform(encoding, errors=\'strict\')\nbytearray.untransform(encoding, errors=\'strict\')\n\n   Return an decoded version of the bytes object.  This provides the\n   reverse operation of ``transform()``.\n\n   New in version 3.2.\n\nstatic bytes.maketrans(from, to)\nstatic bytearray.maketrans(from, to)\n\n   This static method returns a translation table usable for\n   ``bytes.translate()`` that will map each character in *from* into\n   the character at the same position in *to*; *from* and *to* must be\n   bytes objects and have the same length.\n\n   New in version 3.1.\n',
  'typesseq-mutable': '\nMutable Sequence Types\n**********************\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object.  Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation                      | Result                           | Notes                 |\n+================================+==================================+=======================+\n| ``s[i] = x``                   | item *i* of *s* is replaced by   |                       |\n|                                | *x*                              |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t``                 | slice of *s* from *i* to *j* is  |                       |\n|                                | replaced by the contents of the  |                       |\n|                                | iterable *t*                     |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]``                 | same as ``s[i:j] = []``          |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t``               | the elements of ``s[i:j:k]`` are | (1)                   |\n|                                | replaced by those of *t*         |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]``               | removes the elements of          |                       |\n|                                | ``s[i:j:k]`` from the list       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)``                | same as ``s[len(s):len(s)] =     |                       |\n|                                | [x]``                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)``                | same as ``s[len(s):len(s)] = x`` | (2)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)``                 | return number of *i*\'s for which |                       |\n|                                | ``s[i] == x``                    |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])``       | return smallest *k* such that    | (3)                   |\n|                                | ``s[k] == x`` and ``i <= k < j`` |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)``             | same as ``s[i:i] = [x]``         | (4)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])``                 | same as ``x = s[i]; del s[i];    | (5)                   |\n|                                | return x``                       |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)``                | same as ``del s[s.index(x)]``    | (3)                   |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()``                | reverses the items of *s* in     | (6)                   |\n|                                | place                            |                       |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])``   | sort the items of *s* in place   | (6), (7), (8)         |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n   index is passed as the second or third parameter to the ``index()``\n   method, the sequence length is added, as for slice indices.  If it\n   is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n   ``insert()`` method, the sequence length is added, as for slice\n   indices.  If it is still negative, it is truncated to zero, as for\n   slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n   the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n   place for economy of space when sorting or reversing a large\n   sequence.  To remind you that they operate by side effect, they\n   don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n   comparisons.  Each must be specified as a keyword argument.\n\n   *key* specifies a function of one argument that is used to extract\n   a comparison key from each list element: ``key=str.lower``.  The\n   default value is ``None``. Use ``functools.cmp_to_key()`` to\n   convert an old-style *cmp* function to a *key* function.\n\n   *reverse* is a boolean value.  If set to ``True``, then the list\n   elements are sorted as if each comparison were reversed.\n\n   The ``sort()`` method is guaranteed to be stable.  A sort is stable\n   if it guarantees not to change the relative order of elements that\n   compare equal --- this is helpful for sorting in multiple passes\n   (for example, sort by department, then by salary grade).\n\n   **CPython implementation detail:** While a list is being sorted,\n   the effect of attempting to mutate, or even inspect, the list is\n   undefined.  The C implementation of Python makes the list appear\n   empty for the duration, and raises ``ValueError`` if it can detect\n   that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n',
  'unary': '\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n   u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\ninteger argument.  The bitwise inversion of ``x`` is defined as\n``-(x+1)``.  It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n',
  'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n   while_stmt ::= "while" expression ":" suite\n                  ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite.  A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n',

From python-checkins at python.org  Sat Dec  4 20:02:20 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 20:02:20 +0100 (CET)
Subject: [Python-checkins] r87061 -
	python/branches/release27-maint/Doc/library/collections.rst
Message-ID: <20101204190220.64608EE9BD@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 20:02:20 2010
New Revision: 87061

Log:
Add missing label.

Modified:
   python/branches/release27-maint/Doc/library/collections.rst

Modified: python/branches/release27-maint/Doc/library/collections.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/collections.rst	(original)
+++ python/branches/release27-maint/Doc/library/collections.rst	Sat Dec  4 20:02:20 2010
@@ -853,6 +853,8 @@
             OrderedDict.__setitem__(self, key, value)
 
 
+.. _abstract-base-classes:
+
 ABCs - abstract base classes
 ----------------------------
 

From python-checkins at python.org  Sat Dec  4 20:06:15 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 20:06:15 +0100 (CET)
Subject: [Python-checkins] r87062 -
	python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv
Message-ID: <20101204190615.06D9EEE985@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 20:06:14 2010
New Revision: 87062

Log:
Update suspicious exceptions.

Modified:
   python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv

Modified: python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv	(original)
+++ python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv	Sat Dec  4 20:06:14 2010
@@ -324,3 +324,10 @@
 library/configparser,,`,# Set the optional `raw` argument of get() to True if you wish to disable
 library/configparser,,`,# The optional `vars` argument is a dict with members that will take
 library/configparser,,`,# The optional `fallback` argument can be used to provide a fallback value
+library/configparser,,:option,${section:option}
+library/configparser,,:system,path: ${Common:system_dir}/Library/Frameworks/
+library/configparser,,:home,my_dir: ${Common:home_dir}/twosheds
+library/configparser,,:path,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
+library/configparser,,:Python,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}
+library/pdb,,:lineno,[filename:lineno | bpnumber [bpnumber ...]]
+library/pdb,,:lineno,filename:lineno

From python-checkins at python.org  Sat Dec  4 20:06:18 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 20:06:18 +0100 (CET)
Subject: [Python-checkins] r87063 - in python/branches/py3k/Doc/library:
	functions.rst unittest.rst urllib.parse.rst
Message-ID: <20101204190618.DFC7CEE9E1@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 20:06:18 2010
New Revision: 87063

Log:
Fix markup errors.

Modified:
   python/branches/py3k/Doc/library/functions.rst
   python/branches/py3k/Doc/library/unittest.rst
   python/branches/py3k/Doc/library/urllib.parse.rst

Modified: python/branches/py3k/Doc/library/functions.rst
==============================================================================
--- python/branches/py3k/Doc/library/functions.rst	(original)
+++ python/branches/py3k/Doc/library/functions.rst	Sat Dec  4 20:06:18 2010
@@ -454,8 +454,8 @@
       sign: "+" | "-"
       infinity: "Infinity" | "inf"
       nan: "nan"
-      numeric-value: `floatnumber` | `infinity` | `nan`
-      numeric-string: [`sign`] `numeric-value`
+      numeric_value: `floatnumber` | `infinity` | `nan`
+      numeric_string: [`sign`] `numeric_value`
 
    Here ``floatnumber`` is the form of a Python floating-point literal,
    described in :ref:`floating`.  Case is not significant, so, for example,

Modified: python/branches/py3k/Doc/library/unittest.rst
==============================================================================
--- python/branches/py3k/Doc/library/unittest.rst	(original)
+++ python/branches/py3k/Doc/library/unittest.rst	Sat Dec  4 20:06:18 2010
@@ -1879,7 +1879,7 @@
    :ref:`deprecated unittest methods ` are also
    special-cased and, when the warning filters are ``'default'`` or ``'always'``,
    they will appear only once per-module, in order to avoid too many warning
-   messages.  This behavior can be overridden using the :option`-Wd` or
+   messages.  This behavior can be overridden using the :option:`-Wd` or
    :option:`-Wa` options and leaving *warnings* to ``None``.
 
    .. method:: _makeResult()

Modified: python/branches/py3k/Doc/library/urllib.parse.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.parse.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.parse.rst	Sat Dec  4 20:06:18 2010
@@ -316,7 +316,7 @@
 ------------------------
 
 The result objects from the :func:`urlparse`, :func:`urlsplit`  and
-:func:`urldefrag`functions are subclasses of the :class:`tuple` type.
+:func:`urldefrag` functions are subclasses of the :class:`tuple` type.
 These subclasses add the attributes listed in the documentation for
 those functions, the encoding and decoding support described in the
 previous section, as well as an additional method:

From python-checkins at python.org  Sat Dec  4 20:09:24 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat,  4 Dec 2010 20:09:24 +0100 (CET)
Subject: [Python-checkins] r87064 - in python/branches/py3k:
	Include/patchlevel.h Lib/distutils/__init__.py
	Lib/idlelib/idlever.py Misc/NEWS Misc/RPM/python-3.2.spec README
Message-ID: <20101204190924.59CB3EE985@mail.python.org>

Author: georg.brandl
Date: Sat Dec  4 20:09:24 2010
New Revision: 87064

Log:
Bump to 3.2b1.

Modified:
   python/branches/py3k/Include/patchlevel.h
   python/branches/py3k/Lib/distutils/__init__.py
   python/branches/py3k/Lib/idlelib/idlever.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/RPM/python-3.2.spec
   python/branches/py3k/README

Modified: python/branches/py3k/Include/patchlevel.h
==============================================================================
--- python/branches/py3k/Include/patchlevel.h	(original)
+++ python/branches/py3k/Include/patchlevel.h	Sat Dec  4 20:09:24 2010
@@ -19,11 +19,11 @@
 #define PY_MAJOR_VERSION	3
 #define PY_MINOR_VERSION	2
 #define PY_MICRO_VERSION	0
-#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_ALPHA
-#define PY_RELEASE_SERIAL	4
+#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_BETA
+#define PY_RELEASE_SERIAL	1
 
 /* Version as a string */
-#define PY_VERSION      	"3.2a4+"
+#define PY_VERSION      	"3.2b1"
 /*--end constants--*/
 
 /* Subversion Revision number of this file (not of the repository) */

Modified: python/branches/py3k/Lib/distutils/__init__.py
==============================================================================
--- python/branches/py3k/Lib/distutils/__init__.py	(original)
+++ python/branches/py3k/Lib/distutils/__init__.py	Sat Dec  4 20:09:24 2010
@@ -15,5 +15,5 @@
 # Updated automatically by the Python release process.
 #
 #--start constants--
-__version__ = "3.2a4"
+__version__ = "3.2b1"
 #--end constants--

Modified: python/branches/py3k/Lib/idlelib/idlever.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/idlever.py	(original)
+++ python/branches/py3k/Lib/idlelib/idlever.py	Sat Dec  4 20:09:24 2010
@@ -1 +1 @@
-IDLE_VERSION = "3.2a4"
+IDLE_VERSION = "3.2b1"

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Dec  4 20:09:24 2010
@@ -5,26 +5,25 @@
 What's New in Python 3.2 Beta 1?
 ================================
 
-*Release date: XX-Dec-2010*
+*Release date: 05-Dec-2010*
 
 Core and Builtins
 -----------------
 
-- Issue #10596: Fix float.__mod__ to have the same behaviour as
-  float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
-  0.0, not -0.0.
+- Issue #10596: Fix float.__mod__ to have the same behaviour as float.__divmod__
+  with respect to signed zeros.  -4.0 % 4.0 should be 0.0, not -0.0.
 
-- Issue #1772833: Add the -q command-line option to suppress copyright
-  and version output in interactive mode.
+- Issue #1772833: Add the -q command-line option to suppress copyright and
+  version output in interactive mode.
 
 - Provide an *optimize* parameter in the built-in compile() function.
 
-- Fixed several corner case issues on os.stat/os.lstat related to reparse
-  points. (Windows)
+- Fixed several corner case issues on Windows in os.stat/os.lstat related to
+  reparse points.
 
 - PEP 384 (Defining a Stable ABI) is implemented.
 
-- Issue #2690: Range objects support negative indices and slicing
+- Issue #2690: Range objects support negative indices and slicing.
 
 - Issue #9915: Speed up sorting with a key.
 
@@ -56,8 +55,8 @@
 
 - Add the "display" and "undisplay" pdb commands.
 
-- Issue #7245: Add a SIGINT handler in pdb that allows to break a program
-  again after a "continue" command.
+- Issue #7245: Add a SIGINT handler in pdb that allows to break a program again
+  after a "continue" command.
 
 - Add the "interact" pdb command.
 
@@ -260,8 +259,8 @@
 -----
 
 - Issue #10557: Added a new API function, PyUnicode_TransformDecimalToASCII(),
-  which transforms non-ASCII decimal digits in a Unicode string to their
-  ASCII equivalents. 
+  which transforms non-ASCII decimal digits in a Unicode string to their ASCII
+  equivalents.
 
 - Issue #9518: Extend the PyModuleDef_HEAD_INIT macro to explicitly
   zero-initialize all fields, fixing compiler warnings seen when building
@@ -279,10 +278,10 @@
 -----
 
 - regrtest.py once again ensures the test directory is removed from sys.path
-  when it is invoked directly as the __main__ module
+  when it is invoked directly as the __main__ module.
 
-- `python -m test` can be used to run the test suite as well as
-  `python -m test.regrtest`.
+- `python -m test` can be used to run the test suite as well as `python -m
+  test.regrtest`.
 
 - Do not fail test_socket when the IP address of the local hostname cannot be
   looked up.

Modified: python/branches/py3k/Misc/RPM/python-3.2.spec
==============================================================================
--- python/branches/py3k/Misc/RPM/python-3.2.spec	(original)
+++ python/branches/py3k/Misc/RPM/python-3.2.spec	Sat Dec  4 20:09:24 2010
@@ -39,7 +39,7 @@
 
 %define name python
 #--start constants--
-%define version 3.2a4
+%define version 3.2b1
 %define libvers 3.2
 #--end constants--
 %define release 1pydotorg

Modified: python/branches/py3k/README
==============================================================================
--- python/branches/py3k/README	(original)
+++ python/branches/py3k/README	Sat Dec  4 20:09:24 2010
@@ -1,5 +1,5 @@
-This is Python version 3.2 alpha 4
-==================================
+This is Python version 3.2 beta 1
+=================================
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 Python Software Foundation.

From python-checkins at python.org  Sat Dec  4 21:51:36 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sat,  4 Dec 2010 21:51:36 +0100 (CET)
Subject: [Python-checkins] r87065 -
	python/branches/py3k/Doc/library/itertools.rst
Message-ID: <20101204205136.B375DEE9DA@mail.python.org>

Author: raymond.hettinger
Date: Sat Dec  4 21:51:36 2010
New Revision: 87065

Log:
Doc nit.

Modified:
   python/branches/py3k/Doc/library/itertools.rst

Modified: python/branches/py3k/Doc/library/itertools.rst
==============================================================================
--- python/branches/py3k/Doc/library/itertools.rst	(original)
+++ python/branches/py3k/Doc/library/itertools.rst	Sat Dec  4 21:51:36 2010
@@ -96,7 +96,7 @@
             total = next(it)
             yield total
             for element in it:
-                total += element
+                total = total + element
                 yield total
 
     .. versionadded:: 3.2

From python-checkins at python.org  Sat Dec  4 23:56:25 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sat,  4 Dec 2010 23:56:25 +0100 (CET)
Subject: [Python-checkins] r87066 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101204225625.CDFD8EEA29@mail.python.org>

Author: raymond.hettinger
Date: Sat Dec  4 23:56:25 2010
New Revision: 87066

Log:
Fill-in stub for concurrent.futures

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sat Dec  4 23:56:25 2010
@@ -11,7 +11,7 @@
 
    * Anyone can add text to this document.  Do not spend very much time
    on the wording of your changes, because your text will probably
-   get rewritten to some degree.
+   get rewritten.
 
    * The maintainer will go through Misc/NEWS periodically and add
    changes; it's therefore more important to add your changes to
@@ -59,7 +59,7 @@
 Python interpreter internals that extension modules could use.
 
 With Python 3.2, an alternative approach becomes available: extension
-modules with restrict themselves to a limited API (by defining
+modules which restrict themselves to a limited API (by defining
 Py_LIMITED_API) cannot use many of the internals, but are constrained
 to a set of API functions that are promised to be stable for several
 releases. As a consequence, extension modules built for 3.2 in that
@@ -67,6 +67,11 @@
 make use of details of memory structures can still be built, but will
 need to be recompiled for every feature release.
 
+.. seealso::
+
+   :pep:`384` - PYC Repository Directories
+      PEP written by Martin von Loewis.
+
 
 PEP 391:  Dictionary Based Configuration for Logging
 ====================================================
@@ -102,7 +107,7 @@
     "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
 
 
-If that dictionary is stored in a file called "conf.json", it can loaded
+If that dictionary is stored in a file called :file:`conf.json`, it can loaded
 and called with code like this::
 
    >>> import logging.config
@@ -118,7 +123,39 @@
 PEP 3148:  The ``concurrent.futures`` module
 ============================================
 
-.. (Stub section)
+Code for creating and managing concurrency is being collected in a new toplevel
+namespace, *concurrent*.  Its first member is a *futures* package which provides
+a uniform high level interface for managing threads and processes.
+
+The design for :mod:`concurrent.futures` was inspired by
+*java.util.concurrent.package*.  In that model, a running call and its result
+are represented by a :class:`~concurrent.futures.Future` object which abstracts
+features common to threads, processes, and remote procedure calls.  That object
+supports status checks (running or done), timeouts, cancellations, adding
+callbacks, and access to results or exceptions.XS
+
+The primary offering of the new module is a pair of executor classes for
+launching and managing calls.  The goal of the executors is to make it easier to
+use existing tools for making parallel calls. They save the effort needed to
+setup a pool of resources, launch the calls, create a results queue, add
+time-out handling, and limit the total number of threads, processes, or remote
+procedure calls.
+
+Ideally, each application should share a single executor across multiple
+components so that process and thread limits can be centrally managed.  This
+solves the design challenge that arises when each component has its own
+competing strategy for resource management.
+
+For an example of :class:`~concurrent.futures.ThreadPoolExecutor`,
+see :ref:`code for threaded parallel URL reads`.
+
+For an example of :class:`~concurrent.futures.ProcessPoolExecutor`,
+see :ref:`code for computing prime numbers in parallel`.
+
+.. seealso::
+
+   :pep:`3148` - PYC Repository Directories
+      PEP written by Brain Quinlan.
 
 
 PEP 3147:  PYC Repository Directories
@@ -788,4 +825,5 @@
   instead; the new type has a well-defined interface for passing typing safety
   information and a less complicated signature for calling a destructor.
 
- * Remove sys.setfilesystemencoding() function: it was broken by design.
+ * The :func:`sys.setfilesystemencoding` function was removed because
+   it has a flawed design.

From python-checkins at python.org  Sun Dec  5 00:42:13 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 00:42:13 +0100 (CET)
Subject: [Python-checkins] r87067 - in python/branches/py3k/Doc:
	library/random.rst whatsnew/3.2.rst
Message-ID: <20101204234213.0CE84EE9DA@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 00:42:12 2010
New Revision: 87067

Log:
Mention itertools.accumulate().

Modified:
   python/branches/py3k/Doc/library/random.rst
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst	(original)
+++ python/branches/py3k/Doc/library/random.rst	Sun Dec  5 00:42:12 2010
@@ -274,6 +274,7 @@
 * The generator's :meth:`random` method will continue to produce the same
   sequence when the compatible seeder is given the same seed.
 
+.. _random-examples:
 
 Examples and Recipes
 ====================

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 00:42:12 2010
@@ -405,7 +405,8 @@
 
   >>> get_phone_number.cache_clear()
 
-  (Contributed by Raymond Hettinger.)
+  (Contributed by Raymond Hettinger and incorporating design ideas from
+  Jim Baker, Miki Tebeka, and Nick Coglan.)
 
 * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
   pointing to the original callable function.  This allows wrapped functions to
@@ -416,6 +417,22 @@
   (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
   :issue:`8814`.)
 
+* The :mod:`itertools` module has a new function, :func:`~itertools.accumulate`
+  modeled on APL's *scan* and on Numpy's *accumulate* function:
+
+  >>> list(accumulate(8, 2, 50))
+  [8, 10, 60]
+
+  >>> prob_dist = [0.1, 0.4, 0.2, 0.3]
+  >>> list(accumulate(prob_dist))      # cumulative probability distribution
+  [0.1, 0.5, 0.7, 1.0]
+
+  For an example using :func:`~itertools.accumulate`, see the :ref:`examples for
+  the random module `.
+
+  (Contributed by Raymond Hettinger and incorporating design suggestions
+  from Mark Dickinson.)
+
 * The :mod:`nntplib` module gets a revamped implementation with better
   bytes / unicode semantics as well as more practical APIs.  These improvements
   break compatibility with the nntplib version in Python 3.1, which was

From python-checkins at python.org  Sun Dec  5 01:39:18 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 01:39:18 +0100 (CET)
Subject: [Python-checkins] r87068 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205003918.A3D0FEE99D@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 01:39:18 2010
New Revision: 87068

Log:
Start the argparse entry.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 01:39:18 2010
@@ -69,9 +69,30 @@
 
 .. seealso::
 
-   :pep:`384` - PYC Repository Directories
+   :pep:`384` - Define a Stable ABI
       PEP written by Martin von Loewis.
 
+PEP 389: Argparse Command Line Parsing Module
+=============================================
+
+A new module for command line parsing, :mod:`argparse`, was introduced to
+overcome the limitations of :mod:`optparse` which did not provide support for
+positional arguments (not just option), subcommands, required options and other
+common patterns of specifying and validatig options.
+
+This module has already has wide-spread success in the community as a
+third-party module.  Being more fully featured than its predecessor,
+:mod:`argparse`, is now the preferred module for command-line processing.  The
+older module is still being kept available because of the substantial amount of
+legacy code that depends on it.
+
+.. XXX add examples that highlight the new features
+
+.. seealso::
+
+   :pep:`389` - New Command Line Parsing Module
+      PEP written by Steven Bethard.
+
 
 PEP 391:  Dictionary Based Configuration for Logging
 ====================================================
@@ -139,7 +160,7 @@
 use existing tools for making parallel calls. They save the effort needed to
 setup a pool of resources, launch the calls, create a results queue, add
 time-out handling, and limit the total number of threads, processes, or remote
-procedure calls.
+procedure calls. adfasdf
 
 Ideally, each application should share a single executor across multiple
 components so that process and thread limits can be centrally managed.  This
@@ -154,14 +175,14 @@
 
 .. seealso::
 
-   :pep:`3148` - PYC Repository Directories
+   :pep:`3148` - Futures -- Execute Computations Asynchronously
       PEP written by Brain Quinlan.
 
 
 PEP 3147:  PYC Repository Directories
 =====================================
 
-Python's scheme for caching bytecode in *.pyc* files did not work well in
+Python's scheme for caching bytecode in *.pyc* files did not wosrk well in
 environments with multiple python interpreters.  If one interpreter encountered
 a cached file created by another interpreter, it would recompile the source and
 overwrite the cached file, thus losing the benefits of caching.
@@ -376,8 +397,6 @@
 New, Improved, and Deprecated Modules
 =====================================
 
-* XXX mention :mod:`argparse`.
-
 * The :mod:`functools` module includes a new decorator for caching function
   calls.  :func:`functools.lru_cache` can save repeated queries to an external
   resource whenever the results are expected to be the same.
@@ -418,7 +437,7 @@
   :issue:`8814`.)
 
 * The :mod:`itertools` module has a new function, :func:`~itertools.accumulate`
-  modeled on APL's *scan* and on Numpy's *accumulate* function:
+  modeled on APL's *scan* operator and on Numpy's *accumulate* function:
 
   >>> list(accumulate(8, 2, 50))
   [8, 10, 60]
@@ -443,6 +462,10 @@
 * The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
   :func:`~abc.abstractstaticmethod`.
 
+  These tools make it possible to define an :term:`Abstract Base Class` that
+  requires a particular :func:`classmethod` or :func:`staticmethod` to be
+  implemented.
+
   (Patch submitted by Daniel Urban; :issue:`5867`.)
 
 * The previously deprecated :func:`contextlib.nested` function has been removed

From python-checkins at python.org  Sun Dec  5 02:01:52 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 02:01:52 +0100 (CET)
Subject: [Python-checkins] r87069 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205010152.A4A1AEEA24@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 02:01:52 2010
New Revision: 87069

Log:
Optimization of Timsort.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 02:01:52 2010
@@ -160,7 +160,7 @@
 use existing tools for making parallel calls. They save the effort needed to
 setup a pool of resources, launch the calls, create a results queue, add
 time-out handling, and limit the total number of threads, processes, or remote
-procedure calls. adfasdf
+procedure calls.
 
 Ideally, each application should share a single executor across multiple
 components so that process and thread limits can be centrally managed.  This
@@ -298,6 +298,11 @@
 
 Some smaller changes made to the core Python language are:
 
+* The interpreter can now be started with a quiet option, ``-q``, to suppress
+  the copyright and version information in an interactive mode.
+
+  (Contributed by Marcin Wojdyr in issue:`1772833`).
+
 * The :func:`hasattr` function used to catch and suppress any Exception.  Now,
   it only catches :exc:`AttributeError`.  Under the hood, :func:`hasattr` works
   by calling :func:`getattr` and throwing away the results.  This is necessary
@@ -360,9 +365,9 @@
   (See :issue:`4617`.)
 
 * A new warning category, :exc:`ResourceWarning`, has been added.  It is
-  emitted when certain potential issues with resource consumption or cleanup
+  emitted when potential issues with resource consumption or cleanup
   are detected.  It is silenced by default in normal release builds, but
-  can be easily enabled through the means provided by the :mod:`warnings`
+  can be enabled through the means provided by the :mod:`warnings`
   module, or on the command line.
 
   :exc:`ResourceWarning` is issued at interpreter shutdown if the
@@ -761,6 +766,17 @@
   several times faster. (Contributed by Alexandre Vassalotti, Antoine Pitrou
   and the Unladen Swallow team in :issue:`9410` and :issue:`3873`.)
 
+* The `Timsort algorithm `_ used in
+  :meth:`list.sort` and :func:`sorted` now runs faster and used less memory
+  when called with a :term:`key function`.  Previously, every element of
+  a list was wrapped with a temporary object that remembered the key value
+  associated with each element.  Now, an array of keys and values are
+  sorted in parallel.  This save the memory consumed by the sort wrappers,
+  and it saves time lost from during comparisons which where delegated
+  by the sort wrappers.
+
+  (Patch by Daniel Stuzback in :issue:`9915`.)
+
 
 Unicode
 =======

From python-checkins at python.org  Sun Dec  5 03:04:17 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun,  5 Dec 2010 03:04:17 +0100 (CET)
Subject: [Python-checkins] r87070 -
	python/branches/py3k/Lib/test/test_shutil.py
Message-ID: <20101205020417.16069EE9C9@mail.python.org>

Author: hirokazu.yamamoto
Date: Sun Dec  5 03:04:16 2010
New Revision: 87070

Log:
Now can reproduce the error on AMD64 Windows Server 2008
even where os.symlink is not supported.


Modified:
   python/branches/py3k/Lib/test/test_shutil.py

Modified: python/branches/py3k/Lib/test/test_shutil.py
==============================================================================
--- python/branches/py3k/Lib/test/test_shutil.py	(original)
+++ python/branches/py3k/Lib/test/test_shutil.py	Sun Dec  5 03:04:16 2010
@@ -271,25 +271,33 @@
             shutil.rmtree(src_dir)
             shutil.rmtree(os.path.dirname(dst_dir))
 
-    @unittest.skipUnless(hasattr(os, "symlink"),
-                         "Missing symlink implementation")
+    @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
     def test_dont_copy_file_onto_link_to_itself(self):
         # bug 851123.
         os.mkdir(TESTFN)
         src = os.path.join(TESTFN, 'cheese')
         dst = os.path.join(TESTFN, 'shop')
         try:
-            f = open(src, 'w')
-            f.write('cheddar')
-            f.close()
-
-            if hasattr(os, "link"):
-                os.link(src, dst)
-                self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
-                with open(src, 'r') as f:
-                    self.assertEqual(f.read(), 'cheddar')
-                os.remove(dst)
+            with open(src, 'w') as f:
+                f.write('cheddar')
+            os.link(src, dst)
+            self.assertRaises(shutil.Error, shutil.copyfile, src, dst)
+            with open(src, 'r') as f:
+                self.assertEqual(f.read(), 'cheddar')
+            os.remove(dst)
+        finally:
+            shutil.rmtree(TESTFN, ignore_errors=True)
 
+    @unittest.skipUnless(hasattr(os, "symlink"),
+                         "Missing symlink implementation")
+    def test_dont_copy_file_onto_symlink_to_itself(self):
+        # bug 851123.
+        os.mkdir(TESTFN)
+        src = os.path.join(TESTFN, 'cheese')
+        dst = os.path.join(TESTFN, 'shop')
+        try:
+            with open(src, 'w') as f:
+                f.write('cheddar')
             # Using `src` here would mean we end up with a symlink pointing
             # to TESTFN/TESTFN/cheese, while it should point at
             # TESTFN/cheese.
@@ -299,10 +307,7 @@
                 self.assertEqual(f.read(), 'cheddar')
             os.remove(dst)
         finally:
-            try:
-                shutil.rmtree(TESTFN)
-            except OSError:
-                pass
+            shutil.rmtree(TESTFN, ignore_errors=True)
 
     @unittest.skipUnless(hasattr(os, "symlink"),
                          "Missing symlink implementation")

From python-checkins at python.org  Sun Dec  5 03:41:52 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun,  5 Dec 2010 03:41:52 +0100 (CET)
Subject: [Python-checkins] r87071 - python/branches/py3k/Lib/test/test_os.py
Message-ID: <20101205024152.B4CE5EEA10@mail.python.org>

Author: hirokazu.yamamoto
Date: Sun Dec  5 03:41:46 2010
New Revision: 87071

Log:
Avoid possible zombi process.


Modified:
   python/branches/py3k/Lib/test/test_os.py

Modified: python/branches/py3k/Lib/test/test_os.py
==============================================================================
--- python/branches/py3k/Lib/test/test_os.py	(original)
+++ python/branches/py3k/Lib/test/test_os.py	Sun Dec  5 03:41:46 2010
@@ -1106,13 +1106,15 @@
                                 "win_console_handler.py"), tagname],
                    creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
         # Let the interpreter startup before we send signals. See #3137.
-        count, max = 0, 20
+        count, max = 0, 100
         while count < max and proc.poll() is None:
             if m[0] == 1:
                 break
-            time.sleep(0.5)
+            time.sleep(0.1)
             count += 1
         else:
+            # Forcefully kill the process if we weren't able to signal it.
+            os.kill(proc.pid, signal.SIGINT)
             self.fail("Subprocess didn't finish initialization")
         os.kill(proc.pid, event)
         # proc.send_signal(event) could also be done here.

From python-checkins at python.org  Sun Dec  5 03:48:08 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun,  5 Dec 2010 03:48:08 +0100 (CET)
Subject: [Python-checkins] r87072 -
	python/branches/py3k/Modules/posixmodule.c
Message-ID: <20101205024808.293F5EE9E2@mail.python.org>

Author: hirokazu.yamamoto
Date: Sun Dec  5 03:48:08 2010
New Revision: 87072

Log:
Sorry, I had introduced tab in source code.

Modified:
   python/branches/py3k/Modules/posixmodule.c

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Sun Dec  5 03:48:08 2010
@@ -1108,7 +1108,7 @@
     HANDLE hFile;
     BY_HANDLE_FILE_INFORMATION info;
     ULONG reparse_tag = 0;
-	wchar_t *target_path;
+    wchar_t *target_path;
     const char *dot;
 
     if (depth > SYMLOOP_MAX) {

From python-checkins at python.org  Sun Dec  5 03:56:21 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 03:56:21 +0100 (CET)
Subject: [Python-checkins] r87073 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205025621.521A9EE993@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 03:56:21 2010
New Revision: 87073

Log:
Note the updates to range objects.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 03:56:21 2010
@@ -394,9 +394,16 @@
 
   (Added by Antoine Pitrou, :issue:`10093`.)
 
-.. XXX: Issues #9213 and #2690 make the objects returned by range()
-        more sequence like in accordance with their registration as
-        implementing the Sequence ABC
+* :class:`range` objects now support and *index* and *count* methods. This is
+  part of an effort to make more objects fully implement the :class:`collections.Sequence`
+  :term:`abstract base class`.  As a result, the language will have a more
+  uniform API.
+
+  In addition, :class:`range` objects now support slicing and negative indices.
+  This makes *range* more interoperable with lists.
+
+  (Contributed by Daniel Stuzback in :issue:`9213` and by Alexander Belopolsky
+  in :issue:`2690`.)
 
 
 New, Improved, and Deprecated Modules
@@ -730,16 +737,6 @@
 
 A number of small performance enhancements have been added:
 
-* JSON decoding performance is improved and memory consumption is reduced
-  whenever the same string is repeated for multiple keys.
-
-  (Contributed by Antoine Pitrou; :issue:`7451`.)
-
-* JSON encoding now uses the C speedups also when the ``sort_keys`` argument
-  is true.
-
-  (Contributed by Raymond Hettinger and Antoine Pitrou, :issue:`10314`.)
-
 * Python's peephole optimizer now recognizes patterns such ``x in {1, 2, 3}`` as
   being a test for membership in a set of constants.  The optimizer recasts the
   :class:`set` as a :class:`frozenset` and stores the pre-built constant.
@@ -754,16 +751,10 @@
 
   (Patch and additional tests by Dave Malcolm; :issue:`6690`).
 
-* The fast-search algorithm in stringlib is now used by the :meth:`split`,
-  :meth:`rsplit`, :meth:`splitlines` and :meth:`replace` methods on
-  :class:`bytes`, :class:`bytearray` and :class:`str` objects. Likewise, the
-  algorithm is also used by :meth:`rfind`, :meth:`rindex`, :meth:`rsplit` and
-  :meth:`rpartition`.
-
-  (Patch by Florent Xicluna in :issue:`7622` and :issue:`7462`.)
-
 * Serializing and unserializing data using the :mod:`pickle` module is now
-  several times faster. (Contributed by Alexandre Vassalotti, Antoine Pitrou
+  several times faster.
+
+  (Contributed by Alexandre Vassalotti, Antoine Pitrou
   and the Unladen Swallow team in :issue:`9410` and :issue:`3873`.)
 
 * The `Timsort algorithm `_ used in
@@ -777,6 +768,21 @@
 
   (Patch by Daniel Stuzback in :issue:`9915`.)
 
+* JSON decoding performance is improved and memory consumption is reduced
+  whenever the same string is repeated for multiple keys.  Aslo, JSON encoding
+  now uses the C speedups when the ``sort_keys`` argument is true.
+
+  (Contributed by Antoine Pitrou in :issue:`7451` and by Raymond Hettinger and
+  Antoine Pitrou in :issue:`10314`.)
+
+* The fast-search algorithm in stringlib is now used by the :meth:`split`,
+  :meth:`rsplit`, :meth:`splitlines` and :meth:`replace` methods on
+  :class:`bytes`, :class:`bytearray` and :class:`str` objects. Likewise, the
+  algorithm is also used by :meth:`rfind`, :meth:`rindex`, :meth:`rsplit` and
+  :meth:`rpartition`.
+
+  (Patch by Florent Xicluna in :issue:`7622` and :issue:`7462`.)
+
 
 Unicode
 =======
@@ -824,7 +830,8 @@
 .. IDLE
    ====
 
-   * Stub
+* The format menu now has an option to clean-up source files by strip trailing
+  whitespace (:issue:`5150`).
 
 
 Build and C API Changes

From solipsis at pitrou.net  Sun Dec  5 04:50:18 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sun, 05 Dec 2010 04:50:18 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87070): sum=0
Message-ID: 

py3k results for svn r87070 (hg cset 021f9c8e33e0)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogCEjoDy', '-x']

From python-checkins at python.org  Sun Dec  5 05:04:22 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 05:04:22 +0100 (CET)
Subject: [Python-checkins] r87074 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205040422.0FE88EEA0E@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 05:04:21 2010
New Revision: 87074

Log:
Describe the transform/untranform methods

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 05:04:21 2010
@@ -298,6 +298,25 @@
 
 Some smaller changes made to the core Python language are:
 
+* :class:`bytes` and :class:`str` now have two net methods, *tranform* and *untransform*.
+  These provided analogues to *encode* and *decode* but are used for general purpose
+  string-to-string and bytes-to-bytes transformations rather than Unicode codecs.
+
+  Along with the new methods, several non-unicode codecs been restored from Python 2.x
+  including *base64*, *bz2*, *hex*, *quopri*, *rot13*, *uu*, and *zlib*.
+
+  >>> t = b'which witch had which witches wrist watch'
+  >>> t.transform('quopri')
+  b'which=20witch=20had=20which=20witches=20wrist=20watch'
+
+  >>> short = t.transform('zlib_codec')
+  >>> len(t), len(short)
+  (41, 38)
+  >>> short.untransform('zlib_codec')
+  b'which witch had which witches wrist watch'
+
+  (From multiple contributers in :issue:`7475`.)
+
 * The interpreter can now be started with a quiet option, ``-q``, to suppress
   the copyright and version information in an interactive mode.
 

From python-checkins at python.org  Sun Dec  5 05:16:47 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun,  5 Dec 2010 05:16:47 +0100 (CET)
Subject: [Python-checkins] r87075 - in python/branches/py3k:
	Lib/test/test_ntpath.py Modules/posixmodule.c
Message-ID: <20101205041647.9C6BDEEA10@mail.python.org>

Author: hirokazu.yamamoto
Date: Sun Dec  5 05:16:47 2010
New Revision: 87075

Log:
Should use posix_error here.

Modified:
   python/branches/py3k/Lib/test/test_ntpath.py
   python/branches/py3k/Modules/posixmodule.c

Modified: python/branches/py3k/Lib/test/test_ntpath.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ntpath.py	(original)
+++ python/branches/py3k/Lib/test/test_ntpath.py	Sun Dec  5 05:16:47 2010
@@ -248,7 +248,7 @@
             self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
             # Make sure invalid values don't cause issues on win32
             if sys.platform == "win32":
-                with self.assertRaises(ValueError):
+                with self.assertRaises(OSError):
                     # Invalid file descriptors shouldn't display assert
                     # dialogs (#4804)
                     ntpath.sameopenfile(-1, -1)

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Sun Dec  5 05:16:47 2010
@@ -2803,14 +2803,12 @@
     if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
         return NULL;
 
-    if (!_PyVerify_fd(fd)) {
-        PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
-        return NULL;
-    }
+    if (!_PyVerify_fd(fd))
+        return posix_error();
 
     hFile = (HANDLE)_get_osfhandle(fd);
     if (hFile == INVALID_HANDLE_VALUE)
-        return win32_error("_getfileinformation", NULL);
+        return posix_error();
 
     if (!GetFileInformationByHandle(hFile, &info))
         return win32_error("_getfileinformation", NULL);

From python-checkins at python.org  Sun Dec  5 06:39:55 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 06:39:55 +0100 (CET)
Subject: [Python-checkins] r87076 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205053955.1B31CEE9DA@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 06:39:54 2010
New Revision: 87076

Log:
Optimization notes.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 06:39:54 2010
@@ -348,6 +348,11 @@
   the context manager protocol.  This allows timely release of any resources
   that were acquired when requesting a buffer from the original object.
 
+  >>> with memoryview(b'abcdefgh') as v:
+  ...     print(v.tolist())
+  ...
+  [97, 98, 99, 100, 101, 102, 103, 104]
+
   (Added by Antoine Pitrou; :issue:`9757`.)
 
 * Mark Dickinson crafted an elegant and efficient scheme for assuring that
@@ -389,13 +394,11 @@
   can be enabled through the means provided by the :mod:`warnings`
   module, or on the command line.
 
-  :exc:`ResourceWarning` is issued at interpreter shutdown if the
+  A :exc:`ResourceWarning` is issued at interpreter shutdown if the
   :data:`gc.garbage` list isn't empty.  This is meant to make the programmer
   aware that their code contains object finalization issues.
 
-  (Added by Antoine Pitrou and Georg Brandl; :issue:`477863`.)
-
-  :exc:`ResourceWarning` is also issued when a :term:`file object` is destroyed
+  A :exc:`ResourceWarning` is also issued when a :term:`file object` is destroyed
   without having been explicitly closed.  While the deallocator for such
   object ensures it closes the underlying operating system resource
   (usually, a file descriptor), the delay in deallocating the object could
@@ -411,7 +414,7 @@
       __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
       >>>
 
-  (Added by Antoine Pitrou, :issue:`10093`.)
+  (Added by Antoine Pitrou and Georg Brandl in :issue:`10093` and :issue:`477863`.)
 
 * :class:`range` objects now support and *index* and *count* methods. This is
   part of an effort to make more objects fully implement the :class:`collections.Sequence`
@@ -424,6 +427,11 @@
   (Contributed by Daniel Stuzback in :issue:`9213` and by Alexander Belopolsky
   in :issue:`2690`.)
 
+* The :func:`callable` builtin function from Py2.x was resurrected.  It provides
+  a concise, readable alternative to using an :term:`abstract base class` to in
+  an expression like ``isinstance(x, collections.Callable)``.
+
+  (See :issue:`10518`.)
 
 New, Improved, and Deprecated Modules
 =====================================
@@ -802,6 +810,15 @@
 
   (Patch by Florent Xicluna in :issue:`7622` and :issue:`7462`.)
 
+There were several other minor optimizations. Set differencing now runs faster
+when one operand is much larger than the other (Patch by Andress Bennetts in
+:issue:`8685`).  The :meth:`array.repeat` method has a faster implementation
+(:issue:`1569291` by Alexander Belopolsky). The :class:`BaseHTTPRequestHandler`
+has more efficient buffering (:issue:`3709` by Andrew Schaaf).  The
+multi-argument form of :func:`operator.attrgetter` now function runs slightly
+faster (:issue:`10160` by Christos Georgiou).  And :class:`ConfigParser` loads
+multi-line arguments a bit faster (:issue:`7113` by ?ukasz Langa).
+
 
 Unicode
 =======

From python-checkins at python.org  Sun Dec  5 07:35:16 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 07:35:16 +0100 (CET)
Subject: [Python-checkins] r87077 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205063516.E601FEE9DA@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 07:35:16 2010
New Revision: 87077

Log:
New string format character.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 07:35:16 2010
@@ -315,7 +315,20 @@
   >>> short.untransform('zlib_codec')
   b'which witch had which witches wrist watch'
 
-  (From multiple contributers in :issue:`7475`.)
+  (From multiple contributors in :issue:`7475`.)
+
+* String formatting for :func:`format` and :meth:`str.format` gained a new format
+  character **#**.  For integers in binary, octal, or hexadecimal, it causes
+  the output to be prefixed with  '0b', '0o', or '0x' respectively.  For floats,
+  complex, and Decimal, it causes the output to always have a decimal point
+  even when no digits follow it.
+
+  >>> format(20, '#o')
+  '0o24'
+  >>> format(12.34, '#5.0f')
+  '  12.'
+
+  (Suggested by Mark Dickinson and implemented by Eric Smith in :issue:`7094`.)
 
 * The interpreter can now be started with a quiet option, ``-q``, to suppress
   the copyright and version information in an interactive mode.

From python-checkins at python.org  Sun Dec  5 07:45:03 2010
From: python-checkins at python.org (nick.coghlan)
Date: Sun,  5 Dec 2010 07:45:03 +0100 (CET)
Subject: [Python-checkins] r87078 - python/branches/py3k/Lib/test/regrtest.py
Message-ID: <20101205064503.9B884EE99D@mail.python.org>

Author: nick.coghlan
Date: Sun Dec  5 07:45:03 2010
New Revision: 87078

Log:
Issue 10517 investigation: regrtest now checks for alterations to the logging state in the current process (and yes, test_pydoc alters it)

Modified:
   python/branches/py3k/Lib/test/regrtest.py

Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py	(original)
+++ python/branches/py3k/Lib/test/regrtest.py	Sun Dec  5 07:45:03 2010
@@ -167,6 +167,7 @@
 import tempfile
 import platform
 import sysconfig
+import logging
 
 
 # Some times __path__ and __file__ are not absolute (e.g. while running from
@@ -814,7 +815,7 @@
 
     resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr',
                  'os.environ', 'sys.path', 'sys.path_hooks', '__import__',
-                 'warnings.filters', 'asyncore.socket_map')
+                 'warnings.filters', 'asyncore.socket_map', 'logging._handlers')
 
     def get_sys_argv(self):
         return id(sys.argv), sys.argv, sys.argv[:]
@@ -882,6 +883,15 @@
             asyncore.close_all(ignore_all=True)
             asyncore.socket_map.update(saved_map)
 
+    def get_logging__handlers(self):
+        # _handlers is a WeakValueDictionary
+        # _handlerList is a list of weakrefs to handlers
+        return (id(logging._handlers), logging._handlers, logging._handlers.copy(),
+                id(logging._handlerList), logging._handlerList, logging._handlerList[:])
+    def restore_logging__handlers(self, saved_handlers):
+        # Can't easily revert the logging state
+        pass
+
     def resource_info(self):
         for name in self.resources:
             method_suffix = name.replace('.', '_')

From python-checkins at python.org  Sun Dec  5 07:56:04 2010
From: python-checkins at python.org (nick.coghlan)
Date: Sun,  5 Dec 2010 07:56:04 +0100 (CET)
Subject: [Python-checkins] r87078 - svn:log
Message-ID: <20101205065604.D5215EE99D@mail.python.org>

Author: nick.coghlan
Revision: 87078
Property Name: svn:log
Action: modified

Property diff:
--- old property value
+++ new property value
@@ -1 +1 @@
-Issue 10517 investigation: regrtest now checks for alterations to the logging state in the current process (and yes, test_pydoc alters it)
\ No newline at end of file
+Issue 10626 investigation: regrtest now checks for alterations to the logging state in the current process (and yes, test_pydoc alters it)

From python-checkins at python.org  Sun Dec  5 08:02:45 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 08:02:45 +0100 (CET)
Subject: [Python-checkins] r87079 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205070245.28A73EEA74@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 08:02:45 2010
New Revision: 87079

Log:
Update the unittest section.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 08:02:45 2010
@@ -651,23 +651,33 @@
   as recommended in public uses of HTTPS.
   (Added by Antoine Pitrou, :issue:`9003`.)
 
-* Instances of :class:`unittest.TestCase` have two new methods
-  :meth:`~unittest.TestCase.assertWarns` and :meth:`~unittest.TestCase.assertWarnsRegexp`
-  to check that a given warning type was triggered by the code under test::
-
-      with self.assertWarns(DeprecationWarning):
-          legacy_function('XYZ')
-
-* The following :class:`unittest.TestCase` methods are now deprecated:
-   * :meth:`assert_` (use :meth:`.assertTrue` instead);
-   * :meth:`assertEquals` (use :meth:`.assertEqual` instead);
-   * :meth:`assertNotEquals` (use :meth:`.assertNotEqual` instead);
-   * :meth:`assertAlmostEquals` (use :meth:`.assertAlmostEqual` instead);
-   * :meth:`assertNotAlmostEquals` (use :meth:`.assertNotAlmostEqual` instead);
-
-  The ``TestCase.fail*`` methods deprecated in Python 3.1 will be removed in
-  Python 3.3. See also the :ref:`deprecated-aliases` section in the
-  :mod:`unittest` documentation.
+* The command call, ``python -m unittest`` can now accept file paths instead
+  of module names for running specific tests (:issue:`10620`).
+
+* The :mod:`unittest` module has two new methods,
+  :meth:`~unittest.TestCase.assertWarns` and
+  :meth:`~unittest.TestCase.assertWarnsRegex` to check that a given warning type
+  was triggered by the code under test:
+
+  >>> with self.assertWarns(DeprecationWarning):
+  ...     legacy_function('XYZ')
+
+  In addition, the naming in the module has ungone a number of clean-ups.
+  For example, :meth:`assertRegex` is the new name for :meth:`assertRegexpMatches`
+  which was misnamed because the test uses :func:`re.search`, not :func:`re.match`.
+
+  To improve consistency, some of long-standing method aliases are being
+  deprecated in favor of the preferred names:
+
+   - replace :meth:`assert_` with :meth:`.assertTrue`
+   - replace :meth:`assertEquals` with :meth:`.assertEqual`
+   - replace :meth:`assertNotEquals` with :meth:`.assertNotEqual`
+   - replace :meth:`assertAlmostEquals` with :meth:`.assertAlmostEqual`
+   - replace :meth:`assertNotAlmostEquals` with :meth:`.assertNotAlmostEqual`
+
+  Likewise, the ``TestCase.fail*`` methods deprecated in Python 3.1 are expected
+  to be removed in Python 3.3. See also the :ref:`deprecated-aliases` section in
+  the :mod:`unittest` documentation.
 
   (Contributed by Ezio Melotti; :issue:`9424`.)
 

From python-checkins at python.org  Sun Dec  5 08:06:48 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 08:06:48 +0100 (CET)
Subject: [Python-checkins] r87080 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205070648.1CAAFEE99D@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 08:06:47 2010
New Revision: 87080

Log:
Spelling

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 08:06:47 2010
@@ -78,7 +78,7 @@
 A new module for command line parsing, :mod:`argparse`, was introduced to
 overcome the limitations of :mod:`optparse` which did not provide support for
 positional arguments (not just option), subcommands, required options and other
-common patterns of specifying and validatig options.
+common patterns of specifying and validating options.
 
 This module has already has wide-spread success in the community as a
 third-party module.  Being more fully featured than its predecessor,
@@ -657,7 +657,7 @@
 * The :mod:`unittest` module has two new methods,
   :meth:`~unittest.TestCase.assertWarns` and
   :meth:`~unittest.TestCase.assertWarnsRegex` to check that a given warning type
-  was triggered by the code under test:
+  is triggered by the code under test:
 
   >>> with self.assertWarns(DeprecationWarning):
   ...     legacy_function('XYZ')
@@ -819,7 +819,7 @@
   (Patch by Daniel Stuzback in :issue:`9915`.)
 
 * JSON decoding performance is improved and memory consumption is reduced
-  whenever the same string is repeated for multiple keys.  Aslo, JSON encoding
+  whenever the same string is repeated for multiple keys.  Also, JSON encoding
   now uses the C speedups when the ``sort_keys`` argument is true.
 
   (Contributed by Antoine Pitrou in :issue:`7451` and by Raymond Hettinger and

From python-checkins at python.org  Sun Dec  5 08:17:25 2010
From: python-checkins at python.org (nick.coghlan)
Date: Sun,  5 Dec 2010 08:17:25 +0100 (CET)
Subject: [Python-checkins] r87081 - python/branches/py3k/Lib/test/regrtest.py
Message-ID: <20101205071725.E6F07EE99D@mail.python.org>

Author: nick.coghlan
Date: Sun Dec  5 08:17:25 2010
New Revision: 87081

Log:
More fine-grained monitoring of alterations to logging state

Modified:
   python/branches/py3k/Lib/test/regrtest.py

Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py	(original)
+++ python/branches/py3k/Lib/test/regrtest.py	Sun Dec  5 08:17:25 2010
@@ -815,7 +815,8 @@
 
     resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr',
                  'os.environ', 'sys.path', 'sys.path_hooks', '__import__',
-                 'warnings.filters', 'asyncore.socket_map', 'logging._handlers')
+                 'warnings.filters', 'asyncore.socket_map',
+                 'logging._handlers', 'logging._handlerList')
 
     def get_sys_argv(self):
         return id(sys.argv), sys.argv, sys.argv[:]
@@ -885,13 +886,18 @@
 
     def get_logging__handlers(self):
         # _handlers is a WeakValueDictionary
-        # _handlerList is a list of weakrefs to handlers
-        return (id(logging._handlers), logging._handlers, logging._handlers.copy(),
-                id(logging._handlerList), logging._handlerList, logging._handlerList[:])
+        return id(logging._handlers), logging._handlers, logging._handlers.copy()
     def restore_logging__handlers(self, saved_handlers):
         # Can't easily revert the logging state
         pass
 
+    def get_logging__handlerList(self):
+        # _handlerList is a list of weakrefs to handlers
+        return id(logging._handlerList), logging._handlerList, logging._handlerList[:]
+    def restore_logging__handlerList(self, saved_handlerList):
+        # Can't easily revert the logging state
+        pass
+
     def resource_info(self):
         for name in self.resources:
             method_suffix = name.replace('.', '_')

From python-checkins at python.org  Sun Dec  5 08:51:40 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 08:51:40 +0100 (CET)
Subject: [Python-checkins] r87082 -
	python/branches/py3k/Lib/test/test_shutil.py
Message-ID: <20101205075140.2A867EE9C9@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 08:51:39 2010
New Revision: 87082

Log:
Temporarily disable newly failing test for the release.

Modified:
   python/branches/py3k/Lib/test/test_shutil.py

Modified: python/branches/py3k/Lib/test/test_shutil.py
==============================================================================
--- python/branches/py3k/Lib/test/test_shutil.py	(original)
+++ python/branches/py3k/Lib/test/test_shutil.py	Sun Dec  5 08:51:39 2010
@@ -273,6 +273,9 @@
 
     @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
     def test_dont_copy_file_onto_link_to_itself(self):
+        # Temporarily disable test on Windows.
+        if os.name == 'nt':
+            return
         # bug 851123.
         os.mkdir(TESTFN)
         src = os.path.join(TESTFN, 'cheese')

From python-checkins at python.org  Sun Dec  5 08:59:30 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 08:59:30 +0100 (CET)
Subject: [Python-checkins] r87083 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205075930.1D899EE9C9@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 08:59:29 2010
New Revision: 87083

Log:
Apply rest of #10628, and add a few todo comments.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 08:59:29 2010
@@ -234,8 +234,8 @@
       PEP written by Barry Warsaw.
 
 
-PEP 3149 ABI Version Tagged .so Files
-=====================================
+PEP 3149: ABI Version Tagged .so Files
+======================================
 
 The PYC repository directory allows multiple bytecode cache files to be
 co-located.  This PEP implements a similar mechanism for shared object files by
@@ -554,6 +554,8 @@
   (Contributed by Tarek Ziad? and Giampaolo Rodol? in :issue:`4972`, and
   by Georg Brandl in :issue:`8046` and :issue:`1286`.)
 
+.. mention os.popen and subprocess.Popen auto-closing of fds
+
 * :class:`gzip.GzipFile` now implements the :class:`io.BufferedIOBase` ABC
   (except for ``truncate()``), has a :meth:`~gzip.GzipFile.peek` method,
   and supports unseekable as well as zero-padded file objects.
@@ -749,6 +751,14 @@
 
   (Contributed by Ron Adam; :issue:`2001`.)
 
+.. XXX add something about pdb additions:
+
+   * new commands interact, (un)display, longlist, source, until lineno
+   * -c option that executes commands as if given in .pdbrc
+   * SIGINT handler to break a continued program
+
+.. XXX add optimize flags for py_compile/compileall (issue10553)
+
 Multi-threading
 ===============
 

From python-checkins at python.org  Sun Dec  5 09:35:21 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun,  5 Dec 2010 09:35:21 +0100 (CET)
Subject: [Python-checkins] r87084 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205083521.30F1CEEA7B@mail.python.org>

Author: raymond.hettinger
Date: Sun Dec  5 09:35:21 2010
New Revision: 87084

Log:
Nits and todos

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 09:35:21 2010
@@ -317,11 +317,12 @@
 
   (From multiple contributors in :issue:`7475`.)
 
-* String formatting for :func:`format` and :meth:`str.format` gained a new format
-  character **#**.  For integers in binary, octal, or hexadecimal, it causes
-  the output to be prefixed with  '0b', '0o', or '0x' respectively.  For floats,
-  complex, and Decimal, it causes the output to always have a decimal point
-  even when no digits follow it.
+* String formatting for :func:`format` and :meth:`str.format` gained new
+  capabilities for the format character **#**.  Previously, for integers in
+  binary, octal, or hexadecimal, it caused the output to be prefixed with '0b',
+  '0o', or '0x' respectively.  Now it can also handle floats, complex, and
+  Decimal, causing the output to always have a decimal point even when no digits
+  follow it.
 
   >>> format(20, '#o')
   '0o24'
@@ -429,7 +430,7 @@
 
   (Added by Antoine Pitrou and Georg Brandl in :issue:`10093` and :issue:`477863`.)
 
-* :class:`range` objects now support and *index* and *count* methods. This is
+* :class:`range` objects now support *index* and *count* methods. This is
   part of an effort to make more objects fully implement the :class:`collections.Sequence`
   :term:`abstract base class`.  As a result, the language will have a more
   uniform API.
@@ -735,6 +736,8 @@
 
   (Contributed by Rodolpho Eckhardt and Nick Coghlan, :issue:`10220`.)
 
+.. XXX: Create a new section for all changes relating to context managers.
+.. XXX: Various ConfigParser changes
 .. XXX: Mention inspect.getattr_static (Michael Foord)
 .. XXX: Mention urllib.parse changes
           Issue 9873 (Nick Coghlan):

From python-checkins at python.org  Sun Dec  5 10:24:00 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 10:24:00 +0100 (CET)
Subject: [Python-checkins] r87085 - python/tags/r32b1
Message-ID: <20101205092400.BFE2DEEA83@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 10:24:00 2010
New Revision: 87085

Log:
Tagging 3.2b1.


Added:
   python/tags/r32b1/
      - copied from r87084, /python/branches/py3k/

From ncoghlan at gmail.com  Sun Dec  5 10:39:47 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Sun, 5 Dec 2010 19:39:47 +1000
Subject: [Python-checkins] r87066 -
	python/branches/py3k/Doc/whatsnew/3.2.rst
In-Reply-To: <20101204225625.CDFD8EEA29@mail.python.org>
References: <20101204225625.CDFD8EEA29@mail.python.org>
Message-ID: 

On Sun, Dec 5, 2010 at 8:56 AM, raymond.hettinger
 wrote:
> +.. seealso::
> +
> + ? :pep:`384` - PYC Repository Directories
> + ? ? ?PEP written by Martin von Loewis.
> +

The PEP title here should be "Defining a Stable ABI" (I noticed a
later checkin fixing the PEP 3148 see-also title, but I didn't see
anything for this one).

Cheers,
Nick.

-- 
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From python-checkins at python.org  Sun Dec  5 12:40:48 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:40:48 +0100 (CET)
Subject: [Python-checkins] r87086 -
	python/branches/py3k/Include/unicodeobject.h
Message-ID: <20101205114048.85BCEEEA2A@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:40:48 2010
New Revision: 87086

Log:
Take PyUnicode_TransformDecimalToASCII out of the limited API.

Modified:
   python/branches/py3k/Include/unicodeobject.h

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Sun Dec  5 12:40:48 2010
@@ -1231,10 +1231,12 @@
    Returns a new Unicode string on success, NULL on failure.
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_TransformDecimalToASCII(
     Py_UNICODE *s,              /* Unicode buffer */
     Py_ssize_t length           /* Number of Py_UNICODE chars to transform */
     );
+#endif
 
 /* --- File system encoding ---------------------------------------------- */
 

From python-checkins at python.org  Sun Dec  5 12:41:32 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:41:32 +0100 (CET)
Subject: [Python-checkins] r87087 - python/tags/r32b1
Message-ID: <20101205114132.E3275EEA2A@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:41:32 2010
New Revision: 87087

Log:
Remove tag.


Removed:
   python/tags/r32b1/

From python-checkins at python.org  Sun Dec  5 12:42:39 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:42:39 +0100 (CET)
Subject: [Python-checkins] r87088 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101205114239.21F70EEA2A@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:42:38 2010
New Revision: 87088

Log:
Fix title.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec  5 12:42:38 2010
@@ -69,7 +69,7 @@
 
 .. seealso::
 
-   :pep:`384` - Define a Stable ABI
+   :pep:`384` - Defining a Stable ABI
       PEP written by Martin von Loewis.
 
 PEP 389: Argparse Command Line Parsing Module

From python-checkins at python.org  Sun Dec  5 12:45:06 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:45:06 +0100 (CET)
Subject: [Python-checkins] r87089 - python/tags/r32b1
Message-ID: <20101205114506.A596AEEA2A@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:45:06 2010
New Revision: 87089

Log:
Retagging 3.2b1.


Added:
   python/tags/r32b1/
      - copied from r87088, /python/branches/py3k/

From python-checkins at python.org  Sun Dec  5 12:50:41 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:50:41 +0100 (CET)
Subject: [Python-checkins] r87090 - sandbox/trunk/release/release.py
Message-ID: <20101205115041.64BF6EEA2A@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:50:41 2010
New Revision: 87090

Log:
Actually show the keys.

Modified:
   sandbox/trunk/release/release.py

Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py	(original)
+++ sandbox/trunk/release/release.py	Sun Dec  5 12:50:41 2010
@@ -237,7 +237,7 @@
 
     print('Signing tarballs')
     print('List of available private keys:')
-    run_cmd(['gpg -K | grep -A 1 "^sec"'], silent=True)
+    run_cmd(['gpg -K | grep -A 1 "^sec"'])
     uid = input('Please enter key ID to use for signing: ')
     os.system('gpg -bas -u ' + uid + ' ' + tgz)
     os.system('gpg -bas -u ' + uid + ' ' + bz)

From python-checkins at python.org  Sun Dec  5 12:53:06 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 12:53:06 +0100 (CET)
Subject: [Python-checkins] r87091 - sandbox/trunk/release/release.py
Message-ID: <20101205115306.1FEA8EE993@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 12:53:05 2010
New Revision: 87091

Log:
Fix-ups for rename of dist dir.

Modified:
   sandbox/trunk/release/release.py

Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py	(original)
+++ sandbox/trunk/release/release.py	Sun Dec  5 12:53:05 2010
@@ -203,11 +203,11 @@
         os.mkdir(name)
     except OSError:
         if os.path.isdir(name):
-            print('WARNING: dist already exists', file=sys.stderr)
+            print('WARNING: dist dir %s already exists' % name, file=sys.stderr)
         else:
-            error('dist/ is not a directory')
+            error('%s/ is not a directory' % name)
     else:
-        print('created dist directory')
+        print('created dist directory %s' % name)
 
 def tarball(source):
     """Build tarballs for a directory."""
@@ -290,7 +290,8 @@
         os.mkdir('src')
         with changed_dir('src'):
             tarball(os.path.join("..", archivename))
-    print('\n**Now extract the archives in dist/src and run the tests**')
+    print()
+    print('**Now extract the archives in %s/src and run the tests**' % tag.text)
     print('**You may also want to run make install and re-test**')
 
 

From python-checkins at python.org  Sun Dec  5 13:11:52 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun,  5 Dec 2010 13:11:52 +0100 (CET)
Subject: [Python-checkins] r87092 - peps/trunk/pep-0101.txt
Message-ID: <20101205121152.88468EEA9D@mail.python.org>

Author: georg.brandl
Date: Sun Dec  5 13:11:52 2010
New Revision: 87092

Log:
This is actually one step and cannot be done until after the release is up on python.org.

Modified:
   peps/trunk/pep-0101.txt

Modified: peps/trunk/pep-0101.txt
==============================================================================
--- peps/trunk/pep-0101.txt	(original)
+++ peps/trunk/pep-0101.txt	Sun Dec  5 13:11:52 2010
@@ -340,20 +340,6 @@
       freshly unpacked directory looks weird, you better stop now and
       figure out what the problem is.
 
-  ___ For the extra paranoid, do a completely clean test of the
-      release.  This includes downloading the tarball from
-      www.python.org.
-
-  ___ Make sure the md5 checksums match.  Then unpack the tarball,
-      and do a clean make test.
-
-      % make distclean
-      % ./configure
-      % make test
-
-      To ensure that the regression test suite passes.  If not, you
-      screwed up somewhere!
-
   ___ Now you need to go to dinsdale.python.org and move all the files
       in place over there.  Our policy is that every Python version gets its
       own directory, but each directory may contain several releases.  We keep
@@ -401,6 +387,20 @@
           stable/development branches, and to install it and make the initial
           checkout.
 
+  ___ For the extra paranoid, do a completely clean test of the
+      release.  This includes downloading the tarball from
+      www.python.org.
+
+      Make sure the md5 checksums match.  Then unpack the tarball,
+      and do a clean make test.
+
+      % make distclean
+      % ./configure
+      % make test
+
+      To ensure that the regression test suite passes.  If not, you
+      screwed up somewhere!
+
   Now it's time to twiddle the web site.
 
   To do these steps, you must have the permission to edit the website.  If you

From python-checkins at python.org  Mon Dec  6 00:07:59 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Mon,  6 Dec 2010 00:07:59 +0100 (CET)
Subject: [Python-checkins] r87093 - in python/branches/py3k: PC/python3.mak
	PC/python32gen.py PC/python32stub.def PCbuild/pcbuild.sln
	PCbuild/python3dll.vcproj Tools/msi/msi.py
Message-ID: <20101205230759.05063EE9A1@mail.python.org>

Author: martin.v.loewis
Date: Mon Dec  6 00:07:58 2010
New Revision: 87093

Log:
Automate build for python3.dll.
Package missing files.

Added:
   python/branches/py3k/PC/python3.mak
   python/branches/py3k/PC/python32gen.py
   python/branches/py3k/PC/python32stub.def
Modified:
   python/branches/py3k/PCbuild/pcbuild.sln
   python/branches/py3k/PCbuild/python3dll.vcproj
   python/branches/py3k/Tools/msi/msi.py

Added: python/branches/py3k/PC/python3.mak
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/python3.mak	Mon Dec  6 00:07:58 2010
@@ -0,0 +1,10 @@
+$(OutDir)python32.dll:	python3.def $(OutDir)python32stub.lib
+	cl /LD /Fe$(OutDir)python3.dll python3dll.c python3.def $(OutDir)python32stub.lib
+
+$(OutDir)python32stub.lib:	python32stub.def
+	lib /def:python32stub.def /out:$(OutDir)python32stub.lib /MACHINE:$(MACHINE)
+
+clean:
+	del $(OutDir)python3.dll $(OutDir)python3.lib $(OutDir)python32stub.lib $(OutDir)python3.exp $(OutDir)python32stub.exp
+
+rebuild: clean $(OutDir)python32.dll

Added: python/branches/py3k/PC/python32gen.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/python32gen.py	Mon Dec  6 00:07:58 2010
@@ -0,0 +1,25 @@
+# Generate python32stub.def out of python3.def
+# The regular import library cannot be used,
+# since it doesn't provide the right symbols for
+# data forwarding
+out = open("python32stub.def", "w")
+out.write('LIBRARY "python32"\n')
+out.write('EXPORTS\n')
+
+inp = open("python3.def")
+inp.readline()
+line = inp.readline()
+assert line.strip()=='EXPORTS'
+
+for line in inp:
+    # SYM1=python32.SYM2[ DATA]
+    head, tail = line.split('.')
+    if 'DATA' in tail:
+        symbol, tail = tail.split(' ')
+    else:
+        symbol = tail.strip()
+    out.write(symbol+'\n')
+
+inp.close()
+out.close()
+

Added: python/branches/py3k/PC/python32stub.def
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/python32stub.def	Mon Dec  6 00:07:58 2010
@@ -0,0 +1,698 @@
+LIBRARY "python32"
+EXPORTS
+PyArg_Parse
+PyArg_ParseTuple
+PyArg_ParseTupleAndKeywords
+PyArg_UnpackTuple
+PyArg_VaParse
+PyArg_VaParseTupleAndKeywords
+PyArg_ValidateKeywordArguments
+PyBaseObject_Type
+PyBool_FromLong
+PyBool_Type
+PyBuffer_FillContiguousStrides
+PyBuffer_FillInfo
+PyBuffer_FromContiguous
+PyBuffer_GetPointer
+PyBuffer_IsContiguous
+PyBuffer_Release
+PyBuffer_ToContiguous
+PyByteArrayIter_Type
+PyByteArray_AsString
+PyByteArray_Concat
+PyByteArray_FromObject
+PyByteArray_FromStringAndSize
+PyByteArray_Resize
+PyByteArray_Size
+PyByteArray_Type
+PyBytesIter_Type
+PyBytes_AsString
+PyBytes_AsStringAndSize
+PyBytes_Concat
+PyBytes_ConcatAndDel
+PyBytes_DecodeEscape
+PyBytes_FromFormat
+PyBytes_FromFormatV
+PyBytes_FromObject
+PyBytes_FromString
+PyBytes_FromStringAndSize
+PyBytes_Repr
+PyBytes_Size
+PyBytes_Type
+PyCFunction_Call
+PyCFunction_ClearFreeList
+PyCFunction_GetFlags
+PyCFunction_GetFunction
+PyCFunction_GetSelf
+PyCFunction_NewEx
+PyCFunction_Type
+PyCallIter_New
+PyCallIter_Type
+PyCallable_Check
+PyCapsule_GetContext
+PyCapsule_GetDestructor
+PyCapsule_GetName
+PyCapsule_GetPointer
+PyCapsule_Import
+PyCapsule_IsValid
+PyCapsule_New
+PyCapsule_SetContext
+PyCapsule_SetDestructor
+PyCapsule_SetName
+PyCapsule_SetPointer
+PyCapsule_Type
+PyClassMethodDescr_Type
+PyCodec_BackslashReplaceErrors
+PyCodec_Decode
+PyCodec_Decoder
+PyCodec_Encode
+PyCodec_Encoder
+PyCodec_IgnoreErrors
+PyCodec_IncrementalDecoder
+PyCodec_IncrementalEncoder
+PyCodec_KnownEncoding
+PyCodec_LookupError
+PyCodec_Register
+PyCodec_RegisterError
+PyCodec_ReplaceErrors
+PyCodec_StreamReader
+PyCodec_StreamWriter
+PyCodec_StrictErrors
+PyCodec_XMLCharRefReplaceErrors
+PyComplex_FromDoubles
+PyComplex_ImagAsDouble
+PyComplex_RealAsDouble
+PyComplex_Type
+PyDescr_NewClassMethod
+PyDescr_NewGetSet
+PyDescr_NewMember
+PyDescr_NewMethod
+PyDictItems_Type
+PyDictIterItem_Type
+PyDictIterKey_Type
+PyDictIterValue_Type
+PyDictKeys_Type
+PyDictProxy_New
+PyDictProxy_Type
+PyDictValues_Type
+PyDict_Clear
+PyDict_Contains
+PyDict_Copy
+PyDict_DelItem
+PyDict_DelItemString
+PyDict_GetItem
+PyDict_GetItemString
+PyDict_GetItemWithError
+PyDict_Items
+PyDict_Keys
+PyDict_Merge
+PyDict_MergeFromSeq2
+PyDict_New
+PyDict_Next
+PyDict_SetItem
+PyDict_SetItemString
+PyDict_Size
+PyDict_Type
+PyDict_Update
+PyDict_Values
+PyEllipsis_Type
+PyEnum_Type
+PyErr_BadArgument
+PyErr_BadInternalCall
+PyErr_CheckSignals
+PyErr_Clear
+PyErr_Display
+PyErr_ExceptionMatches
+PyErr_Fetch
+PyErr_Format
+PyErr_GivenExceptionMatches
+PyErr_NewException
+PyErr_NewExceptionWithDoc
+PyErr_NoMemory
+PyErr_NormalizeException
+PyErr_Occurred
+PyErr_Print
+PyErr_PrintEx
+PyErr_ProgramText
+PyErr_Restore
+PyErr_SetFromErrno
+PyErr_SetFromErrnoWithFilename
+PyErr_SetFromErrnoWithFilenameObject
+PyErr_SetInterrupt
+PyErr_SetNone
+PyErr_SetObject
+PyErr_SetString
+PyErr_SyntaxLocation
+PyErr_WarnEx
+PyErr_WarnExplicit
+PyErr_WarnFormat
+PyErr_WriteUnraisable
+PyEval_AcquireLock
+PyEval_AcquireThread
+PyEval_CallFunction
+PyEval_CallMethod
+PyEval_CallObjectWithKeywords
+PyEval_EvalCode
+PyEval_EvalCodeEx
+PyEval_EvalFrame
+PyEval_EvalFrameEx
+PyEval_GetBuiltins
+PyEval_GetCallStats
+PyEval_GetFrame
+PyEval_GetFuncDesc
+PyEval_GetFuncName
+PyEval_GetGlobals
+PyEval_GetLocals
+PyEval_InitThreads
+PyEval_ReInitThreads
+PyEval_ReleaseLock
+PyEval_ReleaseThread
+PyEval_RestoreThread
+PyEval_SaveThread
+PyEval_ThreadsInitialized
+PyExc_ArithmeticError
+PyExc_AssertionError
+PyExc_AttributeError
+PyExc_BaseException
+PyExc_BufferError
+PyExc_BytesWarning
+PyExc_DeprecationWarning
+PyExc_EOFError
+PyExc_EnvironmentError
+PyExc_Exception
+PyExc_FloatingPointError
+PyExc_FutureWarning
+PyExc_GeneratorExit
+PyExc_IOError
+PyExc_ImportError
+PyExc_ImportWarning
+PyExc_IndentationError
+PyExc_IndexError
+PyExc_KeyError
+PyExc_KeyboardInterrupt
+PyExc_LookupError
+PyExc_MemoryError
+PyExc_MemoryErrorInst
+PyExc_NameError
+PyExc_NotImplementedError
+PyExc_OSError
+PyExc_OverflowError
+PyExc_PendingDeprecationWarning
+PyExc_RecursionErrorInst
+PyExc_ReferenceError
+PyExc_RuntimeError
+PyExc_RuntimeWarning
+PyExc_StopIteration
+PyExc_SyntaxError
+PyExc_SyntaxWarning
+PyExc_SystemError
+PyExc_SystemExit
+PyExc_TabError
+PyExc_TypeError
+PyExc_UnboundLocalError
+PyExc_UnicodeDecodeError
+PyExc_UnicodeEncodeError
+PyExc_UnicodeError
+PyExc_UnicodeTranslateError
+PyExc_UnicodeWarning
+PyExc_UserWarning
+PyExc_ValueError
+PyExc_Warning
+PyExc_ZeroDivisionError
+PyException_GetCause
+PyException_GetContext
+PyException_GetTraceback
+PyException_SetCause
+PyException_SetContext
+PyException_SetTraceback
+PyFile_FromFd
+PyFile_GetLine
+PyFile_WriteObject
+PyFile_WriteString
+PyFilter_Type
+PyFloat_AsDouble
+PyFloat_FromDouble
+PyFloat_FromString
+PyFloat_GetInfo
+PyFloat_GetMax
+PyFloat_GetMin
+PyFloat_Type
+PyFrozenSet_New
+PyFrozenSet_Type
+PyGC_Collect
+PyGILState_Ensure
+PyGILState_GetThisThreadState
+PyGILState_Release
+PyGetSetDescr_Type
+PyImport_AddModule
+PyImport_AppendInittab
+PyImport_Cleanup
+PyImport_ExecCodeModule
+PyImport_ExecCodeModuleEx
+PyImport_ExecCodeModuleWithPathnames
+PyImport_GetImporter
+PyImport_GetMagicNumber
+PyImport_GetMagicTag
+PyImport_GetModuleDict
+PyImport_Import
+PyImport_ImportFrozenModule
+PyImport_ImportModule
+PyImport_ImportModuleLevel
+PyImport_ImportModuleNoBlock
+PyImport_ReloadModule
+PyInterpreterState_Clear
+PyInterpreterState_Delete
+PyInterpreterState_New
+PyIter_Next
+PyListIter_Type
+PyListRevIter_Type
+PyList_Append
+PyList_AsTuple
+PyList_GetItem
+PyList_GetSlice
+PyList_Insert
+PyList_New
+PyList_Reverse
+PyList_SetItem
+PyList_SetSlice
+PyList_Size
+PyList_Sort
+PyList_Type
+PyLongRangeIter_Type
+PyLong_AsDouble
+PyLong_AsLong
+PyLong_AsLongAndOverflow
+PyLong_AsLongLong
+PyLong_AsLongLongAndOverflow
+PyLong_AsSize_t
+PyLong_AsSsize_t
+PyLong_AsUnsignedLong
+PyLong_AsUnsignedLongLong
+PyLong_AsUnsignedLongLongMask
+PyLong_AsUnsignedLongMask
+PyLong_AsVoidPtr
+PyLong_FromDouble
+PyLong_FromLong
+PyLong_FromLongLong
+PyLong_FromSize_t
+PyLong_FromSsize_t
+PyLong_FromString
+PyLong_FromUnsignedLong
+PyLong_FromUnsignedLongLong
+PyLong_FromVoidPtr
+PyLong_GetInfo
+PyLong_Type
+PyMap_Type
+PyMapping_Check
+PyMapping_GetItemString
+PyMapping_HasKey
+PyMapping_HasKeyString
+PyMapping_Items
+PyMapping_Keys
+PyMapping_Length
+PyMapping_SetItemString
+PyMapping_Size
+PyMapping_Values
+PyMem_Free
+PyMem_Malloc
+PyMem_Realloc
+PyMemberDescr_Type
+PyMemoryView_FromBuffer
+PyMemoryView_FromObject
+PyMemoryView_GetContiguous
+PyMemoryView_Type
+PyMethodDescr_Type
+PyModule_AddIntConstant
+PyModule_AddObject
+PyModule_AddStringConstant
+PyModule_Create2
+PyModule_GetDef
+PyModule_GetDict
+PyModule_GetFilename
+PyModule_GetFilenameObject
+PyModule_GetName
+PyModule_GetState
+PyModule_New
+PyModule_Type
+PyNullImporter_Type
+PyNumber_Absolute
+PyNumber_Add
+PyNumber_And
+PyNumber_AsSsize_t
+PyNumber_Check
+PyNumber_Divmod
+PyNumber_Float
+PyNumber_FloorDivide
+PyNumber_InPlaceAdd
+PyNumber_InPlaceAnd
+PyNumber_InPlaceFloorDivide
+PyNumber_InPlaceLshift
+PyNumber_InPlaceMultiply
+PyNumber_InPlaceOr
+PyNumber_InPlacePower
+PyNumber_InPlaceRemainder
+PyNumber_InPlaceRshift
+PyNumber_InPlaceSubtract
+PyNumber_InPlaceTrueDivide
+PyNumber_InPlaceXor
+PyNumber_Index
+PyNumber_Invert
+PyNumber_Long
+PyNumber_Lshift
+PyNumber_Multiply
+PyNumber_Negative
+PyNumber_Or
+PyNumber_Positive
+PyNumber_Power
+PyNumber_Remainder
+PyNumber_Rshift
+PyNumber_Subtract
+PyNumber_ToBase
+PyNumber_TrueDivide
+PyNumber_Xor
+PyOS_AfterFork
+PyOS_InitInterrupts
+PyOS_InputHook
+PyOS_InterruptOccurred
+PyOS_ReadlineFunctionPointer
+PyOS_double_to_string
+PyOS_getsig
+PyOS_mystricmp
+PyOS_mystrnicmp
+PyOS_setsig
+PyOS_snprintf
+PyOS_string_to_double
+PyOS_strtol
+PyOS_strtoul
+PyOS_vsnprintf
+PyObject_ASCII
+PyObject_AsCharBuffer
+PyObject_AsFileDescriptor
+PyObject_AsReadBuffer
+PyObject_AsWriteBuffer
+PyObject_Bytes
+PyObject_Call
+PyObject_CallFunction
+PyObject_CallFunctionObjArgs
+PyObject_CallMethod
+PyObject_CallMethodObjArgs
+PyObject_CallObject
+PyObject_CheckReadBuffer
+PyObject_ClearWeakRefs
+PyObject_CopyData
+PyObject_DelItem
+PyObject_DelItemString
+PyObject_Dir
+PyObject_Format
+PyObject_Free
+PyObject_GC_Del
+PyObject_GC_Track
+PyObject_GC_UnTrack
+PyObject_GenericGetAttr
+PyObject_GenericSetAttr
+PyObject_GetAttr
+PyObject_GetAttrString
+PyObject_GetBuffer
+PyObject_GetItem
+PyObject_GetIter
+PyObject_HasAttr
+PyObject_HasAttrString
+PyObject_Hash
+PyObject_HashNotImplemented
+PyObject_Init
+PyObject_InitVar
+PyObject_IsInstance
+PyObject_IsSubclass
+PyObject_IsTrue
+PyObject_Length
+PyObject_Malloc
+PyObject_Not
+PyObject_Realloc
+PyObject_Repr
+PyObject_RichCompare
+PyObject_RichCompareBool
+PyObject_SelfIter
+PyObject_SetAttr
+PyObject_SetAttrString
+PyObject_SetItem
+PyObject_Size
+PyObject_Str
+PyObject_Type
+PyParser_SimpleParseFileFlags
+PyParser_SimpleParseStringFlags
+PyProperty_Type
+PyRangeIter_Type
+PyRange_Type
+PyReversed_Type
+PySeqIter_New
+PySeqIter_Type
+PySequence_Check
+PySequence_Concat
+PySequence_Contains
+PySequence_Count
+PySequence_DelItem
+PySequence_DelSlice
+PySequence_Fast
+PySequence_GetItem
+PySequence_GetSlice
+PySequence_In
+PySequence_InPlaceConcat
+PySequence_InPlaceRepeat
+PySequence_Index
+PySequence_Length
+PySequence_List
+PySequence_Repeat
+PySequence_SetItem
+PySequence_SetSlice
+PySequence_Size
+PySequence_Tuple
+PySetIter_Type
+PySet_Add
+PySet_Clear
+PySet_Contains
+PySet_Discard
+PySet_New
+PySet_Pop
+PySet_Size
+PySet_Type
+PySlice_GetIndices
+PySlice_GetIndicesEx
+PySlice_New
+PySlice_Type
+PySortWrapper_Type
+PyState_FindModule
+PyStructSequence_GetItem
+PyStructSequence_New
+PyStructSequence_NewType
+PyStructSequence_SetItem
+PySuper_Type
+PySys_AddWarnOption
+PySys_AddWarnOptionUnicode
+PySys_FormatStderr
+PySys_FormatStdout
+PySys_GetObject
+PySys_HasWarnOptions
+PySys_ResetWarnOptions
+PySys_SetArgv
+PySys_SetArgvEx
+PySys_SetObject
+PySys_SetPath
+PySys_WriteStderr
+PySys_WriteStdout
+PyThreadState_Clear
+PyThreadState_Delete
+PyThreadState_DeleteCurrent
+PyThreadState_Get
+PyThreadState_GetDict
+PyThreadState_New
+PyThreadState_SetAsyncExc
+PyThreadState_Swap
+PyTraceBack_Here
+PyTraceBack_Print
+PyTraceBack_Type
+PyTupleIter_Type
+PyTuple_ClearFreeList
+PyTuple_GetItem
+PyTuple_GetSlice
+PyTuple_New
+PyTuple_Pack
+PyTuple_SetItem
+PyTuple_Size
+PyTuple_Type
+PyType_ClearCache
+PyType_FromSpec
+PyType_GenericAlloc
+PyType_GenericNew
+PyType_IsSubtype
+PyType_Modified
+PyType_Ready
+PyType_Type
+PyUnicodeDecodeError_Create
+PyUnicodeDecodeError_GetEncoding
+PyUnicodeDecodeError_GetEnd
+PyUnicodeDecodeError_GetObject
+PyUnicodeDecodeError_GetReason
+PyUnicodeDecodeError_GetStart
+PyUnicodeDecodeError_SetEnd
+PyUnicodeDecodeError_SetReason
+PyUnicodeDecodeError_SetStart
+PyUnicodeEncodeError_GetEncoding
+PyUnicodeEncodeError_GetEnd
+PyUnicodeEncodeError_GetObject
+PyUnicodeEncodeError_GetReason
+PyUnicodeEncodeError_GetStart
+PyUnicodeEncodeError_SetEnd
+PyUnicodeEncodeError_SetReason
+PyUnicodeEncodeError_SetStart
+PyUnicodeIter_Type
+PyUnicodeTranslateError_GetEnd
+PyUnicodeTranslateError_GetObject
+PyUnicodeTranslateError_GetReason
+PyUnicodeTranslateError_GetStart
+PyUnicodeTranslateError_SetEnd
+PyUnicodeTranslateError_SetReason
+PyUnicodeTranslateError_SetStart
+PyUnicodeUCS2_Append
+PyUnicodeUCS2_AppendAndDel
+PyUnicodeUCS2_AsASCIIString
+PyUnicodeUCS2_AsCharmapString
+PyUnicodeUCS2_AsDecodedObject
+PyUnicodeUCS2_AsDecodedUnicode
+PyUnicodeUCS2_AsEncodedObject
+PyUnicodeUCS2_AsEncodedString
+PyUnicodeUCS2_AsEncodedUnicode
+PyUnicodeUCS2_AsLatin1String
+PyUnicodeUCS2_AsRawUnicodeEscapeString
+PyUnicodeUCS2_AsUTF16String
+PyUnicodeUCS2_AsUTF32String
+PyUnicodeUCS2_AsUTF8String
+PyUnicodeUCS2_AsUnicodeEscapeString
+PyUnicodeUCS2_AsWideChar
+PyUnicodeUCS2_ClearFreelist
+PyUnicodeUCS2_Compare
+PyUnicodeUCS2_Concat
+PyUnicodeUCS2_Contains
+PyUnicodeUCS2_Count
+PyUnicodeUCS2_Decode
+PyUnicodeUCS2_DecodeASCII
+PyUnicodeUCS2_DecodeCharmap
+PyUnicodeUCS2_DecodeFSDefault
+PyUnicodeUCS2_DecodeFSDefaultAndSize
+PyUnicodeUCS2_DecodeLatin1
+PyUnicodeUCS2_DecodeRawUnicodeEscape
+PyUnicodeUCS2_DecodeUTF16
+PyUnicodeUCS2_DecodeUTF16Stateful
+PyUnicodeUCS2_DecodeUTF32
+PyUnicodeUCS2_DecodeUTF32Stateful
+PyUnicodeUCS2_DecodeUTF8
+PyUnicodeUCS2_DecodeUTF8Stateful
+PyUnicodeUCS2_DecodeUnicodeEscape
+PyUnicodeUCS2_FSConverter
+PyUnicodeUCS2_FSDecoder
+PyUnicodeUCS2_Find
+PyUnicodeUCS2_Format
+PyUnicodeUCS2_FromEncodedObject
+PyUnicodeUCS2_FromFormat
+PyUnicodeUCS2_FromFormatV
+PyUnicodeUCS2_FromObject
+PyUnicodeUCS2_FromOrdinal
+PyUnicodeUCS2_FromString
+PyUnicodeUCS2_FromStringAndSize
+PyUnicodeUCS2_FromWideChar
+PyUnicodeUCS2_GetDefaultEncoding
+PyUnicodeUCS2_GetSize
+PyUnicodeUCS2_IsIdentifier
+PyUnicodeUCS2_Join
+PyUnicodeUCS2_Partition
+PyUnicodeUCS2_RPartition
+PyUnicodeUCS2_RSplit
+PyUnicodeUCS2_Replace
+PyUnicodeUCS2_Resize
+PyUnicodeUCS2_RichCompare
+PyUnicodeUCS2_SetDefaultEncoding
+PyUnicodeUCS2_Split
+PyUnicodeUCS2_Splitlines
+PyUnicodeUCS2_Tailmatch
+PyUnicodeUCS2_Translate
+PyUnicode_BuildEncodingMap
+PyUnicode_CompareWithASCIIString
+PyUnicode_DecodeUTF7
+PyUnicode_DecodeUTF7Stateful
+PyUnicode_EncodeFSDefault
+PyUnicode_InternFromString
+PyUnicode_InternImmortal
+PyUnicode_InternInPlace
+PyUnicode_Type
+PyWeakref_GetObject
+PyWeakref_NewProxy
+PyWeakref_NewRef
+PyWrapperDescr_Type
+PyWrapper_New
+PyZip_Type
+Py_AddPendingCall
+Py_AtExit
+Py_BuildValue
+Py_CompileString
+Py_DecRef
+Py_EndInterpreter
+Py_Exit
+Py_FatalError
+Py_FileSystemDefaultEncoding
+Py_Finalize
+Py_GetBuildInfo
+Py_GetCompiler
+Py_GetCopyright
+Py_GetExecPrefix
+Py_GetPath
+Py_GetPlatform
+Py_GetPrefix
+Py_GetProgramFullPath
+Py_GetProgramName
+Py_GetPythonHome
+Py_GetRecursionLimit
+Py_GetVersion
+Py_HasFileSystemDefaultEncoding
+Py_IncRef
+Py_Initialize
+Py_InitializeEx
+Py_IsInitialized
+Py_Main
+Py_MakePendingCalls
+Py_NewInterpreter
+Py_ReprEnter
+Py_ReprLeave
+Py_SetProgramName
+Py_SetPythonHome
+Py_SetRecursionLimit
+Py_SymtableString
+Py_VaBuildValue
+_PyErr_BadInternalCall
+_PyObject_CallFunction_SizeT
+_PyObject_CallMethod_SizeT
+_PyObject_GC_Malloc
+_PyObject_GC_New
+_PyObject_GC_NewVar
+_PyObject_GC_Resize
+_PyObject_New
+_PyObject_NewVar
+_PyState_AddModule
+_PyThreadState_Init
+_PyThreadState_Prealloc
+_PyTrash_delete_later
+_PyTrash_delete_nesting
+_PyTrash_deposit_object
+_PyTrash_destroy_chain
+_PyWeakref_CallableProxyType
+_PyWeakref_ProxyType
+_PyWeakref_RefType
+_Py_BuildValue_SizeT
+_Py_CheckRecursionLimit
+_Py_CheckRecursiveCall
+_Py_Dealloc
+_Py_EllipsisObject
+_Py_FalseStruct
+Py_GetCopyright
+_Py_NotImplementedStruct
+_Py_SwappedOp
+_Py_TrueStruct
+_Py_VaBuildValue_SizeT

Modified: python/branches/py3k/PCbuild/pcbuild.sln
==============================================================================
--- python/branches/py3k/PCbuild/pcbuild.sln	(original)
+++ python/branches/py3k/PCbuild/pcbuild.sln	Mon Dec  6 00:07:58 2010
@@ -73,8 +73,8 @@
 	ProjectSection(ProjectDependencies) = postProject
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
 		{86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480}
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 		{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
@@ -112,8 +112,8 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}"
 	ProjectSection(ProjectDependencies) = postProject
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 		{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}"
@@ -134,9 +134,6 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}"
 EndProject
@@ -560,16 +557,15 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Release|x64
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Release|x64
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Release|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Release|x64
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Release|x64
 		{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32

Modified: python/branches/py3k/PCbuild/python3dll.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/python3dll.vcproj	(original)
+++ python/branches/py3k/PCbuild/python3dll.vcproj	Mon Dec  6 00:07:58 2010
@@ -21,377 +21,117 @@
 	
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 		
 			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
-			
 		
 	
@@ -406,10 +146,58 @@
 			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
 			
 			
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
 			
 		
 		
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
+				
 			
 		
 	

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Mon Dec  6 00:07:58 2010
@@ -1054,6 +1054,10 @@
         if dir=="macholib":
             lib.add_file("README.ctypes")
             lib.glob("fetch_macholib*")
+        if dir=='turtledemo':
+            lib.add_file("turtle.cfg")
+        if dir=="pydoc_data":
+            lib.add_file("_pydoc.css")
         if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email":
             # This should contain all non-.svn files listed in subversion
             for f in os.listdir(lib.absolute):
@@ -1082,6 +1086,7 @@
             continue
         dlls.append(f)
         lib.add_file(f)
+    lib.add_file('python3.dll')
     # Add sqlite
     if msilib.msi_type=="Intel64;1033":
         sqlite_arch = "/ia64"
@@ -1118,6 +1123,7 @@
     for f in dlls:
         lib.add_file(f.replace('pyd','lib'))
     lib.add_file('python%s%s.lib' % (major, minor))
+    lib.add_file('python3.lib')
     # Add the mingw-format library
     if have_mingw:
         lib.add_file('libpython%s%s.a' % (major, minor))

From solipsis at pitrou.net  Mon Dec  6 04:50:40 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Mon, 06 Dec 2010 04:50:40 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87093): sum=0
Message-ID: 

py3k results for svn r87093 (hg cset ff7355285459)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogSt06oy', '-x']

From python-checkins at python.org  Mon Dec  6 05:31:46 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon,  6 Dec 2010 05:31:46 +0100 (CET)
Subject: [Python-checkins] r87094 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101206043146.61EEDEE982@mail.python.org>

Author: raymond.hettinger
Date: Mon Dec  6 05:31:40 2010
New Revision: 87094

Log:
Typo fixups.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Mon Dec  6 05:31:40 2010
@@ -442,8 +442,8 @@
   in :issue:`2690`.)
 
 * The :func:`callable` builtin function from Py2.x was resurrected.  It provides
-  a concise, readable alternative to using an :term:`abstract base class` to in
-  an expression like ``isinstance(x, collections.Callable)``.
+  a concise, readable alternative to using an :term:`abstract base class` in an
+  expression like ``isinstance(x, collections.Callable)``.
 
   (See :issue:`10518`.)
 
@@ -478,7 +478,7 @@
   >>> get_phone_number.cache_clear()
 
   (Contributed by Raymond Hettinger and incorporating design ideas from
-  Jim Baker, Miki Tebeka, and Nick Coglan.)
+  Jim Baker, Miki Tebeka, and Nick Coghlan.)
 
 * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
   pointing to the original callable function.  This allows wrapped functions to

From python-checkins at python.org  Mon Dec  6 19:39:33 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:39:33 +0100 (CET)
Subject: [Python-checkins] r87095 - in python/branches/release31-maint:
	Lib/email/message.py
Message-ID: <20101206183933.1585DEE9D2@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:39:32 2010
New Revision: 87095

Log:
Merged revisions 85130 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85130 | r.david.murray | 2010-09-30 22:08:02 -0400 (Thu, 30 Sep 2010) | 2 lines
  
  Fix a couple spelling errors in comments and delete redundant __len__ def.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/email/message.py

Modified: python/branches/release31-maint/Lib/email/message.py
==============================================================================
--- python/branches/release31-maint/Lib/email/message.py	(original)
+++ python/branches/release31-maint/Lib/email/message.py	Mon Dec  6 19:39:32 2010
@@ -98,7 +98,7 @@
     objects, otherwise it is a string.
 
     Message objects implement part of the `mapping' interface, which assumes
-    there is exactly one occurrance of the header per message.  Some headers
+    there is exactly one occurrence of the header per message.  Some headers
     do in fact appear multiple times (e.g. Received) and for those headers,
     you must use the explicit API to set or get all the headers.  Not all of
     the mapping methods are implemented.
@@ -289,7 +289,7 @@
         Return None if the header is missing instead of raising an exception.
 
         Note that if the header appeared multiple times, exactly which
-        occurrance gets returned is undefined.  Use get_all() to get all
+        occurrence gets returned is undefined.  Use get_all() to get all
         the values matching a header field name.
         """
         return self.get(name)
@@ -321,9 +321,6 @@
         for field, value in self._headers:
             yield field
 
-    def __len__(self):
-        return len(self._headers)
-
     def keys(self):
         """Return a list of all the message's header field names.
 

From python-checkins at python.org  Mon Dec  6 19:45:46 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:45:46 +0100 (CET)
Subject: [Python-checkins] r87096 - in python/branches/release27-maint:
	Lib/email/message.py
Message-ID: <20101206184546.542B1EE9D2@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:45:46 2010
New Revision: 87096

Log:
Merged revisions 85130 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85130 | r.david.murray | 2010-09-30 22:08:02 -0400 (Thu, 30 Sep 2010) | 2 lines
  
  Fix a couple spelling errors in comments and delete redundant __len__ def.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/email/message.py

Modified: python/branches/release27-maint/Lib/email/message.py
==============================================================================
--- python/branches/release27-maint/Lib/email/message.py	(original)
+++ python/branches/release27-maint/Lib/email/message.py	Mon Dec  6 19:45:46 2010
@@ -97,7 +97,7 @@
     objects, otherwise it is a string.
 
     Message objects implement part of the `mapping' interface, which assumes
-    there is exactly one occurrance of the header per message.  Some headers
+    there is exactly one occurrence of the header per message.  Some headers
     do in fact appear multiple times (e.g. Received) and for those headers,
     you must use the explicit API to set or get all the headers.  Not all of
     the mapping methods are implemented.
@@ -286,7 +286,7 @@
         Return None if the header is missing instead of raising an exception.
 
         Note that if the header appeared multiple times, exactly which
-        occurrance gets returned is undefined.  Use get_all() to get all
+        occurrence gets returned is undefined.  Use get_all() to get all
         the values matching a header field name.
         """
         return self.get(name)

From python-checkins at python.org  Mon Dec  6 19:48:11 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:48:11 +0100 (CET)
Subject: [Python-checkins] r87097 - in python/branches/release31-maint:
	Lib/email/generator.py
Message-ID: <20101206184811.B1F2EEE9D2@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:48:11 2010
New Revision: 87097

Log:
Merged revisions 85146 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85146 | r.david.murray | 2010-10-01 16:38:33 -0400 (Fri, 01 Oct 2010) | 3 lines
  
  Fix docstring typo.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/email/generator.py

Modified: python/branches/release31-maint/Lib/email/generator.py
==============================================================================
--- python/branches/release31-maint/Lib/email/generator.py	(original)
+++ python/branches/release31-maint/Lib/email/generator.py	Mon Dec  6 19:48:11 2010
@@ -270,7 +270,7 @@
 _FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]'
 
 class DecodedGenerator(Generator):
-    """Generator a text representation of a message.
+    """Generates a text representation of a message.
 
     Like the Generator base class, except that non-text parts are substituted
     with a format string representing the part.

From python-checkins at python.org  Mon Dec  6 19:48:31 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:48:31 +0100 (CET)
Subject: [Python-checkins] r87098 - in python/branches/release27-maint:
	Lib/email/generator.py
Message-ID: <20101206184831.95988EE9D2@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:48:31 2010
New Revision: 87098

Log:
Merged revisions 85146 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85146 | r.david.murray | 2010-10-01 16:38:33 -0400 (Fri, 01 Oct 2010) | 3 lines
  
  Fix docstring typo.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/email/generator.py

Modified: python/branches/release27-maint/Lib/email/generator.py
==============================================================================
--- python/branches/release27-maint/Lib/email/generator.py	(original)
+++ python/branches/release27-maint/Lib/email/generator.py	Mon Dec  6 19:48:31 2010
@@ -292,7 +292,7 @@
 _FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]'
 
 class DecodedGenerator(Generator):
-    """Generator a text representation of a message.
+    """Generates a text representation of a message.
 
     Like the Generator base class, except that non-text parts are substituted
     with a format string representing the part.

From python-checkins at python.org  Mon Dec  6 19:52:48 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:52:48 +0100 (CET)
Subject: [Python-checkins] r87099 - in python/branches/release31-maint:
	Doc/library/base64.rst
Message-ID: <20101206185248.BFD4DEEAEE@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:52:48 2010
New Revision: 87099

Log:
Merged revisions 85674 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85674 | r.david.murray | 2010-10-17 19:12:16 -0400 (Sun, 17 Oct 2010) | 2 lines
  
  Tighten up 'byte string' wording in base64 docs.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/library/base64.rst

Modified: python/branches/release31-maint/Doc/library/base64.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/base64.rst	(original)
+++ python/branches/release31-maint/Doc/library/base64.rst	Mon Dec  6 19:52:48 2010
@@ -10,21 +10,23 @@
    single: MIME; base64 encoding
 
 This module provides data encoding and decoding as specified in :rfc:`3548`.
-This standard defines the Base16, Base32, and Base64 algorithms for encoding and
-decoding arbitrary binary strings into text strings that can be safely sent by
-email, used as parts of URLs, or included as part of an HTTP POST request.  The
-encoding algorithm is not the same as the :program:`uuencode` program.
-
-There are two interfaces provided by this module.  The modern interface supports
-encoding and decoding string objects using all three alphabets.  The legacy
-interface provides for encoding and decoding to and from file-like objects as
-well as strings, but only using the Base64 standard alphabet.
+This standard defines the Base16, Base32, and Base64 algorithms for encoding
+and decoding arbitrary binary strings into ASCII-only byte strings that can be
+safely sent by email, used as parts of URLs, or included as part of an HTTP
+POST request.  The encoding algorithm is not the same as the
+:program:`uuencode` program.
+
+There are two interfaces provided by this module.  The modern interface
+supports encoding and decoding ASCII byte string objects using all three
+alphabets.  The legacy interface provides for encoding and decoding to and from
+file-like objects as well as byte strings, but only using the Base64 standard
+alphabet.
 
 The modern interface provides:
 
 .. function:: b64encode(s, altchars=None)
 
-   Encode a byte string use Base64.
+   Encode a byte string using Base64.
 
    *s* is the string to encode.  Optional *altchars* must be a string of at least
    length 2 (additional characters are ignored) which specifies an alternative
@@ -39,9 +41,9 @@
 
    Decode a Base64 encoded byte string.
 
-   *s* is the string to decode.  Optional *altchars* must be a string of at least
-   length 2 (additional characters are ignored) which specifies the alternative
-   alphabet used instead of the ``+`` and ``/`` characters.
+   *s* is the byte string to decode.  Optional *altchars* must be a string of
+   at least length 2 (additional characters are ignored) which specifies the
+   alternative alphabet used instead of the ``+`` and ``/`` characters.
 
    The decoded byte string is returned.  A :exc:`TypeError` is raised if *s* were
    incorrectly padded or if there are non-alphabet characters present in the
@@ -81,9 +83,9 @@
 
    Decode a Base32 encoded byte string.
 
-   *s* is the string to decode.  Optional *casefold* is a flag specifying whether a
-   lowercase alphabet is acceptable as input.  For security purposes, the default
-   is ``False``.
+   *s* is the byte string to decode.  Optional *casefold* is a flag specifying
+   whether a lowercase alphabet is acceptable as input.  For security purposes,
+   the default is ``False``.
 
    :rfc:`3548` allows for optional mapping of the digit 0 (zero) to the letter O
    (oh), and for optional mapping of the digit 1 (one) to either the letter I (eye)
@@ -130,8 +132,8 @@
 .. function:: decodebytes(s)
               decodestring(s)
 
-   Decode the bytestring *s*, which must contain one or more lines of base64
-   encoded data, and return a bytestring containing the resulting binary data.
+   Decode the byte string *s*, which must contain one or more lines of base64
+   encoded data, and return a byte string containing the resulting binary data.
    ``decodestring`` is a deprecated alias.
 
 
@@ -147,8 +149,8 @@
 .. function:: encodebytes(s)
               encodestring(s)
 
-   Encode the bytestring *s*, which can contain arbitrary binary data, and
-   return a bytestring containing one or more lines of base64-encoded data.
+   Encode the byte string *s*, which can contain arbitrary binary data, and
+   return a byte string containing one or more lines of base64-encoded data.
    :func:`encodebytes` returns a string containing one or more lines of
    base64-encoded data always including an extra trailing newline (``b'\n'``).
    ``encodestring`` is a deprecated alias.

From python-checkins at python.org  Mon Dec  6 19:53:47 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon,  6 Dec 2010 19:53:47 +0100 (CET)
Subject: [Python-checkins] r87100 - python/branches/release27-maint
Message-ID: <20101206185347.92DFEEEACB@mail.python.org>

Author: r.david.murray
Date: Mon Dec  6 19:53:47 2010
New Revision: 87100

Log:
Blocked revisions 85674 via svnmerge

........
  r85674 | r.david.murray | 2010-10-17 19:12:16 -0400 (Sun, 17 Oct 2010) | 2 lines
  
  Tighten up 'byte string' wording in base64 docs.
........


Modified:
   python/branches/release27-maint/   (props changed)

From python-checkins at python.org  Mon Dec  6 23:02:48 2010
From: python-checkins at python.org (georg.brandl)
Date: Mon,  6 Dec 2010 23:02:48 +0100 (CET)
Subject: [Python-checkins] r87101 -
	python/branches/py3k/Doc/c-api/typeobj.rst
Message-ID: <20101206220248.D26D7EE9A3@mail.python.org>

Author: georg.brandl
Date: Mon Dec  6 23:02:48 2010
New Revision: 87101

Log:
Remove visible XXX comments.

Modified:
   python/branches/py3k/Doc/c-api/typeobj.rst

Modified: python/branches/py3k/Doc/c-api/typeobj.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/typeobj.rst	(original)
+++ python/branches/py3k/Doc/c-api/typeobj.rst	Mon Dec  6 23:02:48 2010
@@ -705,7 +705,9 @@
    This field is not inherited by subtypes (computed attributes are inherited
    through a different mechanism).
 
-   Docs for PyGetSetDef (XXX belong elsewhere)::
+   .. XXX belongs elsewhere
+
+   Docs for PyGetSetDef::
 
       typedef PyObject *(*getter)(PyObject *, void *);
       typedef int (*setter)(PyObject *, PyObject *, void *);
@@ -752,7 +754,7 @@
 
       PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
 
-   XXX explain.
+   .. XXX explain.
 
    This field is inherited by subtypes.
 
@@ -767,7 +769,7 @@
 
    This field is inherited by subtypes.
 
-   XXX explain.
+   .. XXX explain.
 
 
 .. c:member:: long PyTypeObject.tp_dictoffset

From python-checkins at python.org  Mon Dec  6 23:25:26 2010
From: python-checkins at python.org (georg.brandl)
Date: Mon,  6 Dec 2010 23:25:26 +0100 (CET)
Subject: [Python-checkins] r87102 -
	python/branches/py3k/Lib/encodings/base64_codec.py
Message-ID: <20101206222526.0E7F6EEABF@mail.python.org>

Author: georg.brandl
Date: Mon Dec  6 23:25:25 2010
New Revision: 87102

Log:
Don't use deprecated aliases.

Modified:
   python/branches/py3k/Lib/encodings/base64_codec.py

Modified: python/branches/py3k/Lib/encodings/base64_codec.py
==============================================================================
--- python/branches/py3k/Lib/encodings/base64_codec.py	(original)
+++ python/branches/py3k/Lib/encodings/base64_codec.py	Mon Dec  6 23:25:25 2010
@@ -13,11 +13,11 @@
 
 def base64_encode(input, errors='strict'):
     assert errors == 'strict'
-    return (base64.encodestring(input), len(input))
+    return (base64.encodebytes(input), len(input))
 
 def base64_decode(input, errors='strict'):
     assert errors == 'strict'
-    return (base64.decodestring(input), len(input))
+    return (base64.decodebytes(input), len(input))
 
 class Codec(codecs.Codec):
     def encode(self, input, errors='strict'):
@@ -28,12 +28,12 @@
 class IncrementalEncoder(codecs.IncrementalEncoder):
     def encode(self, input, final=False):
         assert self.errors == 'strict'
-        return base64.encodestring(input)
+        return base64.encodebytes(input)
 
 class IncrementalDecoder(codecs.IncrementalDecoder):
     def decode(self, input, final=False):
         assert self.errors == 'strict'
-        return base64.decodestring(input)
+        return base64.decodebytes(input)
 
 class StreamWriter(Codec, codecs.StreamWriter):
     charbuffertype = bytes

From python-checkins at python.org  Tue Dec  7 00:31:37 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 00:31:37 +0100 (CET)
Subject: [Python-checkins] r87103 - in python/branches/py3k/Doc:
	library/itertools.rst library/re.rst whatsnew/3.2.rst
Message-ID: <20101206233137.8D64EEEA9B@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 00:31:36 2010
New Revision: 87103

Log:
Note improvements to the docs.

Modified:
   python/branches/py3k/Doc/library/itertools.rst
   python/branches/py3k/Doc/library/re.rst
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/library/itertools.rst
==============================================================================
--- python/branches/py3k/Doc/library/itertools.rst	(original)
+++ python/branches/py3k/Doc/library/itertools.rst	Tue Dec  7 00:31:36 2010
@@ -577,8 +577,8 @@
 
 .. _itertools-recipes:
 
-Recipes
--------
+Itertools Recipes
+-----------------
 
 This section shows recipes for creating an extended toolset using the existing
 itertools as building blocks.

Modified: python/branches/py3k/Doc/library/re.rst
==============================================================================
--- python/branches/py3k/Doc/library/re.rst	(original)
+++ python/branches/py3k/Doc/library/re.rst	Tue Dec  7 00:31:36 2010
@@ -991,8 +991,10 @@
    The string passed to :meth:`~regex.match` or :meth:`~regex.search`.
 
 
-Examples
---------
+.. _re-examples:
+
+Regular Expression Examples
+---------------------------
 
 
 Checking For a Pair

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 00:31:36 2010
@@ -899,8 +899,28 @@
 systems.
 
 
-.. IDLE
-   ====
+Documentation
+=============
+
+The documentation continues to be improved.
+
+A table of quick links has been added to the top of lengthy sections such as
+:ref:`built-in-funcs`.  In the case of :mod:`itertools`, the links are
+accompanied by tables of cheatsheet-style summaries to provide an overview and
+memory jog without having to read all of the docs.
+
+In some cases, the pure python source code can be helpful adjunct to the docs,
+so now some modules feature quick links to the latest version of the source
+code.  For example, the :mod:`functools` module documentation has a quick link
+at the top labeled :source:`functools Python source code `.
+
+The docs now contain more examples and recipes.  In particular, :mod:`re` module
+has an extensive section, :ref:`re-examples`.  Likewise, the :mod:`itertools`
+module continues to be updated with new :ref:`itertools-recipes`.
+
+
+IDLE
+====
 
 * The format menu now has an option to clean-up source files by strip trailing
   whitespace (:issue:`5150`).
@@ -933,7 +953,10 @@
 
 * Hash values are now values of a new type, Py_hash_t, which is defined to
   be the same size as a pointer.  Previously they were of type long, which
-  on some 64-bit operating systems is still only 32 bits long.
+  on some 64-bit operating systems is still only 32 bits long.  As a result
+  of this fix, :class:`set` and :class:`dict` can now hold more than ``2**32``
+  entries on builds with 64-bit pointers (previously, they could grow to
+  that size but their performance degraded catastrophically).
 
   (Contributed by Benjamin Peterson; :issue:`9778`.)
 
@@ -947,8 +970,8 @@
 * The :mod:`nntplib` module was reworked extensively, meaning that its APIs
   are often incompatible with the 3.1 APIs.
 
-* :class:`bytearray` objects cannot be used any more as filenames: convert them
-  to :class:`bytes`.
+* :class:`bytearray` objects can no longer be used as filenames; instead,
+  they should be converted to :class:`bytes`.
 
 * PyArg_Parse*() functions:
 
@@ -961,4 +984,4 @@
   information and a less complicated signature for calling a destructor.
 
  * The :func:`sys.setfilesystemencoding` function was removed because
-   it has a flawed design.
+   it had a flawed design.

From python-checkins at python.org  Tue Dec  7 01:32:04 2010
From: python-checkins at python.org (david.malcolm)
Date: Tue,  7 Dec 2010 01:32:04 +0100 (CET)
Subject: [Python-checkins] r87104 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207003204.C65E6EEAC1@mail.python.org>

Author: david.malcolm
Date: Tue Dec  7 01:32:04 2010
New Revision: 87104

Log:
Fix typo


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 01:32:04 2010
@@ -182,7 +182,7 @@
 PEP 3147:  PYC Repository Directories
 =====================================
 
-Python's scheme for caching bytecode in *.pyc* files did not wosrk well in
+Python's scheme for caching bytecode in *.pyc* files did not work well in
 environments with multiple python interpreters.  If one interpreter encountered
 a cached file created by another interpreter, it would recompile the source and
 overwrite the cached file, thus losing the benefits of caching.

From python-checkins at python.org  Tue Dec  7 02:47:52 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 02:47:52 +0100 (CET)
Subject: [Python-checkins] r87105 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207014752.EBBBFEE99D@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 02:47:52 2010
New Revision: 87105

Log:
Add entry for the new sysconfig module.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 02:47:52 2010
@@ -762,6 +762,65 @@
 
 .. XXX add optimize flags for py_compile/compileall (issue10553)
 
+* The new :mod:`sysconfig` module makes it straight-forward to discover
+  installation paths and configuration variables which vary across platforms and
+  installs.
+
+  The module offers access simple access functions for platform and version
+  information:
+
+  * :func:`~sysconfig.get_platform` returning values like *linux-i586* or
+    *macosx-10.6-ppc*.
+  * :func:`~sysconfig.get_python_version` returns a Python version string in
+    the form, "3.2".
+
+  It also provides access to the paths and variables corresponding to one of
+  seven named schemes used by :mod:`distutils`.  Those include *posix_prefix*,
+  *posix_home*, *posix_user*, *nt*, *nt_user*, *os2*, *os2_home*:
+
+  * :func:`~sysconfig.get_paths` makes a dictionary containing installation paths
+    for the current installation scheme.
+  * :func:`~sysconfig.get_config_vars` returns a dictionary of platform specific
+    variables.
+
+  There is also a convenient command-line interface::
+
+    C:\Python32>python -m sysconfig
+    Platform: "win32"
+    Python version: "3.2"
+    Current installation scheme: "nt"
+
+    Paths:
+            data = "C:\Python32"
+            include = "C:\Python32\Include"
+            platinclude = "C:\Python32\Include"
+            platlib = "C:\Python32\Lib\site-packages"
+            platstdlib = "C:\Python32\Lib"
+            purelib = "C:\Python32\Lib\site-packages"
+            scripts = "C:\Python32\Scripts"
+            stdlib = "C:\Python32\Lib"
+
+    Variables:
+            BINDIR = "C:\Python32"
+            BINLIBDEST = "C:\Python32\Lib"
+            EXE = ".exe"
+            INCLUDEPY = "C:\Python32\Include"
+            LIBDEST = "C:\Python32\Lib"
+            SO = ".pyd"
+            VERSION = "32"
+            abiflags = ""
+            base = "C:\Python32"
+            exec_prefix = "C:\Python32"
+            platbase = "C:\Python32"
+            prefix = "C:\Python32"
+            projectbase = "C:\Python32"
+            py_version = "3.2b1"
+            py_version_nodot = "32"
+            py_version_short = "3.2"
+            srcdir = "C:\Python32"
+            userbase = "C:\Documents and Settings\Raymond\Application Data\Python"
+
+
 Multi-threading
 ===============
 

From python-checkins at python.org  Tue Dec  7 03:04:56 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 03:04:56 +0100 (CET)
Subject: [Python-checkins] r87106 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207020456.9D72CEE98A@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 03:04:56 2010
New Revision: 87106

Log:
Add entry for new pdb features

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 03:04:56 2010
@@ -820,6 +820,21 @@
             srcdir = "C:\Python32"
             userbase = "C:\Documents and Settings\Raymond\Application Data\Python"
 
+* The :mod:`pdb` debugger module gained a number of usability improvements:
+
+  - :file:`pdb.py` now has a ``-c`` option that executes commands as given in a
+    :file:`.pdbrc` script file.
+  - A :file:`.pdbrc` script file can contain ``continue`` and ``next`` commands
+    that continue debugging.
+  - The :class:`Pdb` class constructor now accepts a *nosigint* argument.
+  - new commands: ``l(list)``, ``ll(long list`` and ``source`` for
+    listing source code.
+  - new commands: ``display`` and ``undisplay`` for showing or hiding
+    the value of an expression if it has changed.
+  - new command: ``interact`` for starting an interative interpreter containing
+    the global and local  names found in the current scope.
+  - breakpoints can be cleared by breakpoint number
+
 
 Multi-threading
 ===============

From python-checkins at python.org  Tue Dec  7 04:46:27 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Tue,  7 Dec 2010 04:46:27 +0100 (CET)
Subject: [Python-checkins] r87107 - in python/branches/py3k:
	Lib/test/test_descr.py Objects/descrobject.c
Message-ID: <20101207034627.D7A04EE98A@mail.python.org>

Author: benjamin.peterson
Date: Tue Dec  7 04:46:27 2010
New Revision: 87107

Log:
return views from dict proxy items/values/keys #10630

Modified:
   python/branches/py3k/Lib/test/test_descr.py
   python/branches/py3k/Objects/descrobject.c

Modified: python/branches/py3k/Lib/test/test_descr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_descr.py	(original)
+++ python/branches/py3k/Lib/test/test_descr.py	Tue Dec  7 04:46:27 2010
@@ -4233,20 +4233,26 @@
         self.C = C
 
     def test_iter_keys(self):
-        # Testing dict-proxy iterkeys...
-        keys = [ key for key in self.C.__dict__.keys() ]
+        # Testing dict-proxy keys...
+        it = self.C.__dict__.keys()
+        self.assertNotIsInstance(it, list)
+        keys = list(it)
         keys.sort()
         self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
             '__weakref__', 'meth'])
 
     def test_iter_values(self):
-        # Testing dict-proxy itervalues...
-        values = [ values for values in self.C.__dict__.values() ]
+        # Testing dict-proxy values...
+        it = self.C.__dict__.values()
+        self.assertNotIsInstance(it, list)
+        values = list(it)
         self.assertEqual(len(values), 5)
 
     def test_iter_items(self):
         # Testing dict-proxy iteritems...
-        keys = [ key for (key, value) in self.C.__dict__.items() ]
+        it = self.C.__dict__.items()
+        self.assertNotIsInstance(it, list)
+        keys = [item[0] for item in it]
         keys.sort()
         self.assertEqual(keys, ['__dict__', '__doc__', '__module__',
             '__weakref__', 'meth'])

Modified: python/branches/py3k/Objects/descrobject.c
==============================================================================
--- python/branches/py3k/Objects/descrobject.c	(original)
+++ python/branches/py3k/Objects/descrobject.c	Tue Dec  7 04:46:27 2010
@@ -710,19 +710,19 @@
 static PyObject *
 proxy_keys(proxyobject *pp)
 {
-    return PyMapping_Keys(pp->dict);
+    return PyObject_CallMethod(pp->dict, "keys", NULL);
 }
 
 static PyObject *
 proxy_values(proxyobject *pp)
 {
-    return PyMapping_Values(pp->dict);
+    return PyObject_CallMethod(pp->dict, "values", NULL);
 }
 
 static PyObject *
 proxy_items(proxyobject *pp)
 {
-    return PyMapping_Items(pp->dict);
+    return PyObject_CallMethod(pp->dict, "items", NULL);
 }
 
 static PyObject *

From python-checkins at python.org  Tue Dec  7 04:47:37 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Tue,  7 Dec 2010 04:47:37 +0100 (CET)
Subject: [Python-checkins] r87108 - python/branches/py3k/Misc/NEWS
Message-ID: <20101207034737.CBFFCEE98A@mail.python.org>

Author: benjamin.peterson
Date: Tue Dec  7 04:47:37 2010
New Revision: 87108

Log:
add news note

Modified:
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec  7 04:47:37 2010
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #10630: Return dict views from the dict proxy keys()/values()/items()
+  methods.
+
 - Issue #10596: Fix float.__mod__ to have the same behaviour as float.__divmod__
   with respect to signed zeros.  -4.0 % 4.0 should be 0.0, not -0.0.
 

From solipsis at pitrou.net  Tue Dec  7 04:50:45 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Tue, 07 Dec 2010 04:50:45 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87106): sum=0
Message-ID: 

py3k results for svn r87106 (hg cset 89ac354a1e1c)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogMNnRux', '-x']

From python-checkins at python.org  Tue Dec  7 05:04:04 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Tue,  7 Dec 2010 05:04:04 +0100 (CET)
Subject: [Python-checkins] r87109 -
	python/branches/py3k/Objects/descrobject.c
Message-ID: <20101207040404.1B514EE991@mail.python.org>

Author: benjamin.peterson
Date: Tue Dec  7 05:04:02 2010
New Revision: 87109

Log:
use the more direct API

Modified:
   python/branches/py3k/Objects/descrobject.c

Modified: python/branches/py3k/Objects/descrobject.c
==============================================================================
--- python/branches/py3k/Objects/descrobject.c	(original)
+++ python/branches/py3k/Objects/descrobject.c	Tue Dec  7 05:04:02 2010
@@ -1190,7 +1190,7 @@
         PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
         return NULL;
     }
-    return PyObject_CallFunction(gs->prop_get, "(O)", obj);
+    return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL);
 }
 
 static int
@@ -1211,9 +1211,9 @@
         return -1;
     }
     if (value == NULL)
-        res = PyObject_CallFunction(func, "(O)", obj);
+        res = PyObject_CallFunctionObjArgs(func, obj, NULL);
     else
-        res = PyObject_CallFunction(func, "(OO)", obj, value);
+        res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
     if (res == NULL)
         return -1;
     Py_DECREF(res);

From python-checkins at python.org  Tue Dec  7 07:45:30 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 07:45:30 +0100 (CET)
Subject: [Python-checkins] r87110 - in python/branches/py3k/Doc:
	library/argparse.rst whatsnew/3.2.rst
Message-ID: <20101207064530.83446EE991@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 07:45:30 2010
New Revision: 87110

Log:
Add example for the entry for argparse

Modified:
   python/branches/py3k/Doc/library/argparse.rst
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/library/argparse.rst
==============================================================================
--- python/branches/py3k/Doc/library/argparse.rst	(original)
+++ python/branches/py3k/Doc/library/argparse.rst	Tue Dec  7 07:45:30 2010
@@ -1729,6 +1729,7 @@
    This method prints a usage message including the *message* to the
    standard output and terminates the program with a status code of 2.
 
+.. _upgrading-optparse-code:
 
 Upgrading optparse code
 -----------------------

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 07:45:30 2010
@@ -77,7 +77,7 @@
 
 A new module for command line parsing, :mod:`argparse`, was introduced to
 overcome the limitations of :mod:`optparse` which did not provide support for
-positional arguments (not just option), subcommands, required options and other
+positional arguments (not just options), subcommands, required options and other
 common patterns of specifying and validating options.
 
 This module has already has wide-spread success in the community as a
@@ -86,13 +86,66 @@
 older module is still being kept available because of the substantial amount of
 legacy code that depends on it.
 
-.. XXX add examples that highlight the new features
+Here's an annotated example parser showing features like limiting results to a
+set of choices, specifying a *metavar* in the help screen, validating that one
+or more postional arguments is present, and making a required option::
+
+    import argparse
+    parser = argparse.ArgumentParser(
+                description = 'Manage servers',         # main description for help
+                epilog = 'Tested on Solaris and Linux') # displayed after help
+    parser.add_argument('action',                       # argument name
+                choices = ['deploy', 'start', 'stop'],  # one of four allowed values
+                help = 'action on each target')         # help msg
+    parser.add_argument('targets',
+                metavar = 'HOSTNAME',                   # var name used in help msg
+                nargs = '+',                            # require 1 or more targets
+                help = 'url for target machines')       # help msg explanation
+    parser.add_argument('-u', '--user',                 # -u or --user option
+                required = True,                        # make this a required argument
+                help = 'login as user')
+
+Example of calling the parser on a command string::
+
+    >>> cmd  = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
+    >>> result = parser.parse_args(cmd.split())
+
+    >>> # parsed variable are stored in the attributes
+    >>> result.action
+    'deploy'
+    >>> result.targets
+    ['sneezy.example.com', 'sleepy.example.com']
+    >>> result.user
+    'skycaptain'
+
+Example of the parser's automatically generated help::
+
+    >>> parser.parse_args('-h'.split())
+
+    usage: tmp_argparse_example.py [-h] -u USER
+                                   {deploy,start,stop} HOSTNAME [HOSTNAME ...]
+
+    Manage servers
+
+    positional arguments:
+      {deploy,start,stop}   action on each target
+      HOSTNAME              url for target machines
+
+    optional arguments:
+      -h, --help            show this help message and exit
+      -u USER, --user USER  login as user
+
+    Tested on Solaris and Linux
+
 
 .. seealso::
 
    :pep:`389` - New Command Line Parsing Module
       PEP written by Steven Bethard.
 
+   :ref:`upgrading-optparse-code` for details on the differences from
+      :mod:`optparse`.
+
 
 PEP 391:  Dictionary Based Configuration for Logging
 ====================================================
@@ -992,6 +1045,10 @@
 has an extensive section, :ref:`re-examples`.  Likewise, the :mod:`itertools`
 module continues to be updated with new :ref:`itertools-recipes`.
 
+The :mod:`datetime` module now has an auxiliary implementation in pure Python.
+No functionality was changed.  This just provides an easier-to-read
+alternate implementation.  (Contributed by Alexander Belopolsky.)
+
 
 IDLE
 ====

From python-checkins at python.org  Tue Dec  7 08:10:04 2010
From: python-checkins at python.org (senthil.kumaran)
Date: Tue,  7 Dec 2010 08:10:04 +0100 (CET)
Subject: [Python-checkins] r87111 -
	python/branches/release27-maint/Lib/xmlrpclib.py
Message-ID: <20101207071004.E67A0EE991@mail.python.org>

Author: senthil.kumaran
Date: Tue Dec  7 08:10:04 2010
New Revision: 87111

Log:
Fix Issue8194  - Fix incompatible API change in the parse_respones for xmlrpclib.



Modified:
   python/branches/release27-maint/Lib/xmlrpclib.py

Modified: python/branches/release27-maint/Lib/xmlrpclib.py
==============================================================================
--- python/branches/release27-maint/Lib/xmlrpclib.py	(original)
+++ python/branches/release27-maint/Lib/xmlrpclib.py	Tue Dec  7 08:10:04 2010
@@ -1446,8 +1446,13 @@
 
     def parse_response(self, response):
         # read response data from httpresponse, and parse it
-        if response.getheader("Content-Encoding", "") == "gzip":
-            stream = GzipDecodedResponse(response)
+
+        # Check for new http response object, else it is a file object
+        if hasattr(response,'getheader'):
+            if response.getheader("Content-Encoding", "") == "gzip":
+                stream = GzipDecodedResponse(response)
+            else:
+                stream = response
         else:
             stream = response
 

From python-checkins at python.org  Tue Dec  7 09:52:41 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 09:52:41 +0100 (CET)
Subject: [Python-checkins] r87112 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207085241.662E2EE99D@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 09:52:41 2010
New Revision: 87112

Log:
More cleanups and examples.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 09:52:41 2010
@@ -483,13 +483,12 @@
 
   (Added by Antoine Pitrou and Georg Brandl in :issue:`10093` and :issue:`477863`.)
 
-* :class:`range` objects now support *index* and *count* methods. This is
-  part of an effort to make more objects fully implement the :class:`collections.Sequence`
-  :term:`abstract base class`.  As a result, the language will have a more
-  uniform API.
-
-  In addition, :class:`range` objects now support slicing and negative indices.
-  This makes *range* more interoperable with lists.
+* :class:`range` objects now support *index* and *count* methods. This is part
+  of an effort to make more objects fully implement the
+  :class:`collections.Sequence` :term:`abstract base class`.  As a result, the
+  language will have a more uniform API.  In addition, :class:`range` objects
+  now support slicing and negative indices.  This makes *range* more
+  interoperable with lists.
 
   (Contributed by Daniel Stuzback in :issue:`9213` and by Alexander Belopolsky
   in :issue:`2690`.)
@@ -558,10 +557,10 @@
   (Contributed by Raymond Hettinger and incorporating design suggestions
   from Mark Dickinson.)
 
-* The :mod:`nntplib` module gets a revamped implementation with better
-  bytes / unicode semantics as well as more practical APIs.  These improvements
-  break compatibility with the nntplib version in Python 3.1, which was
-  partly dysfunctional in itself.
+* The :mod:`nntplib` module gets a revamped implementation with better bytes and
+  unicode semantics as well as more practical APIs.  These improvements break
+  compatibility with the nntplib version in Python 3.1, which was partly
+  dysfunctional in itself.
 
   (Contributed by Antoine Pitrou in :issue:`9360`)
 
@@ -610,21 +609,35 @@
 
 .. mention os.popen and subprocess.Popen auto-closing of fds
 
-* :class:`gzip.GzipFile` now implements the :class:`io.BufferedIOBase` ABC
-  (except for ``truncate()``), has a :meth:`~gzip.GzipFile.peek` method,
-  and supports unseekable as well as zero-padded file objects.
-
-  (Contributed by Antoine Pitrou, Nir Aides and Brian Curtin in :issue:`9962`,
-  :issue:`1675951`, :issue:`7471` and :issue:`2846`.)
+* :class:`gzip.GzipFile` now implements the :class:`io.BufferedIOBase`
+  :term:`abstract base class` (except for ``truncate()``).  It also has a
+  :meth:`~gzip.GzipFile.peek` method and supports unseekable as well as
+  zero-padded file objects.
 
   The :mod:`gzip` module also gains the :func:`~gzip.compress` and
   :func:`~gzip.decompress` functions for easier in-memory compression and
   decompression.
 
-  (Contributed by Anand B. Pillai in :issue:`3488`.)
+  Keep in mind that text needs to be encoded in to bytes before compressing
+  and decompressing:
+
+  >>> s = 'Three shall be the number thou shalt count, '
+  >>> s += 'and the number of the counting shall be three'
+  >>> b = s.encode()                        # convert to utf-8
+  >>> len(b)
+  89
+  >>> c = gzip.compress(b)
+  >>> len(c)
+  77
+  >>> gzip.decompress(c).decode()[:43]      # decompress and convert to text
+  'Three shall be the number thou shalt count, '
+
+  (Contributed by Anand B. Pillai in :issue:`3488`; and by Antoine Pitrou, Nir
+  Aides and Brian Curtin in :issue:`9962`, :issue:`1675951`, :issue:`7471` and
+  :issue:`2846`.)
 
 * The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
-  constants, for use with the :func:`~os.statvfs` function.
+  constants for use with the :func:`~os.statvfs` function.
 
   (Patch by Adam Jackson; :issue:`7647`.)
 
@@ -707,8 +720,16 @@
   as recommended in public uses of HTTPS.
   (Added by Antoine Pitrou, :issue:`9003`.)
 
-* The command call, ``python -m unittest`` can now accept file paths instead
-  of module names for running specific tests (:issue:`10620`).
+* The command-line call, ``python -m unittest`` can now accept file paths
+  instead of module names for running specific tests (:issue:`10620`).  The new
+  test discovery can find tests within packages, locating any test importable
+  from the top level directory.  The top level directory can be specified with
+  the `-t` option, a pattern for matching files with ``-p``, and a directory to
+  start discovery with ``-s``::
+
+    $ python -m unittest discover -s my_proj_dir -p '_test.py'
+
+  (Contributed by Michael Foord.)
 
 * The :mod:`unittest` module has two new methods,
   :meth:`~unittest.TestCase.assertWarns` and
@@ -718,9 +739,24 @@
   >>> with self.assertWarns(DeprecationWarning):
   ...     legacy_function('XYZ')
 
-  In addition, the naming in the module has ungone a number of clean-ups.
-  For example, :meth:`assertRegex` is the new name for :meth:`assertRegexpMatches`
-  which was misnamed because the test uses :func:`re.search`, not :func:`re.match`.
+  Another new method, :meth:`~unittest.TestCase.assertCountEqual` is used to compare two iterables
+  to determine if their element counts are equal (are the same elements present
+  the same number of times::
+
+     def test_anagram(self):
+         self.assertCountEqual('algorithm', 'logarithm')
+
+  A principal feature of the unittest module is an effort to produce meaningful
+  diagnostics when a test fails.  When possible the failure is recorded along
+  with a diff of the output.  This is especially helpful for analyzing log files
+  of failed test runs. However, since diffs can sometime be voluminous, there is
+  a new :attr:`~unittest.TestCase.maxDiff` attribute which sets maximum length of
+  diffs.
+
+  In addition the naming in the module has ungone a number of clean-ups.  For
+  example, :meth:`~unittest.TestCase.assertRegex` is the new name for
+  :meth:`~unittest.TestCase.assertRegexpMatches` which was misnamed because the
+  test uses :func:`re.search`, not :func:`re.match`.
 
   To improve consistency, some of long-standing method aliases are being
   deprecated in favor of the preferred names:
@@ -771,7 +807,10 @@
 
 * The :mod:`tempfile` module has a new context manager,
   :class:`~tempfile.TemporaryDirectory` which provides easy deterministic
-  cleanup of temporary directories.
+  cleanup of temporary directories:
+
+  >>> with tempfile.TemporaryDirectory() as tmpdirname:
+  ...     print 'created temporary directory', tmpdirname
 
   (Contributed by Neil Schemenauer and Nick Coghlan; :issue:`5178`.)
 
@@ -807,14 +846,6 @@
 
   (Contributed by Ron Adam; :issue:`2001`.)
 
-.. XXX add something about pdb additions:
-
-   * new commands interact, (un)display, longlist, source, until lineno
-   * -c option that executes commands as if given in .pdbrc
-   * SIGINT handler to break a continued program
-
-.. XXX add optimize flags for py_compile/compileall (issue10553)
-
 * The new :mod:`sysconfig` module makes it straight-forward to discover
   installation paths and configuration variables which vary across platforms and
   installs.

From python-checkins at python.org  Tue Dec  7 10:24:30 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 10:24:30 +0100 (CET)
Subject: [Python-checkins] r87113 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207092430.4A4DBEE9D0@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 10:24:30 2010
New Revision: 87113

Log:
Spelling.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 10:24:30 2010
@@ -88,7 +88,7 @@
 
 Here's an annotated example parser showing features like limiting results to a
 set of choices, specifying a *metavar* in the help screen, validating that one
-or more postional arguments is present, and making a required option::
+or more positional arguments is present, and making a required option::
 
     import argparse
     parser = argparse.ArgumentParser(
@@ -351,7 +351,7 @@
 
 Some smaller changes made to the core Python language are:
 
-* :class:`bytes` and :class:`str` now have two net methods, *tranform* and *untransform*.
+* :class:`bytes` and :class:`str` now have two net methods, *transform* and *untransform*.
   These provided analogues to *encode* and *decode* but are used for general purpose
   string-to-string and bytes-to-bytes transformations rather than Unicode codecs.
 
@@ -753,7 +753,7 @@
   a new :attr:`~unittest.TestCase.maxDiff` attribute which sets maximum length of
   diffs.
 
-  In addition the naming in the module has ungone a number of clean-ups.  For
+  In addition the naming in the module has undergone a number of clean-ups.  For
   example, :meth:`~unittest.TestCase.assertRegex` is the new name for
   :meth:`~unittest.TestCase.assertRegexpMatches` which was misnamed because the
   test uses :func:`re.search`, not :func:`re.match`.
@@ -915,7 +915,7 @@
     listing source code.
   - new commands: ``display`` and ``undisplay`` for showing or hiding
     the value of an expression if it has changed.
-  - new command: ``interact`` for starting an interative interpreter containing
+  - new command: ``interact`` for starting an interactive interpreter containing
     the global and local  names found in the current scope.
   - breakpoints can be cleared by breakpoint number
 

From python-checkins at python.org  Tue Dec  7 10:37:11 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 10:37:11 +0100 (CET)
Subject: [Python-checkins] r87114 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207093711.839F4EE99C@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 10:37:11 2010
New Revision: 87114

Log:
Clean-ups and examples.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 10:37:11 2010
@@ -472,14 +472,10 @@
   produce various issues, especially under Windows.  Here is an example
   of enabling the warning from the command line::
 
-      $ ./python -Wdefault
-      Python 3.2a3+ (py3k, Nov  5 2010, 22:58:04)
-      [GCC 4.4.3] on linux2
-      Type "help", "copyright", "credits" or "license" for more information.
+      $ ./python -q -Wdefault
       >>> f = open("foo", "wb")
       >>> del f
       __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
-      >>>
 
   (Added by Antoine Pitrou and Georg Brandl in :issue:`10093` and :issue:`477863`.)
 
@@ -541,7 +537,7 @@
   (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
   :issue:`8814`.)
 
-* The :mod:`itertools` module has a new function, :func:`~itertools.accumulate`
+* The :mod:`itertools` module has a new :func:`~itertools.accumulate` function
   modeled on APL's *scan* operator and on Numpy's *accumulate* function:
 
   >>> list(accumulate(8, 2, 50))
@@ -577,7 +573,12 @@
   in favor of a plain :keyword:`with` statement which can accept multiple
   context managers.  The latter technique is faster (because it is built-in),
   and it does a better job finalizing multiple context managers when one of them
-  raises an exception.
+  raises an exception::
+
+    >>> with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
+    ...     for line in infile:
+    ...         if '' in line:
+    ...             outfile.write(line)
 
   (Contributed by Georg Brandl and Mattias Br?ndstr?m;
   `appspot issue 53094 `_.)

From python-checkins at python.org  Tue Dec  7 10:44:21 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 10:44:21 +0100 (CET)
Subject: [Python-checkins] r87115 - python/branches/py3k/Doc/library/re.rst
Message-ID: <20101207094421.BA61BEE99C@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 10:44:21 2010
New Revision: 87115

Log:
Make the example a little more interesting and useful.

Modified:
   python/branches/py3k/Doc/library/re.rst

Modified: python/branches/py3k/Doc/library/re.rst
==============================================================================
--- python/branches/py3k/Doc/library/re.rst	(original)
+++ python/branches/py3k/Doc/library/re.rst	Tue Dec  7 10:44:21 2010
@@ -1300,6 +1300,7 @@
     Token = collections.namedtuple('Token', 'typ value line column')
 
     def tokenize(s):
+        keywords = {'IF', 'THEN', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
         tok_spec = [
             ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
             ('ASSIGN', r':='),          # Assignment operator
@@ -1320,6 +1321,8 @@
                 line_start = pos
                 line += 1
             elif typ != 'SKIP':
+                if typ == 'ID' and val in keywords:
+                    typ = val
                 yield Token(typ, mo.group(typ), line, mo.start()-line_start)
             pos = mo.end()
             mo = gettok(s, pos)

From python-checkins at python.org  Tue Dec  7 10:55:02 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue,  7 Dec 2010 10:55:02 +0100 (CET)
Subject: [Python-checkins] r87116 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101207095502.7250EEE982@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec  7 10:55:02 2010
New Revision: 87116

Log:
Martin's name with Unicode.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec  7 10:55:02 2010
@@ -48,6 +48,9 @@
    when researching a change.
 
 This article explains the new features in Python 3.2, compared to 3.1.
+It focuses on a few highlights and gives a few examples.  For full details,
+see the :file:`Misc/NEWS` file.
+
 
 PEP 384: Defining a Stable ABI
 ==============================
@@ -70,7 +73,7 @@
 .. seealso::
 
    :pep:`384` - Defining a Stable ABI
-      PEP written by Martin von Loewis.
+      PEP written by Martin von L?wis.
 
 PEP 389: Argparse Command Line Parsing Module
 =============================================

From python-checkins at python.org  Tue Dec  7 11:24:37 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Tue,  7 Dec 2010 11:24:37 +0100 (CET)
Subject: [Python-checkins] r87117 -
	python/branches/py3k/Modules/posixmodule.c
Message-ID: <20101207102437.EA365EE9D0@mail.python.org>

Author: hirokazu.yamamoto
Date: Tue Dec  7 11:24:37 2010
New Revision: 87117

Log:
Issue #10637: Called CloseHandle twice in os.stat/os.lstat (Windows)


Modified:
   python/branches/py3k/Modules/posixmodule.c

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Tue Dec  7 11:24:37 2010
@@ -1159,8 +1159,8 @@
                 free(target_path);
                 return code;
             }
-        }
-        CloseHandle(hFile);
+        } else
+            CloseHandle(hFile);
     }
     attribute_data_to_stat(&info, reparse_tag, result);
 
@@ -1232,8 +1232,8 @@
                 free(target_path);
                 return code;
             }
-        }
-        CloseHandle(hFile);
+        } else
+            CloseHandle(hFile);
     }
     attribute_data_to_stat(&info, reparse_tag, result);
 

From python-checkins at python.org  Tue Dec  7 15:41:05 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Tue,  7 Dec 2010 15:41:05 +0100 (CET)
Subject: [Python-checkins] r87118 - in python/branches/py3k:
	Mac/BuildScript/build-installer.py Makefile.pre.in
Message-ID: <20101207144105.C0E88EEB67@mail.python.org>

Author: ronald.oussoren
Date: Tue Dec  7 15:41:05 2010
New Revision: 87118

Log:
Two small changes to adjust framework builds to the new stable ABI

Both the Makefile and the script that is used on OSX to create the binary
installer refer to the directory containing the Makefile using the name
'config'. This name was changed with the new ABI (with default build flags
it is now named config-3.2m).  This patch ensures that both files use the
correct name.

The build-installer.py script contains one other change: it now tests for the
Tcl/Tk framework version by looking at the 'Current' symlink in the framework
instead of runnning a script. This makes it possible to verify the version
that is in the SDK that's used during the build instead of the version that
is installed on the system.


Modified:
   python/branches/py3k/Mac/BuildScript/build-installer.py
   python/branches/py3k/Makefile.pre.in

Modified: python/branches/py3k/Mac/BuildScript/build-installer.py
==============================================================================
--- python/branches/py3k/Mac/BuildScript/build-installer.py	(original)
+++ python/branches/py3k/Mac/BuildScript/build-installer.py	Tue Dec  7 15:41:05 2010
@@ -418,15 +418,16 @@
     #       to install a newer patch level.
 
     for framework in ['Tcl', 'Tk']:
-        fw = dict(lower=framework.lower(),
-                    upper=framework.upper(),
-                    cap=framework.capitalize())
-        fwpth = "Library/Frameworks/%(cap)s.framework/%(lower)sConfig.sh" % fw
-        sysfw = os.path.join('/System', fwpth)
+        #fw = dict(lower=framework.lower(),
+        #            upper=framework.upper(),
+        #            cap=framework.capitalize())
+        #fwpth = "Library/Frameworks/%(cap)s.framework/%(lower)sConfig.sh" % fw
+        fwpth = 'Library/Frameworks/Tcl.framework/Versions/Current'
+        sysfw = os.path.join(SDKPATH, 'System', fwpth)
         libfw = os.path.join('/', fwpth)
         usrfw = os.path.join(os.getenv('HOME'), fwpth)
-        version = "%(upper)s_VERSION" % fw
-        if getTclTkVersion(libfw, version) != getTclTkVersion(sysfw, version):
+        #version = "%(upper)s_VERSION" % fw
+        if os.readlink(libfw) != os.readlink(sysfw):
             fatal("Version of %s must match %s" % (libfw, sysfw) )
         if os.path.exists(usrfw):
             fatal("Please rename %s to avoid possible dynamic load issues."
@@ -825,12 +826,29 @@
             os.chmod(p, stat.S_IMODE(st.st_mode) | stat.S_IWGRP)
             os.chown(p, -1, gid)
 
+    LDVERSION=None
+    VERSION=None
+    ABIFLAGS=None
+
+    with open(os.path.join(buildDir, 'Makefile')) as fp:
+        for ln in fp:
+            if ln.startswith('VERSION='):
+                VERSION=ln.split()[1]
+            if ln.startswith('ABIFLAGS='):
+                ABIFLAGS=ln.split()[1]
+
+            if ln.startswith('LDVERSION='):
+                LDVERSION=ln.split()[1]
+
+    LDVERSION = LDVERSION.replace('$(VERSION)', VERSION)
+    LDVERSION = LDVERSION.replace('$(ABIFLAGS)', ABIFLAGS)
+
     # We added some directories to the search path during the configure
     # phase. Remove those because those directories won't be there on
     # the end-users system.
     path =os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework',
                 'Versions', version, 'lib', 'python%s'%(version,),
-                'config', 'Makefile')
+                'config-' + LDVERSION, 'Makefile')
     fp = open(path, 'r')
     data = fp.read()
     fp.close()

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Tue Dec  7 15:41:05 2010
@@ -498,7 +498,6 @@
 		$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/Info.plist
 	$(LN) -fsn $(VERSION) $(PYTHONFRAMEWORKDIR)/Versions/Current
 	$(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(PYTHONFRAMEWORKDIR)/$(PYTHONFRAMEWORK)
-	$(LN) -fsn Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers
 	$(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources
 
 # This rule builds the Cygwin Python DLL and import library if configured
@@ -1113,7 +1112,7 @@
 		else	true; \
 		fi; \
 	done
-	$(LN) -fsn include/python$(VERSION) $(DESTDIR)$(prefix)/Headers
+	$(LN) -fsn include/python$(LDVERSION) $(DESTDIR)$(prefix)/Headers
 	sed 's/%VERSION%/'"`$(RUNSHARED) ./$(BUILDPYTHON) -c 'import platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > $(DESTDIR)$(prefix)/Resources/Info.plist
 	$(LN) -fsn $(VERSION) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/Current
 	$(LN) -fsn Versions/Current/$(PYTHONFRAMEWORK) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/$(PYTHONFRAMEWORK)
@@ -1125,8 +1124,8 @@
 # Install a number of symlinks to keep software that expects a normal unix
 # install (which includes python-config) happy.
 frameworkinstallmaclib:
-	ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a"
-	ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).dylib"
+	ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config-$(LDVERSION)/libpython$(VERSION).a"
+	ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config-$(LDVERSION)/libpython$(VERSION).dylib"
 	ln -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib"
 
 # This installs the IDE, the Launcher and other apps into /Applications

From python-checkins at python.org  Tue Dec  7 16:28:10 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Tue,  7 Dec 2010 16:28:10 +0100 (CET)
Subject: [Python-checkins] r87119 - in python/branches/py3k:
	Lib/idlelib/FileList.py Lib/idlelib/macosxSupport.py Misc/NEWS
Message-ID: <20101207152810.829BEEE98B@mail.python.org>

Author: ronald.oussoren
Date: Tue Dec  7 16:28:10 2010
New Revision: 87119

Log:
Fix for issue #10107: Without this patch IDLE on OSX doesn't warn about unsaved files when quitting.


Modified:
   python/branches/py3k/Lib/idlelib/FileList.py
   python/branches/py3k/Lib/idlelib/macosxSupport.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/idlelib/FileList.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/FileList.py	(original)
+++ python/branches/py3k/Lib/idlelib/FileList.py	Tue Dec  7 16:28:10 2010
@@ -48,7 +48,7 @@
     def new(self, filename=None):
         return self.EditorWindow(self, filename)
 
-    def close_all_callback(self, event):
+    def close_all_callback(self, *args, **kwds):
         for edit in list(self.inversedict):
             reply = edit.close()
             if reply == "cancel":

Modified: python/branches/py3k/Lib/idlelib/macosxSupport.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/macosxSupport.py	(original)
+++ python/branches/py3k/Lib/idlelib/macosxSupport.py	Tue Dec  7 16:28:10 2010
@@ -103,6 +103,11 @@
     if flist:
         root.bind('<>', flist.close_all_callback)
 
+        # The binding above doesn't reliably work on all versions of Tk
+        # on MacOSX. Adding command definition below does seem to do the
+        # right thing for now.
+        root.createcommand('exit', flist.close_all_callback)
+
 
     ###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding
     tkversion = root.tk.eval('info patchlevel')

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec  7 16:28:10 2010
@@ -2,6 +2,18 @@
 Python News
 +++++++++++
 
+What's New in Python 3.2 Beta 2?
+================================
+
+*Release date: XXXX-XX-XX*
+
+
+Library
+-------
+
+* Issue #10107: Warn about unsaved files in IDLE on OSX.
+
+
 What's New in Python 3.2 Beta 1?
 ================================
 

From python-checkins at python.org  Tue Dec  7 16:31:07 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Tue,  7 Dec 2010 16:31:07 +0100 (CET)
Subject: [Python-checkins] r87120 - in python/branches/release31-maint:
	Lib/idlelib/FileList.py Lib/idlelib/macosxSupport.py Misc/NEWS
Message-ID: <20101207153107.2CA08EEA39@mail.python.org>

Author: ronald.oussoren
Date: Tue Dec  7 16:31:07 2010
New Revision: 87120

Log:
Merged revisions 87119 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87119 | ronald.oussoren | 2010-12-07 16:28:10 +0100 (Tue, 07 Dec 2010) | 2 lines
  
  Fix for issue #10107: Without this patch IDLE on OSX doesn't warn about unsaved files when quitting.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/idlelib/FileList.py
   python/branches/release31-maint/Lib/idlelib/macosxSupport.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/idlelib/FileList.py
==============================================================================
--- python/branches/release31-maint/Lib/idlelib/FileList.py	(original)
+++ python/branches/release31-maint/Lib/idlelib/FileList.py	Tue Dec  7 16:31:07 2010
@@ -48,7 +48,7 @@
     def new(self, filename=None):
         return self.EditorWindow(self, filename)
 
-    def close_all_callback(self, event):
+    def close_all_callback(self, *args, **kwds):
         for edit in list(self.inversedict):
             reply = edit.close()
             if reply == "cancel":

Modified: python/branches/release31-maint/Lib/idlelib/macosxSupport.py
==============================================================================
--- python/branches/release31-maint/Lib/idlelib/macosxSupport.py	(original)
+++ python/branches/release31-maint/Lib/idlelib/macosxSupport.py	Tue Dec  7 16:31:07 2010
@@ -97,6 +97,11 @@
     if flist:
         root.bind('<>', flist.close_all_callback)
 
+        # The binding above doesn't reliably work on all versions of Tk
+        # on MacOSX. Adding command definition below does seem to do the
+        # right thing for now.
+        root.createcommand('exit', flist.close_all_callback)
+
 
     ###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding
     tkversion = root.tk.eval('info patchlevel')

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Tue Dec  7 16:31:07 2010
@@ -17,6 +17,8 @@
 Library
 -------
 
+- Issue #10107: Warn about unsaved files in IDLE on OSX.
+
 - Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by
   RFC3986. Anything before :// is considered a scheme and is followed by an
   authority (or netloc) and by '/' led path, which is optional.

From python-checkins at python.org  Tue Dec  7 17:03:00 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Tue,  7 Dec 2010 17:03:00 +0100 (CET)
Subject: [Python-checkins] r87121 - in python/branches/release27-maint:
	Lib/idlelib/FileList.py Lib/idlelib/macosxSupport.py Misc/NEWS
Message-ID: <20101207160300.2BB66EEB0E@mail.python.org>

Author: ronald.oussoren
Date: Tue Dec  7 17:02:59 2010
New Revision: 87121

Log:
Merged revisions 87119 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87119 | ronald.oussoren | 2010-12-07 16:28:10 +0100 (Tue, 07 Dec 2010) | 2 lines
  
  Fix for issue #10107: Without this patch IDLE on OSX doesn't warn about unsaved files when quitting.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/idlelib/FileList.py
   python/branches/release27-maint/Lib/idlelib/macosxSupport.py
   python/branches/release27-maint/Misc/NEWS

Modified: python/branches/release27-maint/Lib/idlelib/FileList.py
==============================================================================
--- python/branches/release27-maint/Lib/idlelib/FileList.py	(original)
+++ python/branches/release27-maint/Lib/idlelib/FileList.py	Tue Dec  7 17:02:59 2010
@@ -43,7 +43,7 @@
     def new(self, filename=None):
         return self.EditorWindow(self, filename)
 
-    def close_all_callback(self, event):
+    def close_all_callback(self, *args, **kwds):
         for edit in self.inversedict.keys():
             reply = edit.close()
             if reply == "cancel":

Modified: python/branches/release27-maint/Lib/idlelib/macosxSupport.py
==============================================================================
--- python/branches/release27-maint/Lib/idlelib/macosxSupport.py	(original)
+++ python/branches/release27-maint/Lib/idlelib/macosxSupport.py	Tue Dec  7 17:02:59 2010
@@ -97,6 +97,11 @@
     if flist:
         root.bind('<>', flist.close_all_callback)
 
+        # The binding above doesn't reliably work on all versions of Tk
+        # on MacOSX. Adding command definition below does seem to do the
+        # right thing for now.
+        root.createcommand('exit', flist.close_all_callback)
+
 
     ###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding
     tkversion = root.tk.eval('info patchlevel')

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Tue Dec  7 17:02:59 2010
@@ -16,6 +16,8 @@
 Library
 -------
 
+- Issue #10107: Warn about unsaved files in IDLE on OSX.
+
 - Issue #10478: Reentrant calls inside buffered IO objects (for example by
   way of a signal handler) now raise a RuntimeError instead of freezing the
   current process.

From python-checkins at python.org  Tue Dec  7 17:13:17 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Tue,  7 Dec 2010 17:13:17 +0100 (CET)
Subject: [Python-checkins] r87122 - in python/branches/release27-maint:
	Mac/IDLE/config-extensions.def Misc/NEWS
Message-ID: <20101207161317.C3682EEAC6@mail.python.org>

Author: ronald.oussoren
Date: Tue Dec  7 17:13:17 2010
New Revision: 87122

Log:
Fix for issue #10406: enable Rstrip extension on OSX

Without this patch the Rstrip extension for IDLE is not enabled on OSX,
while it is enabled on other platforms.

Patch by Ned Deily.


Modified:
   python/branches/release27-maint/Mac/IDLE/config-extensions.def
   python/branches/release27-maint/Misc/NEWS

Modified: python/branches/release27-maint/Mac/IDLE/config-extensions.def
==============================================================================
--- python/branches/release27-maint/Mac/IDLE/config-extensions.def	(original)
+++ python/branches/release27-maint/Mac/IDLE/config-extensions.def	Tue Dec  7 17:13:17 2010
@@ -86,3 +86,8 @@
 fgcolor=Black
 [CodeContext_bindings]
 toggle-code-context=
+
+[RstripExtension]
+enable=1
+enable_shell=0
+enable_editor=1

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Tue Dec  7 17:13:17 2010
@@ -18,6 +18,9 @@
 
 - Issue #10107: Warn about unsaved files in IDLE on OSX.
 
+- Issue #10406: Enable Rstrip IDLE extension on OSX (just like on other
+  platforms).
+
 - Issue #10478: Reentrant calls inside buffered IO objects (for example by
   way of a signal handler) now raise a RuntimeError instead of freezing the
   current process.

From python-checkins at python.org  Tue Dec  7 19:54:44 2010
From: python-checkins at python.org (giampaolo.rodola)
Date: Tue,  7 Dec 2010 19:54:44 +0100 (CET)
Subject: [Python-checkins] r87123 - in python/branches/release26-maint:
	Lib/smtpd.py Misc/NEWS
Message-ID: <20101207185444.59B8DEEB0D@mail.python.org>

Author: giampaolo.rodola
Date: Tue Dec  7 19:54:43 2010
New Revision: 87123

Log:
backporting security fix of issue 9129 (smtpd module vulnerable to DoS attacks in case of connection bashing)

Modified:
   python/branches/release26-maint/Lib/smtpd.py
   python/branches/release26-maint/Misc/NEWS

Modified: python/branches/release26-maint/Lib/smtpd.py
==============================================================================
--- python/branches/release26-maint/Lib/smtpd.py	(original)
+++ python/branches/release26-maint/Lib/smtpd.py	Tue Dec  7 19:54:43 2010
@@ -121,7 +121,15 @@
         self.__rcpttos = []
         self.__data = ''
         self.__fqdn = socket.getfqdn()
-        self.__peer = conn.getpeername()
+        try:
+            self.__peer = conn.getpeername()
+        except socket.error as err:
+            # a race condition  may occur if the other end is closing
+            # before we can get the peername
+            self.close()
+            if err.args[0] != errno.ENOTCONN:
+                raise
+            return
         print >> DEBUGSTREAM, 'Peer:', repr(self.__peer)
         self.push('220 %s %s' % (self.__fqdn, __version__))
         self.set_terminator('\r\n')
@@ -291,7 +299,20 @@
                 localaddr, remoteaddr)
 
     def handle_accept(self):
-        conn, addr = self.accept()
+        try:
+            conn, addr = self.accept()
+        except TypeError:
+            # sometimes accept() might return None
+            return
+        except socket.error as err:
+            # ECONNABORTED might be thrown
+            if err.args[0] != errno.ECONNABORTED:
+                raise
+            return
+        else:
+            # sometimes addr == None instead of (ip, port)
+            if addr == None:
+                return
         print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
         channel = SMTPChannel(self, conn, addr)
 

Modified: python/branches/release26-maint/Misc/NEWS
==============================================================================
--- python/branches/release26-maint/Misc/NEWS	(original)
+++ python/branches/release26-maint/Misc/NEWS	Tue Dec  7 19:54:43 2010
@@ -19,6 +19,8 @@
 Library
 -------
 
+- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
+  error handling when accepting a new connection.
 
 What's New in Python 2.6.6?
 ===========================
@@ -206,7 +208,7 @@
 - Issue #8620: when a Cmd is fed input that reaches EOF without a final
   newline, it no longer truncates the last character of the last command line.
 
-- Issue #7066: archive_util.make_archive now restores the cwd if an error is 
+- Issue #7066: archive_util.make_archive now restores the cwd if an error is
   raised. Initial patch by Ezio Melotti.
 
 - Issue #5006: Better handling of unicode byte-order marks (BOM) in the io

From python-checkins at python.org  Wed Dec  8 02:13:53 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 02:13:53 +0100 (CET)
Subject: [Python-checkins] r87124 - in python/branches/py3k:
	Doc/whatsnew/3.2.rst Lib/random.py Lib/test/test_random.py
Message-ID: <20101208011353.C0C5CEEA14@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 02:13:53 2010
New Revision: 87124

Log:
Update whatsnew.  Salt the random number seed.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst
   python/branches/py3k/Lib/random.py
   python/branches/py3k/Lib/test/test_random.py

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 02:13:53 2010
@@ -125,8 +125,8 @@
 
     >>> parser.parse_args('-h'.split())
 
-    usage: tmp_argparse_example.py [-h] -u USER
-                                   {deploy,start,stop} HOSTNAME [HOSTNAME ...]
+    usage: manage_cloud.py [-h] -u USER
+                           {deploy,start,stop} HOSTNAME [HOSTNAME ...]
 
     Manage servers
 
@@ -321,10 +321,10 @@
       PEP written by Barry Warsaw.
 
 
-Email 5.1
-=========
+Email
+=====
 
-The email package is extended to be able to parse and generate email messages
+The email package has been extended to parse and generate email messages
 in bytes format.
 
 * New functions :func:`~email.message_from_bytes` and
@@ -832,6 +832,7 @@
 
   (Contributed by Rodolpho Eckhardt and Nick Coghlan, :issue:`10220`.)
 
+.. XXX: notes on new random.seed() version 2
 .. XXX: Create a new section for all changes relating to context managers.
 .. XXX: Various ConfigParser changes
 .. XXX: Mention inspect.getattr_static (Michael Foord)
@@ -902,7 +903,7 @@
             platbase = "C:\Python32"
             prefix = "C:\Python32"
             projectbase = "C:\Python32"
-            py_version = "3.2b1"
+            py_version = "3.2"
             py_version_nodot = "32"
             py_version_short = "3.2"
             srcdir = "C:\Python32"
@@ -1151,3 +1152,8 @@
 
  * The :func:`sys.setfilesystemencoding` function was removed because
    it had a flawed design.
+
+ * The :func:`random.seed` function and method now performing salting for
+   string seeds.  To access the previous version of *seed* in order to
+   reproduce Python 3.1 sequences, set the *version* argument to *1*,
+   ``random.seed(s, version=1)``.

Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py	(original)
+++ python/branches/py3k/Lib/random.py	Wed Dec  8 02:13:53 2010
@@ -43,6 +43,7 @@
 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
 from os import urandom as _urandom
 import collections as _collections
+from hashlib import sha512 as _sha512
 
 __all__ = ["Random","seed","random","uniform","randint","choice","sample",
            "randrange","shuffle","normalvariate","lognormvariate",
@@ -110,10 +111,12 @@
                 import time
                 a = int(time.time() * 256) # use fractional seconds
 
-        if version == 2 and isinstance(a, (str, bytes, bytearray)):
-            if isinstance(a, str):
-                a = a.encode("utf8")
-            a = int.from_bytes(a, 'big')
+        if version == 2:
+            if isinstance(a, (str, bytes, bytearray)):
+                if isinstance(a, str):
+                    a = a.encode("utf8")
+                a += _sha512(a).digest()
+                a = int.from_bytes(a, 'big')
 
         super().seed(a)
         self.gauss_next = None

Modified: python/branches/py3k/Lib/test/test_random.py
==============================================================================
--- python/branches/py3k/Lib/test/test_random.py	(original)
+++ python/branches/py3k/Lib/test/test_random.py	Wed Dec  8 02:13:53 2010
@@ -246,8 +246,8 @@
              '0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
         self.gen.seed("the quick brown fox", version=2)
         self.assertEqual([self.gen.random().hex() for i in range(4)],
-            ['0x1.1294009b9eda4p-2', '0x1.2ff96171b0010p-1',
-             '0x1.459e0989bd8e0p-5', '0x1.8b5f55892ddcbp-1'])
+            ['0x1.1239ddfb11b7cp-3', '0x1.b3cbb5c51b120p-4',
+             '0x1.8c4f55116b60fp-1', '0x1.63eb525174a27p-1'])
 
     def test_setstate_first_arg(self):
         self.assertRaises(ValueError, self.gen.setstate, (1, None, None))

From solipsis at pitrou.net  Wed Dec  8 04:51:52 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Wed, 08 Dec 2010 04:51:52 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87124): sum=0
Message-ID: 

py3k results for svn r87124 (hg cset 76fc3cc49668)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog_C_z41', '-x']

From python-checkins at python.org  Wed Dec  8 07:42:47 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 07:42:47 +0100 (CET)
Subject: [Python-checkins] r87125 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208064247.749A3EEA06@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 07:42:41 2010
New Revision: 87125

Log:
Add example for concurrent.futures.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 07:42:41 2010
@@ -223,11 +223,31 @@
 solves the design challenge that arises when each component has its own
 competing strategy for resource management.
 
-For an example of :class:`~concurrent.futures.ThreadPoolExecutor`,
-see :ref:`code for threaded parallel URL reads`.
-
-For an example of :class:`~concurrent.futures.ProcessPoolExecutor`,
-see :ref:`code for computing prime numbers in parallel`.
+Both classes share a common interface with three methods:
+:meth:`~concurrent.futures.Executor.submit` for scheduling a callable and
+returning a :class:`~concurrent.futures.Future` object;
+:meth:`~concurrent.futures.Executor.map` for scheduling many asynchronous calls
+at time, and :meth:`~concurrent.futures.shutdown` for freeing resources.  The
+class is a :term:`context manager` and can be used within a :keyword:`with`
+statement to assure that resources are automatically released when currently
+pending futures are done executing.
+
+A simple of example of :class:`~concurrent.futures.ThreadPoolExecutor` is a
+launch of four parallel threads for copying directories::
+
+  import shutil
+  with ThreadPoolExecutor(max_workers=4) as e:
+      e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
+      e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
+      e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
+      e.submit(shutil.copy, 'src3.txt', 'dest4.txt')
+
+Also see :ref:`code for threaded parallel URL reads`
+for an example using threads to fetch multiple web pages in parallel.
+
+Or, for an example of :class:`~concurrent.futures.ProcessPoolExecutor`, see
+:ref:`code for computing prime numbers in
+parallel`.
 
 .. seealso::
 

From python-checkins at python.org  Wed Dec  8 07:48:33 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 07:48:33 +0100 (CET)
Subject: [Python-checkins] r87126 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208064833.CC861EE99E@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 07:48:33 2010
New Revision: 87126

Log:
Clean-ups.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 07:48:33 2010
@@ -227,13 +227,13 @@
 :meth:`~concurrent.futures.Executor.submit` for scheduling a callable and
 returning a :class:`~concurrent.futures.Future` object;
 :meth:`~concurrent.futures.Executor.map` for scheduling many asynchronous calls
-at time, and :meth:`~concurrent.futures.shutdown` for freeing resources.  The
-class is a :term:`context manager` and can be used within a :keyword:`with`
-statement to assure that resources are automatically released when currently
-pending futures are done executing.
+at a time, and :meth:`~concurrent.futures.Executor.shutdown` for freeing
+resources.  The class is a :term:`context manager` and can be used within a
+:keyword:`with` statement to assure that resources are automatically released
+when currently pending futures are done executing.
 
 A simple of example of :class:`~concurrent.futures.ThreadPoolExecutor` is a
-launch of four parallel threads for copying directories::
+launch of four parallel threads for copying files::
 
   import shutil
   with ThreadPoolExecutor(max_workers=4) as e:
@@ -242,18 +242,19 @@
       e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
       e.submit(shutil.copy, 'src3.txt', 'dest4.txt')
 
-Also see :ref:`code for threaded parallel URL reads`
-for an example using threads to fetch multiple web pages in parallel.
-
-Or, for an example of :class:`~concurrent.futures.ProcessPoolExecutor`, see
-:ref:`code for computing prime numbers in
-parallel`.
-
 .. seealso::
 
    :pep:`3148` - Futures -- Execute Computations Asynchronously
       PEP written by Brain Quinlan.
 
+   :ref:`Code for Threaded Parallel URL reads`, an
+   example using threads to fetch multiple web pages in parallel.
+
+   :ref:`Code for computing prime numbers in
+   parallel`, an example demonstrating
+   :class:`~concurrent.futures.ProcessPoolExecutor`.
+
+
 
 PEP 3147:  PYC Repository Directories
 =====================================

From python-checkins at python.org  Wed Dec  8 07:50:02 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 07:50:02 +0100 (CET)
Subject: [Python-checkins] r87127 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208065002.D3ED0EE99E@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 07:50:02 2010
New Revision: 87127

Log:
Nits.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 07:50:02 2010
@@ -209,7 +209,7 @@
 are represented by a :class:`~concurrent.futures.Future` object which abstracts
 features common to threads, processes, and remote procedure calls.  That object
 supports status checks (running or done), timeouts, cancellations, adding
-callbacks, and access to results or exceptions.XS
+callbacks, and access to results or exceptions.
 
 The primary offering of the new module is a pair of executor classes for
 launching and managing calls.  The goal of the executors is to make it easier to
@@ -853,7 +853,6 @@
 
   (Contributed by Rodolpho Eckhardt and Nick Coghlan, :issue:`10220`.)
 
-.. XXX: notes on new random.seed() version 2
 .. XXX: Create a new section for all changes relating to context managers.
 .. XXX: Various ConfigParser changes
 .. XXX: Mention inspect.getattr_static (Michael Foord)

From python-checkins at python.org  Wed Dec  8 09:04:49 2010
From: python-checkins at python.org (senthil.kumaran)
Date: Wed,  8 Dec 2010 09:04:49 +0100 (CET)
Subject: [Python-checkins] r87128 - python/branches/py3k/Lib/xmlrpc/client.py
Message-ID: <20101208080449.C9B31EE9CA@mail.python.org>

Author: senthil.kumaran
Date: Wed Dec  8 09:04:49 2010
New Revision: 87128

Log:
Fix Issue8194  - Fix incompatible API change in the parse_respones for xmlrpclib.



Modified:
   python/branches/py3k/Lib/xmlrpc/client.py

Modified: python/branches/py3k/Lib/xmlrpc/client.py
==============================================================================
--- python/branches/py3k/Lib/xmlrpc/client.py	(original)
+++ python/branches/py3k/Lib/xmlrpc/client.py	Wed Dec  8 09:04:49 2010
@@ -1297,8 +1297,12 @@
 
     def parse_response(self, response):
         # read response data from httpresponse, and parse it
-        if response.getheader("Content-Encoding", "") == "gzip":
-            stream = GzipDecodedResponse(response)
+        # Check for new http response object, otherwise it is a file object.
+        if hasattr(response, 'getheader'):
+            if response.getheader("Content-Encoding", "") == "gzip":
+                stream = GzipDecodedResponse(response)
+            else:
+                stream = response
         else:
             stream = response
 

From python-checkins at python.org  Wed Dec  8 11:18:21 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 11:18:21 +0100 (CET)
Subject: [Python-checkins] r87129 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208101821.AF96FEEA44@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 11:18:21 2010
New Revision: 87129

Log:
range() example

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 11:18:21 2010
@@ -508,7 +508,16 @@
   :class:`collections.Sequence` :term:`abstract base class`.  As a result, the
   language will have a more uniform API.  In addition, :class:`range` objects
   now support slicing and negative indices.  This makes *range* more
-  interoperable with lists.
+  interoperable with lists::
+
+      >>> range(0, 100, 2).count(10)
+      1
+      >>> range(0, 100, 2).index(10)
+      5
+      >>> range(0, 100, 2)[5]
+      10
+      >>> range(0, 100, 2)[0:5]
+      range(0, 10, 2)
 
   (Contributed by Daniel Stuzback in :issue:`9213` and by Alexander Belopolsky
   in :issue:`2690`.)

From python-checkins at python.org  Wed Dec  8 12:19:46 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 12:19:46 +0100 (CET)
Subject: [Python-checkins] r87130 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208111946.2D236EEA8B@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 12:19:45 2010
New Revision: 87130

Log:
Example of argparge with subparsers.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 12:19:45 2010
@@ -84,10 +84,10 @@
 common patterns of specifying and validating options.
 
 This module has already has wide-spread success in the community as a
-third-party module.  Being more fully featured than its predecessor,
-:mod:`argparse`, is now the preferred module for command-line processing.  The
-older module is still being kept available because of the substantial amount of
-legacy code that depends on it.
+third-party module.  Being more fully featured than its predecessor, the
+:mod:`argparse` module is now the preferred module for command-line processing.
+The older module is still being kept available because of the substantial amount
+of legacy code that depends on it.
 
 Here's an annotated example parser showing features like limiting results to a
 set of choices, specifying a *metavar* in the help screen, validating that one
@@ -113,7 +113,7 @@
     >>> cmd  = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
     >>> result = parser.parse_args(cmd.split())
 
-    >>> # parsed variable are stored in the attributes
+    >>> # parsed variables are stored in the attributes
     >>> result.action
     'deploy'
     >>> result.targets
@@ -140,6 +140,25 @@
 
     Tested on Solaris and Linux
 
+An especially nice :mod:`argparse` feature is the ability to define subparsers,
+each with their own argument patterns and help displays::
+
+    import argparse
+    parser = argparse.ArgumentParser(prog='HELM')
+    subparsers = parser.add_subparsers()
+
+    parser_l = subparsers.add_parser('launch', help='Launch Control')   # first subgroup
+    parser_l.add_argument('-m', '--missles', action='store_true')
+    parser_l.add_argument('-t', '--torpedos', action='store_true')
+
+    parser_m = subparsers.add_parser('move', help='Move Vessel')        # second subgroup
+    parser_m.add_argument('-c', '--course', type=int, required=True)
+    parser_m.add_argument('-s', '--speed', type=int, default=0)
+
+    $ ./helm.py --help                         # top level help (launch and move)
+    $ ./helm.py launch --help                  # help for launch options
+    $ ./helm.py launch --missiles              # set missiles=True and torpedos=False
+    $ ./helm.py move --course 180 --speed 5    # set movement parameters
 
 .. seealso::
 

From python-checkins at python.org  Wed Dec  8 12:33:19 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed,  8 Dec 2010 12:33:19 +0100 (CET)
Subject: [Python-checkins] r87131 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208113319.5AB31EE9A5@mail.python.org>

Author: raymond.hettinger
Date: Wed Dec  8 12:33:19 2010
New Revision: 87131

Log:
Entry for inspect.getattr_static().


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 12:33:19 2010
@@ -440,7 +440,11 @@
   dictionaries it would miss the dynamic methods and make it difficult to
   implement proxy objects.
 
-  (Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
+  To support lookups without the possibility of activating a dynamic attribute,
+  the :mod:`inspect` module has a new function, :func:`getattr_static`.
+
+  (Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.
+  The inspect function added by Michael Foord.)
 
 * The :func:`str` of a float or complex number is now the same as its
   :func:`repr`. Previously, the :func:`str` form was shorter but that just
@@ -669,10 +673,8 @@
 
   The :mod:`gzip` module also gains the :func:`~gzip.compress` and
   :func:`~gzip.decompress` functions for easier in-memory compression and
-  decompression.
-
-  Keep in mind that text needs to be encoded in to bytes before compressing
-  and decompressing:
+  decompression.  Keep in mind that text needs to be encoded in to
+  :class:`bytes` before compressing and decompressing:
 
   >>> s = 'Three shall be the number thou shalt count, '
   >>> s += 'and the number of the counting shall be three'
@@ -682,8 +684,8 @@
   >>> c = gzip.compress(b)
   >>> len(c)
   77
-  >>> gzip.decompress(c).decode()[:43]      # decompress and convert to text
-  'Three shall be the number thou shalt count, '
+  >>> gzip.decompress(c).decode()[:42]      # decompress and convert to text
+  'Three shall be the number thou shalt count,'
 
   (Contributed by Anand B. Pillai in :issue:`3488`; and by Antoine Pitrou, Nir
   Aides and Brian Curtin in :issue:`9962`, :issue:`1675951`, :issue:`7471` and
@@ -883,7 +885,6 @@
 
 .. XXX: Create a new section for all changes relating to context managers.
 .. XXX: Various ConfigParser changes
-.. XXX: Mention inspect.getattr_static (Michael Foord)
 .. XXX: Mention urllib.parse changes
           Issue 9873 (Nick Coghlan):
             - ASCII byte sequence support in URL parsing

From python-checkins at python.org  Wed Dec  8 15:47:07 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Wed,  8 Dec 2010 15:47:07 +0100 (CET)
Subject: [Python-checkins] r87132 - python/branches/py3k/PC/VC6/readme.txt
Message-ID: <20101208144707.A3747EEAED@mail.python.org>

Author: hirokazu.yamamoto
Date: Wed Dec  8 15:47:07 2010
New Revision: 87132

Log:
Mention NASM which is needed to build openssl-1.0.0a original source.
(PC/VC6/readme.txt)


Modified:
   python/branches/py3k/PC/VC6/readme.txt

Modified: python/branches/py3k/PC/VC6/readme.txt
==============================================================================
--- python/branches/py3k/PC/VC6/readme.txt	(original)
+++ python/branches/py3k/PC/VC6/readme.txt	Wed Dec  8 15:47:07 2010
@@ -158,9 +158,17 @@
     You can (theoretically) use any version of OpenSSL you like - the
     build process will automatically select the latest version.
 
-    You must also install ActivePerl from
+    You can install the NASM assembler from
+        http://www.nasm.us/
+    for x86 builds.  Put nasmw.exe anywhere in your PATH.
+    Note: recent releases of nasm only have nasm.exe. Just rename it to 
+    nasmw.exe.
+
+    You can also install ActivePerl from
         http://www.activestate.com/activeperl/
-    as this is used by the OpenSSL build process.  Complain to them .
+    if you like to use the official sources instead of the files from 
+    python's subversion repository. The svn version contains pre-build
+    makefiles and assembly files.
 
     The MSVC project simply invokes PC/VC6/build_ssl.py to perform
     the build.  This Python script locates and builds your OpenSSL

From python-checkins at python.org  Wed Dec  8 22:21:56 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Wed,  8 Dec 2010 22:21:56 +0100 (CET)
Subject: [Python-checkins] r87133 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208212156.DEC3DEEA3A@mail.python.org>

Author: alexander.belopolsky
Date: Wed Dec  8 22:21:56 2010
New Revision: 87133

Log:
Added a datetime new features entry

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 22:21:56 2010
@@ -609,6 +609,27 @@
   (Contributed by Raymond Hettinger and incorporating design suggestions
   from Mark Dickinson.)
 
+.. XXX: Add a section describing new feature added to datetime module
+
+   * The :mod:`datetime` received several new features including
+
+     - A new type, :class:`timezone` that implements :class:`tzinfo`
+       interface by returning fixed UTC offset and timezone name. This
+       makes it easier to create aware :class:datetime` objects::
+
+       >>> datetime.datetime.now(datetime.timezone.utc)
+       datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)
+
+       >>> datetime.datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
+       datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
+
+      (See :issue:`5094` and :issue:`6641`.)
+
+     - :class: timedelta objects can now be multiplied by float and
+       divided by float and int objects.
+
+       (See :issue:`1289118`.)
+
 * The :mod:`nntplib` module gets a revamped implementation with better bytes and
   unicode semantics as well as more practical APIs.  These improvements break
   compatibility with the nntplib version in Python 3.1, which was partly

From python-checkins at python.org  Wed Dec  8 22:38:46 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Wed,  8 Dec 2010 22:38:46 +0100 (CET)
Subject: [Python-checkins] r87134 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101208213846.D01E0EE982@mail.python.org>

Author: alexander.belopolsky
Date: Wed Dec  8 22:38:46 2010
New Revision: 87134

Log:
Edited the Unicode 6.0.0 entry to add unicode.org links and trim the summary.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Wed Dec  8 22:38:46 2010
@@ -1095,20 +1095,23 @@
 Python has been updated to Unicode 6.0.0.  The new features of the
 Unicode Standard that will affect Python users include:
 
-* adds 2,088 characters, including over 1,000 additional symbols?chief
-  among them the additional emoji symbols, which are especially
-  important for mobile phones;
+* addition of 2,088 characters, including over 1,000 additional
+  symbols?chief among them the additional emoji symbols, which are
+  especially important for mobile phones;
 
-* corrects character properties for existing characters including
+* changes to character properties for existing characters including
 
   - a general category change to two Kannada characters (U+0CF1,
     U+0CF2), which has the effect of making them newly eligible for
     inclusion in identifiers;
 
   - a general category change to one New Tai Lue numeric character
-    (U+19DA), which would have the effect of disqualifying it from
-    inclusion in identifiers unless grandfathering measures are in place
-    for the defining identifier syntax.
+    (U+19DA), which has the effect of disqualifying it from
+    inclusion in identifiers.
+
+  For more information, see `Unicode Character Database Changes
+  `_
+  at the `Unicode Consortium `_ web site.
 
 The :mod:`os` module has two new functions: :func:`~os.fsencode` and
 :func:`~os.fsdecode`. Add :data:`os.environb`: bytes version of

From python-checkins at python.org  Wed Dec  8 23:25:45 2010
From: python-checkins at python.org (victor.stinner)
Date: Wed,  8 Dec 2010 23:25:45 +0100 (CET)
Subject: [Python-checkins] r87135 - in python/branches/py3k:
	Doc/library/codecs.rst Lib/test/test_codecs.py
Message-ID: <20101208222545.4AC7FEE9AA@mail.python.org>

Author: victor.stinner
Date: Wed Dec  8 23:25:45 2010
New Revision: 87135

Log:
Issue #10546: UTF-16-LE and UTF-16-BE *do* support non-BMP characters

Fix the doc and add tests.


Modified:
   python/branches/py3k/Doc/library/codecs.rst
   python/branches/py3k/Lib/test/test_codecs.py

Modified: python/branches/py3k/Doc/library/codecs.rst
==============================================================================
--- python/branches/py3k/Doc/library/codecs.rst	(original)
+++ python/branches/py3k/Doc/library/codecs.rst	Wed Dec  8 23:25:45 2010
@@ -1114,9 +1114,9 @@
 +-----------------+--------------------------------+--------------------------------+
 | utf_16          | U16, utf16                     | all languages                  |
 +-----------------+--------------------------------+--------------------------------+
-| utf_16_be       | UTF-16BE                       | all languages (BMP only)       |
+| utf_16_be       | UTF-16BE                       | all languages                  |
 +-----------------+--------------------------------+--------------------------------+
-| utf_16_le       | UTF-16LE                       | all languages (BMP only)       |
+| utf_16_le       | UTF-16LE                       | all languages                  |
 +-----------------+--------------------------------+--------------------------------+
 | utf_7           | U7, unicode-1-1-utf-7          | all languages                  |
 +-----------------+--------------------------------+--------------------------------+

Modified: python/branches/py3k/Lib/test/test_codecs.py
==============================================================================
--- python/branches/py3k/Lib/test/test_codecs.py	(original)
+++ python/branches/py3k/Lib/test/test_codecs.py	Wed Dec  8 23:25:45 2010
@@ -544,6 +544,12 @@
         self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode,
                           b"\xff", "strict", True)
 
+    def test_nonbmp(self):
+        self.assertEqual("\U00010203".encode(self.encoding),
+                         b'\x00\xd8\x03\xde')
+        self.assertEqual(b'\x00\xd8\x03\xde'.decode(self.encoding),
+                         "\U00010203")
+
 class UTF16BETest(ReadTest):
     encoding = "utf-16-be"
 
@@ -566,6 +572,12 @@
         self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode,
                           b"\xff", "strict", True)
 
+    def test_nonbmp(self):
+        self.assertEqual("\U00010203".encode(self.encoding),
+                         b'\xd8\x00\xde\x03')
+        self.assertEqual(b'\xd8\x00\xde\x03'.decode(self.encoding),
+                         "\U00010203")
+
 class UTF8Test(ReadTest):
     encoding = "utf-8"
 

From python-checkins at python.org  Wed Dec  8 23:53:00 2010
From: python-checkins at python.org (r.david.murray)
Date: Wed,  8 Dec 2010 23:53:00 +0100 (CET)
Subject: [Python-checkins] r87136 -
	python/branches/py3k/Lib/test/script_helper.py
Message-ID: <20101208225300.66903EEA2A@mail.python.org>

Author: r.david.murray
Date: Wed Dec  8 23:53:00 2010
New Revision: 87136

Log:
Have script_helper._assert_python strip refcount strings from stderr.

This makes the output of the function and those that depend on it
independent of whether or not they are being run under a debug
build.


Modified:
   python/branches/py3k/Lib/test/script_helper.py

Modified: python/branches/py3k/Lib/test/script_helper.py
==============================================================================
--- python/branches/py3k/Lib/test/script_helper.py	(original)
+++ python/branches/py3k/Lib/test/script_helper.py	Wed Dec  8 23:53:00 2010
@@ -3,6 +3,7 @@
 
 import sys
 import os
+import re
 import os.path
 import tempfile
 import subprocess
@@ -12,7 +13,7 @@
 import zipfile
 
 from imp import source_from_cache
-from test.support import make_legacy_pyc
+from test.support import make_legacy_pyc, strip_python_stderr
 
 # Executing the interpreter in a subprocess
 def _assert_python(expected_success, *args, **env_vars):
@@ -34,6 +35,7 @@
         p.stdout.close()
         p.stderr.close()
     rc = p.returncode
+    err =  strip_python_stderr(err)
     if (rc and expected_success) or (not rc and not expected_success):
         raise AssertionError(
             "Process return code is %d, "

From python-checkins at python.org  Thu Dec  9 00:31:49 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Thu,  9 Dec 2010 00:31:49 +0100 (CET)
Subject: [Python-checkins] r87137 - in python/branches/py3k:
	Lib/test/datetimetester.py Lib/test/test_pyexpat.py
	Lib/test/test_socket.py Lib/test/test_syslog.py
	Lib/test/test_xml_etree_c.py Modules/_datetimemodule.c
	Modules/_elementtree.c Modules/_lsprof.c
	Modules/_testcapimodule.c Modules/parsermodule.c
	Modules/pyexpat.c Modules/socketmodule.c Modules/syslogmodule.c
Message-ID: <20101208233149.3E78AEE9AA@mail.python.org>

Author: alexander.belopolsky
Date: Thu Dec  9 00:31:48 2010
New Revision: 87137

Log:
Issue #6697: Fixed instances of _PyUnicode_AsString() result not checked for NULL

Modified:
   python/branches/py3k/Lib/test/datetimetester.py
   python/branches/py3k/Lib/test/test_pyexpat.py
   python/branches/py3k/Lib/test/test_socket.py
   python/branches/py3k/Lib/test/test_syslog.py
   python/branches/py3k/Lib/test/test_xml_etree_c.py
   python/branches/py3k/Modules/_datetimemodule.c
   python/branches/py3k/Modules/_elementtree.c
   python/branches/py3k/Modules/_lsprof.c
   python/branches/py3k/Modules/_testcapimodule.c
   python/branches/py3k/Modules/parsermodule.c
   python/branches/py3k/Modules/pyexpat.c
   python/branches/py3k/Modules/socketmodule.c
   python/branches/py3k/Modules/syslogmodule.c

Modified: python/branches/py3k/Lib/test/datetimetester.py
==============================================================================
--- python/branches/py3k/Lib/test/datetimetester.py	(original)
+++ python/branches/py3k/Lib/test/datetimetester.py	Thu Dec  9 00:31:48 2010
@@ -2508,11 +2508,17 @@
 
         # Check that an invalid tzname result raises an exception.
         class Badtzname(tzinfo):
-            def tzname(self, dt): return 42
+            tz = 42
+            def tzname(self, dt): return self.tz
         t = time(2, 3, 4, tzinfo=Badtzname())
         self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04")
         self.assertRaises(TypeError, t.strftime, "%Z")
 
+        # Issue #6697:
+        if '_Fast' in str(type(self)):
+            Badtzname.tz = '\ud800'
+            self.assertRaises(ValueError, t.strftime, "%Z")
+
     def test_hash_edge_cases(self):
         # Offsets that overflow a basic time.
         t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, ""))

Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py	(original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py	Thu Dec  9 00:31:48 2010
@@ -203,6 +203,8 @@
 
         operations = out.out
         self._verify_parse_output(operations)
+        # Issue #6697.
+        self.assertRaises(AttributeError, getattr, parser, '\uD800')
 
     def test_parse_file(self):
         # Try parsing a file

Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py	(original)
+++ python/branches/py3k/Lib/test/test_socket.py	Thu Dec  9 00:31:48 2010
@@ -667,6 +667,8 @@
                                type=socket.SOCK_STREAM, proto=0,
                                flags=socket.AI_PASSIVE)
         self.assertEqual(a, b)
+        # Issue #6697.
+        self.assertRaises(UnicodeEncodeError, socket.getaddrinfo, 'localhost', '\uD800')
 
     def test_getnameinfo(self):
         # only IP addresses are allowed

Modified: python/branches/py3k/Lib/test/test_syslog.py
==============================================================================
--- python/branches/py3k/Lib/test/test_syslog.py	(original)
+++ python/branches/py3k/Lib/test/test_syslog.py	Thu Dec  9 00:31:48 2010
@@ -11,6 +11,8 @@
 
     def test_openlog(self):
         syslog.openlog('python')
+        # Issue #6697.
+        self.assertRaises(UnicodeEncodeError, syslog.openlog, '\uD800')
 
     def test_syslog(self):
         syslog.openlog('python')

Modified: python/branches/py3k/Lib/test/test_xml_etree_c.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xml_etree_c.py	(original)
+++ python/branches/py3k/Lib/test/test_xml_etree_c.py	Thu Dec  9 00:31:48 2010
@@ -8,10 +8,26 @@
 # cElementTree specific tests
 
 def sanity():
-    """
+    r"""
     Import sanity.
 
     >>> from xml.etree import cElementTree
+
+    Issue #6697.
+
+    >>> e = cElementTree.Element('a')
+    >>> getattr(e, '\uD800')           # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+      ...
+    UnicodeEncodeError: ...
+
+    >>> p = cElementTree.XMLParser()
+    >>> p.version.split()[0]
+    'Expat'
+    >>> getattr(p, '\uD800')
+    Traceback (most recent call last):
+     ...
+    AttributeError: 'XMLParser' object has no attribute '\ud800'
     """
 
 

Modified: python/branches/py3k/Modules/_datetimemodule.c
==============================================================================
--- python/branches/py3k/Modules/_datetimemodule.c	(original)
+++ python/branches/py3k/Modules/_datetimemodule.c	Thu Dec  9 00:31:48 2010
@@ -1257,7 +1257,8 @@
             assert(PyUnicode_Check(Zreplacement));
             ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
                                                   &ntoappend);
-            ntoappend = Py_SIZE(Zreplacement);
+            if (ptoappend == NULL)
+                goto Done;
         }
         else if (ch == 'f') {
             /* format microseconds */

Modified: python/branches/py3k/Modules/_elementtree.c
==============================================================================
--- python/branches/py3k/Modules/_elementtree.c	(original)
+++ python/branches/py3k/Modules/_elementtree.c	Thu Dec  9 00:31:48 2010
@@ -1483,6 +1483,9 @@
 
     if (PyUnicode_Check(nameobj))
         name = _PyUnicode_AsString(nameobj);
+    
+    if (name == NULL)
+        return NULL;
 
     /* handle common attributes first */
     if (strcmp(name, "tag") == 0) {
@@ -2139,7 +2142,7 @@
     PyObject *position;
     char buffer[256];
 
-    sprintf(buffer, "%s: line %d, column %d", message, line, column);
+    sprintf(buffer, "%.100s: line %d, column %d", message, line, column);
 
     error = PyObject_CallFunction(elementtree_parseerror_obj, "s", buffer);
     if (!error)
@@ -2194,8 +2197,8 @@
         Py_XDECREF(res);
     } else if (!PyErr_Occurred()) {
         /* Report the first error, not the last */
-        char message[128];
-        sprintf(message, "undefined entity &%.100s;", _PyUnicode_AsString(key));
+        char message[128] = "undefined entity ";
+        strncat(message, data_in, data_len < 100?data_len:100);
         expat_set_error(
             message,
             EXPAT(GetErrorLineNumber)(self->parser),
@@ -2796,29 +2799,25 @@
 static PyObject*  
 xmlparser_getattro(XMLParserObject* self, PyObject* nameobj)
 {
-    PyObject* res;
-    char *name = "";
-
-    if (PyUnicode_Check(nameobj))
-        name = _PyUnicode_AsString(nameobj);
-
-    PyErr_Clear();
-
-    if (strcmp(name, "entity") == 0)
-        res = self->entity;
-    else if (strcmp(name, "target") == 0)
-        res = self->target;
-    else if (strcmp(name, "version") == 0) {
-        char buffer[100];
-        sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
+    if (PyUnicode_Check(nameobj)) {
+        PyObject* res;
+        if (PyUnicode_CompareWithASCIIString(nameobj, "entity") == 0)
+            res = self->entity;
+        else if (PyUnicode_CompareWithASCIIString(nameobj, "target") == 0)
+            res = self->target;
+        else if (PyUnicode_CompareWithASCIIString(nameobj, "version") == 0) {
+            return PyUnicode_FromFormat(
+                "Expat %d.%d.%d", XML_MAJOR_VERSION,
                 XML_MINOR_VERSION, XML_MICRO_VERSION);
-        return PyUnicode_DecodeUTF8(buffer, strlen(buffer), "strict");
-    } else {
-        return PyObject_GenericGetAttr((PyObject*) self, nameobj);
-    }
+        }
+        else
+            goto generic;
 
-    Py_INCREF(res);
-    return res;
+        Py_INCREF(res);
+        return res;
+    }
+  generic:
+    return PyObject_GenericGetAttr((PyObject*) self, nameobj);
 }
 
 static PyTypeObject XMLParser_Type = {

Modified: python/branches/py3k/Modules/_lsprof.c
==============================================================================
--- python/branches/py3k/Modules/_lsprof.c	(original)
+++ python/branches/py3k/Modules/_lsprof.c	Thu Dec  9 00:31:48 2010
@@ -178,7 +178,16 @@
         PyObject *mod = fn->m_module;
         const char *modname;
         if (mod && PyUnicode_Check(mod)) {
+            /* XXX: The following will truncate module names with embedded
+             * null-characters.  It is unlikely that this can happen in
+             * practice and the concequences are not serious enough to
+             * introduce extra checks here.
+             */
             modname = _PyUnicode_AsString(mod);
+            if (modname == NULL) {
+                modname = "";
+                PyErr_Clear();
+            }
         }
         else if (mod && PyModule_Check(mod)) {
             modname = PyModule_GetName(mod);

Modified: python/branches/py3k/Modules/_testcapimodule.c
==============================================================================
--- python/branches/py3k/Modules/_testcapimodule.c	(original)
+++ python/branches/py3k/Modules/_testcapimodule.c	Thu Dec  9 00:31:48 2010
@@ -1741,15 +1741,16 @@
 {
     PyObject *result;
     char *msg;
+    static const Py_UNICODE one[] = {'1', 0};
 
-#define CHECK_1_FORMAT(FORMAT, TYPE)                    \
-    result = PyUnicode_FromFormat(FORMAT, (TYPE)1);     \
-    if (result == NULL)                                 \
-        return NULL;                                    \
-    if (strcmp(_PyUnicode_AsString(result), "1")) {     \
-        msg = FORMAT " failed at 1";                    \
-        goto Fail;                                      \
-    }                                                   \
+#define CHECK_1_FORMAT(FORMAT, TYPE)                                \
+    result = PyUnicode_FromFormat(FORMAT, (TYPE)1);                 \
+    if (result == NULL)                                             \
+        return NULL;                                                \
+    if (Py_UNICODE_strcmp(PyUnicode_AS_UNICODE(result), one)) {     \
+        msg = FORMAT " failed at 1";                                \
+        goto Fail;                                                  \
+    }                                                               \
     Py_DECREF(result)
 
     CHECK_1_FORMAT("%d", int);

Modified: python/branches/py3k/Modules/parsermodule.c
==============================================================================
--- python/branches/py3k/Modules/parsermodule.c	(original)
+++ python/branches/py3k/Modules/parsermodule.c	Thu Dec  9 00:31:48 2010
@@ -792,6 +792,11 @@
                 }
             }
             temp_str = _PyUnicode_AsStringAndSize(temp, &len);
+            if (temp_str == NULL) {
+                Py_DECREF(temp);
+                Py_XDECREF(elem);
+                return 0;
+            }
             strn = (char *)PyObject_MALLOC(len + 1);
             if (strn != NULL)
                 (void) memcpy(strn, temp_str, len + 1);
@@ -870,6 +875,8 @@
             encoding = PySequence_GetItem(tuple, 2);
             /* tuple isn't borrowed anymore here, need to DECREF */
             tuple = PySequence_GetSlice(tuple, 0, 2);
+            if (tuple == NULL)
+                return NULL;
         }
         res = PyNode_New(num);
         if (res != NULL) {
@@ -881,6 +888,12 @@
                 Py_ssize_t len;
                 const char *temp;
                 temp = _PyUnicode_AsStringAndSize(encoding, &len);
+                if (temp == NULL) {
+                    Py_DECREF(res);
+                    Py_DECREF(encoding);
+                    Py_DECREF(tuple);
+                    return NULL;
+                }
                 res->n_str = (char *)PyObject_MALLOC(len + 1);
                 if (res->n_str != NULL && temp != NULL)
                     (void) memcpy(res->n_str, temp, len + 1);

Modified: python/branches/py3k/Modules/pyexpat.c
==============================================================================
--- python/branches/py3k/Modules/pyexpat.c	(original)
+++ python/branches/py3k/Modules/pyexpat.c	Thu Dec  9 00:31:48 2010
@@ -1215,11 +1215,12 @@
 }
 
 static int
-handlername2int(const char *name)
+handlername2int(PyObject *name)
 {
     int i;
     for (i = 0; handler_info[i].name != NULL; i++) {
-        if (strcmp(name, handler_info[i].name) == 0) {
+        if (PyUnicode_CompareWithASCIIString(
+                name, handler_info[i].name) == 0) {
             return i;
         }
     }
@@ -1237,13 +1238,13 @@
 static PyObject *
 xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
 {
-    char *name = "";
+    Py_UNICODE *name;
     int handlernum = -1;
 
-    if (PyUnicode_Check(nameobj))
-        name = _PyUnicode_AsString(nameobj);
+    if (!PyUnicode_Check(nameobj))
+        goto generic;
 
-    handlernum = handlername2int(name);
+    handlernum = handlername2int(nameobj);
 
     if (handlernum != -1) {
         PyObject *result = self->handlers[handlernum];
@@ -1252,46 +1253,48 @@
         Py_INCREF(result);
         return result;
     }
+
+    name = PyUnicode_AS_UNICODE(nameobj);
     if (name[0] == 'E') {
-        if (strcmp(name, "ErrorCode") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorCode") == 0)
             return PyLong_FromLong((long)
                                   XML_GetErrorCode(self->itself));
-        if (strcmp(name, "ErrorLineNumber") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorLineNumber") == 0)
             return PyLong_FromLong((long)
                                   XML_GetErrorLineNumber(self->itself));
-        if (strcmp(name, "ErrorColumnNumber") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorColumnNumber") == 0)
             return PyLong_FromLong((long)
                                   XML_GetErrorColumnNumber(self->itself));
-        if (strcmp(name, "ErrorByteIndex") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorByteIndex") == 0)
             return PyLong_FromLong((long)
                                   XML_GetErrorByteIndex(self->itself));
     }
     if (name[0] == 'C') {
-        if (strcmp(name, "CurrentLineNumber") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentLineNumber") == 0)
             return PyLong_FromLong((long)
                                   XML_GetCurrentLineNumber(self->itself));
-        if (strcmp(name, "CurrentColumnNumber") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentColumnNumber") == 0)
             return PyLong_FromLong((long)
                                   XML_GetCurrentColumnNumber(self->itself));
-        if (strcmp(name, "CurrentByteIndex") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentByteIndex") == 0)
             return PyLong_FromLong((long)
                                   XML_GetCurrentByteIndex(self->itself));
     }
     if (name[0] == 'b') {
-        if (strcmp(name, "buffer_size") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_size") == 0)
             return PyLong_FromLong((long) self->buffer_size);
-        if (strcmp(name, "buffer_text") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_text") == 0)
             return get_pybool(self->buffer != NULL);
-        if (strcmp(name, "buffer_used") == 0)
+        if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_used") == 0)
             return PyLong_FromLong((long) self->buffer_used);
     }
-    if (strcmp(name, "namespace_prefixes") == 0)
+    if (PyUnicode_CompareWithASCIIString(nameobj, "namespace_prefixes") == 0)
         return get_pybool(self->ns_prefixes);
-    if (strcmp(name, "ordered_attributes") == 0)
+    if (PyUnicode_CompareWithASCIIString(nameobj, "ordered_attributes") == 0)
         return get_pybool(self->ordered_attributes);
-    if (strcmp(name, "specified_attributes") == 0)
+    if (PyUnicode_CompareWithASCIIString(nameobj, "specified_attributes") == 0)
         return get_pybool((long) self->specified_attributes);
-    if (strcmp(name, "intern") == 0) {
+    if (PyUnicode_CompareWithASCIIString(nameobj, "intern") == 0) {
         if (self->intern == NULL) {
             Py_INCREF(Py_None);
             return Py_None;
@@ -1301,7 +1304,7 @@
             return self->intern;
         }
     }
-
+  generic:
     return PyObject_GenericGetAttr((PyObject*)self, nameobj);
 }
 
@@ -1352,7 +1355,7 @@
 }
 
 static int
-sethandler(xmlparseobject *self, const char *name, PyObject* v)
+sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
 {
     int handlernum = handlername2int(name);
     if (handlernum >= 0) {
@@ -1388,14 +1391,15 @@
 }
 
 static int
-xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
+xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
 {
     /* Set attribute 'name' to value 'v'. v==NULL means delete */
     if (v == NULL) {
         PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
         return -1;
     }
-    if (strcmp(name, "buffer_text") == 0) {
+    assert(PyUnicode_Check(name));
+    if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
         if (PyObject_IsTrue(v)) {
             if (self->buffer == NULL) {
                 self->buffer = malloc(self->buffer_size);
@@ -1414,7 +1418,7 @@
         }
         return 0;
     }
-    if (strcmp(name, "namespace_prefixes") == 0) {
+    if (PyUnicode_CompareWithASCIIString(name, "namespace_prefixes") == 0) {
         if (PyObject_IsTrue(v))
             self->ns_prefixes = 1;
         else
@@ -1422,14 +1426,14 @@
         XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
         return 0;
     }
-    if (strcmp(name, "ordered_attributes") == 0) {
+    if (PyUnicode_CompareWithASCIIString(name, "ordered_attributes") == 0) {
         if (PyObject_IsTrue(v))
             self->ordered_attributes = 1;
         else
             self->ordered_attributes = 0;
         return 0;
     }
-    if (strcmp(name, "specified_attributes") == 0) {
+    if (PyUnicode_CompareWithASCIIString(name, "specified_attributes") == 0) {
         if (PyObject_IsTrue(v))
             self->specified_attributes = 1;
         else
@@ -1437,7 +1441,7 @@
         return 0;
     }
 
-    if (strcmp(name, "buffer_size") == 0) {
+    if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
       long new_buffer_size;
       if (!PyLong_Check(v)) {
         PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
@@ -1480,7 +1484,7 @@
       return 0;
     }
 
-    if (strcmp(name, "CharacterDataHandler") == 0) {
+    if (PyUnicode_CompareWithASCIIString(name, "CharacterDataHandler") == 0) {
         /* If we're changing the character data handler, flush all
          * cached data with the old handler.  Not sure there's a
          * "right" thing to do, though, but this probably won't
@@ -1492,7 +1496,7 @@
     if (sethandler(self, name, v)) {
         return 0;
     }
-    PyErr_SetString(PyExc_AttributeError, name);
+    PyErr_SetObject(PyExc_AttributeError, name);
     return -1;
 }
 
@@ -1524,7 +1528,7 @@
         (destructor)xmlparse_dealloc,   /*tp_dealloc*/
         (printfunc)0,           /*tp_print*/
         0,                      /*tp_getattr*/
-        (setattrfunc)xmlparse_setattr,  /*tp_setattr*/
+        0,  /*tp_setattr*/
         0,                      /*tp_reserved*/
         (reprfunc)0,            /*tp_repr*/
         0,                      /*tp_as_number*/
@@ -1534,7 +1538,7 @@
         (ternaryfunc)0,         /*tp_call*/
         (reprfunc)0,            /*tp_str*/
         (getattrofunc)xmlparse_getattro, /* tp_getattro */
-        0,              /* tp_setattro */
+        (setattrofunc)xmlparse_setattro,              /* tp_setattro */
         0,              /* tp_as_buffer */
         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
         Xmlparsetype__doc__, /* tp_doc - Documentation string */

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Thu Dec  9 00:31:48 2010
@@ -1406,9 +1406,9 @@
         {
             struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret;
 #if defined(__NetBSD__) || defined(__DragonFly__)
-			char *straddr = PyBytes_AS_STRING(args);
+                        char *straddr = PyBytes_AS_STRING(args);
 
-			_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
+                        _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
             if (straddr == NULL) {
                 PyErr_SetString(socket_error, "getsockaddrarg: "
                     "wrong format");
@@ -4022,8 +4022,10 @@
         pptr = pbuf;
     } else if (PyUnicode_Check(pobj)) {
         pptr = _PyUnicode_AsString(pobj);
+        if (pptr == NULL)
+            goto err;
     } else if (PyBytes_Check(pobj)) {
-        pptr = PyBytes_AsString(pobj);
+        pptr = PyBytes_AS_STRING(pobj);
     } else if (pobj == Py_None) {
         pptr = (char *)NULL;
     } else {

Modified: python/branches/py3k/Modules/syslogmodule.c
==============================================================================
--- python/branches/py3k/Modules/syslogmodule.c	(original)
+++ python/branches/py3k/Modules/syslogmodule.c	Thu Dec  9 00:31:48 2010
@@ -68,9 +68,9 @@
      * is optional.
      */
 
-    Py_ssize_t argv_len;
+    Py_ssize_t argv_len, scriptlen;
     PyObject *scriptobj;
-    char *atslash;
+    Py_UNICODE *atslash, *atstart;
     PyObject *argv = PySys_GetObject("argv");
 
     if (argv == NULL) {
@@ -90,13 +90,16 @@
     if (!PyUnicode_Check(scriptobj)) {
         return(NULL);
     }
-    if (PyUnicode_GET_SIZE(scriptobj) == 0) {
+    scriptlen = PyUnicode_GET_SIZE(scriptobj);
+    if (scriptlen == 0) {
         return(NULL);
     }
 
-    atslash = strrchr(_PyUnicode_AsString(scriptobj), SEP);
+    atstart = PyUnicode_AS_UNICODE(scriptobj);
+    atslash = Py_UNICODE_strrchr(atstart, SEP);
     if (atslash) {
-        return(PyUnicode_FromString(atslash + 1));
+        return(PyUnicode_FromUnicode(atslash + 1,
+                                     scriptlen - (atslash - atstart) - 1));
     } else {
         Py_INCREF(scriptobj);
         return(scriptobj);
@@ -113,6 +116,7 @@
     long facility = LOG_USER;
     PyObject *new_S_ident_o = NULL;
     static char *keywords[] = {"ident", "logoption", "facility", 0};
+    char *ident = NULL;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds,
                           "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility))
@@ -120,12 +124,12 @@
 
     if (new_S_ident_o) {
         Py_INCREF(new_S_ident_o);
-        }
+    }
 
     /*  get sys.argv[0] or NULL if we can't for some reason  */
     if (!new_S_ident_o) {
         new_S_ident_o = syslog_get_argv();
-        }
+    }
 
     Py_XDECREF(S_ident_o);
     S_ident_o = new_S_ident_o;
@@ -134,8 +138,13 @@
      * make a copy, and syslog(3) later uses it.  We can't garbagecollect it
      * If NULL, just let openlog figure it out (probably using C argv[0]).
      */
+    if (S_ident_o) {
+        ident = _PyUnicode_AsString(S_ident_o);
+        if (ident == NULL)
+            return NULL;
+    }
 
-    openlog(S_ident_o ? _PyUnicode_AsString(S_ident_o) : NULL, logopt, facility);
+    openlog(ident, logopt, facility);
     S_log_open = 1;
 
     Py_INCREF(Py_None);

From solipsis at pitrou.net  Thu Dec  9 04:49:28 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Thu, 09 Dec 2010 04:49:28 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87137): sum=0
Message-ID: 

py3k results for svn r87137 (hg cset 6799ef85ab2d)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogk8_aSa', '-x']

From python-checkins at python.org  Thu Dec  9 09:01:24 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 09:01:24 +0100 (CET)
Subject: [Python-checkins] r87138 - in python/branches/release27-maint:
	PC/VC6/build_ssl.py PC/VC6/readme.txt PC/VS8.0/build_ssl.py
	PCbuild/build_ssl.py PCbuild/readme.txt
Message-ID: <20101209080124.261B0EEA13@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 09:01:18 2010
New Revision: 87138

Log:
Merged revisions 85071-85072,85894,87132 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85071 | hirokazu.yamamoto | 2010-09-29 03:29:57 +0900 (?, 29 9 2010) | 1 line
  
  Now perl path with spaces can be used.
........
  r85072 | hirokazu.yamamoto | 2010-09-29 03:36:04 +0900 (?, 29 9 2010) | 1 line
  
  Updated PC/VC6 openssl build script. (for openssl-1.0.0a)
........
  r85894 | hirokazu.yamamoto | 2010-10-29 02:57:25 +0900 (?, 29 10 2010) | 1 line
  
  Updated readme.txt about OpenSSL.
........
  r87132 | hirokazu.yamamoto | 2010-12-08 23:47:07 +0900 (?, 08 12 2010) | 3 lines
  
  Mention NASM which is needed to build openssl-1.0.0a original source.
  (PC/VC6/readme.txt)
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/PC/VC6/build_ssl.py
   python/branches/release27-maint/PC/VC6/readme.txt
   python/branches/release27-maint/PC/VS8.0/build_ssl.py
   python/branches/release27-maint/PCbuild/build_ssl.py
   python/branches/release27-maint/PCbuild/readme.txt

Modified: python/branches/release27-maint/PC/VC6/build_ssl.py
==============================================================================
--- python/branches/release27-maint/PC/VC6/build_ssl.py	(original)
+++ python/branches/release27-maint/PC/VC6/build_ssl.py	Thu Dec  9 09:01:18 2010
@@ -13,6 +13,11 @@
 # it should configure and build SSL, then build the ssl Python extension
 # without intervention.
 
+# Modified by Christian Heimes
+# Now this script supports pre-generated makefiles and assembly files.
+# Developers don't need an installation of Perl anymore to build Python. A svn
+# checkout from our svn repository is enough.
+
 import os, sys, re, shutil
 
 # Find all "foo.exe" files on the PATH.
@@ -36,7 +41,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -120,6 +125,22 @@
     print do_script
     os.system(do_script)
 
+def cmp(f1, f2):
+    bufsize = 1024 * 8
+    with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
+        while True:
+            b1 = fp1.read(bufsize)
+            b2 = fp2.read(bufsize)
+            if b1 != b2:
+                return False
+            if not b1:
+                return True
+
+def copy(src, dst):
+    if os.path.isfile(dst) and cmp(src, dst):
+        return
+    shutil.copy(src, dst)
+
 def main():
     debug = "-d" in sys.argv
     build_all = "-a" in sys.argv
@@ -129,6 +150,7 @@
         do_script = "ms\\do_nasm"
         makefile="ms\\nt.mak"
         m32 = makefile
+        dirsuffix = "32"
     configure += " no-idea no-rc5 no-mdc2"
     make_flags = ""
     if build_all:
@@ -137,12 +159,12 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
-        print "No Perl installation was found. Existing Makefiles are used."
-    else:
+    if perl:
         print "Found a working perl at '%s'" % (perl,)
+    else:
+        print "No Perl installation was found. Existing Makefiles are used."
     sys.stdout.flush()
-    # Look for SSL 3 levels up from pcbuild - ie, same place zlib etc all live.
+    # Look for SSL 3 levels up from PC/VC6 - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..\\..",))
     if ssl_dir is None:
         sys.exit(1)
@@ -173,12 +195,21 @@
             #    os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
 
             fix_makefile(makefile)
-            shutil.copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
-            shutil.copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
+            copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
+            copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
+
+        # If the assembler files don't exist in tmpXX, copy them there
+        if perl is None:
+            if not os.path.exists("tmp"+dirsuffix):
+                os.mkdir("tmp"+dirsuffix)
+            for f in os.listdir("asm"+dirsuffix):
+                if not f.endswith(".asm"): continue
+                if os.path.isfile(r"tmp%s\%s" % (dirsuffix, f)): continue
+                shutil.copy(r"asm%s\%s" % (dirsuffix, f), "tmp"+dirsuffix)
 
         # Now run make.
-        shutil.copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h")
-        shutil.copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h")
+        copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h")
+        copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h")
 
         #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
         makeCommand = "nmake /nologo -f \"%s\"" % makefile

Modified: python/branches/release27-maint/PC/VC6/readme.txt
==============================================================================
--- python/branches/release27-maint/PC/VC6/readme.txt	(original)
+++ python/branches/release27-maint/PC/VC6/readme.txt	Thu Dec  9 09:01:18 2010
@@ -202,21 +202,27 @@
     Get the latest source code for OpenSSL from
         http://www.openssl.org
 
-    You (probably) don't want the "engine" code.  For example, get
-        openssl-0.9.8g.tar.gz
-    not
-        openssl-engine-0.9.8g.tar.gz
+    You (probably) don't want the "engine" code.  For example, don't get
+        openssl-engine-0.9.6g.tar.gz
 
     Unpack into the "dist" directory, retaining the folder name from
     the archive - for example, the latest stable OpenSSL will install as
-        dist/openssl-0.9.8g
+        dist/openssl-1.0.0a
 
     You can (theoretically) use any version of OpenSSL you like - the
     build process will automatically select the latest version.
 
-    You must also install ActivePerl from
-        http://www.activestate.com/Products/ActivePerl/
-    as this is used by the OpenSSL build process.  Complain to them .
+    You can install the NASM assembler from
+        http://www.nasm.us/
+    for x86 builds.  Put nasmw.exe anywhere in your PATH.
+    Note: recent releases of nasm only have nasm.exe. Just rename it to 
+    nasmw.exe.
+
+    You can also install ActivePerl from
+        http://www.activestate.com/activeperl/
+    if you like to use the official sources instead of the files from 
+    python's subversion repository. The svn version contains pre-build
+    makefiles and assembly files.
 
     The MSVC project simply invokes PC/VC6/build_ssl.py to perform
     the build.  This Python script locates and builds your OpenSSL

Modified: python/branches/release27-maint/PC/VS8.0/build_ssl.py
==============================================================================
--- python/branches/release27-maint/PC/VS8.0/build_ssl.py	(original)
+++ python/branches/release27-maint/PC/VS8.0/build_ssl.py	Thu Dec  9 09:01:18 2010
@@ -8,7 +8,7 @@
 #   directory.  It is likely you will already find the zlib library and
 #   any other external packages there.
 # * Install ActivePerl and ensure it is somewhere on your path.
-# * Run this script from the PCBuild directory.
+# * Run this script from the PC/VS8.0 directory.
 #
 # it should configure and build SSL, then build the _ssl and _hashlib
 # Python extensions without intervention.
@@ -46,7 +46,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -178,12 +178,12 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
+    if perl:
+        print("Found a working perl at '%s'" % (perl,))
+    else:
         print("No Perl installation was found. Existing Makefiles are used.")
-
-    print("Found a working perl at '%s'" % (perl,))
     sys.stdout.flush()
-    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
+    # Look for SSL 3 levels up from PC/VS8.0 - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..\\..",))
     if ssl_dir is None:
         sys.exit(1)

Modified: python/branches/release27-maint/PCbuild/build_ssl.py
==============================================================================
--- python/branches/release27-maint/PCbuild/build_ssl.py	(original)
+++ python/branches/release27-maint/PCbuild/build_ssl.py	Thu Dec  9 09:01:18 2010
@@ -47,7 +47,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -184,10 +184,10 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
+    if perl:
+        print("Found a working perl at '%s'" % (perl,))
+    else:
         print("No Perl installation was found. Existing Makefiles are used.")
-
-    print("Found a working perl at '%s'" % (perl,))
     sys.stdout.flush()
     # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..",))

Modified: python/branches/release27-maint/PCbuild/readme.txt
==============================================================================
--- python/branches/release27-maint/PCbuild/readme.txt	(original)
+++ python/branches/release27-maint/PCbuild/readme.txt	Thu Dec  9 09:01:18 2010
@@ -159,7 +159,7 @@
     nasmw.exe.
 
     You can also install ActivePerl from
-        http://www.activestate.com/Products/ActivePerl/
+        http://www.activestate.com/activeperl/
     if you like to use the official sources instead of the files from 
     python's subversion repository. The svn version contains pre-build
     makefiles and assembly files.

From python-checkins at python.org  Thu Dec  9 10:25:38 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 10:25:38 +0100 (CET)
Subject: [Python-checkins] r87139 - in python/branches/release31-maint:
	PC/VC6/build_ssl.py PC/VC6/readme.txt PC/VS8.0/build_ssl.py
	PCbuild/build_ssl.py PCbuild/readme.txt
Message-ID: <20101209092538.CC91BEE982@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 10:25:38 2010
New Revision: 87139

Log:
Merged revisions 85071-85072,85894,87132 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85071 | hirokazu.yamamoto | 2010-09-29 03:29:57 +0900 (?, 29 9 2010) | 1 line
  
  Now perl path with spaces can be used.
........
  r85072 | hirokazu.yamamoto | 2010-09-29 03:36:04 +0900 (?, 29 9 2010) | 1 line
  
  Updated PC/VC6 openssl build script. (for openssl-1.0.0a)
........
  r85894 | hirokazu.yamamoto | 2010-10-29 02:57:25 +0900 (?, 29 10 2010) | 1 line
  
  Updated readme.txt about OpenSSL.
........
  r87132 | hirokazu.yamamoto | 2010-12-08 23:47:07 +0900 (?, 08 12 2010) | 3 lines
  
  Mention NASM which is needed to build openssl-1.0.0a original source.
  (PC/VC6/readme.txt)
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/PC/VC6/build_ssl.py
   python/branches/release31-maint/PC/VC6/readme.txt
   python/branches/release31-maint/PC/VS8.0/build_ssl.py
   python/branches/release31-maint/PCbuild/build_ssl.py
   python/branches/release31-maint/PCbuild/readme.txt

Modified: python/branches/release31-maint/PC/VC6/build_ssl.py
==============================================================================
--- python/branches/release31-maint/PC/VC6/build_ssl.py	(original)
+++ python/branches/release31-maint/PC/VC6/build_ssl.py	Thu Dec  9 10:25:38 2010
@@ -13,6 +13,11 @@
 # it should configure and build SSL, then build the ssl Python extension
 # without intervention.
 
+# Modified by Christian Heimes
+# Now this script supports pre-generated makefiles and assembly files.
+# Developers don't need an installation of Perl anymore to build Python. A svn
+# checkout from our svn repository is enough.
+
 import os, sys, re, shutil
 
 # Find all "foo.exe" files on the PATH.
@@ -36,7 +41,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -120,6 +125,22 @@
     print(do_script)
     os.system(do_script)
 
+def cmp(f1, f2):
+    bufsize = 1024 * 8
+    with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
+        while True:
+            b1 = fp1.read(bufsize)
+            b2 = fp2.read(bufsize)
+            if b1 != b2:
+                return False
+            if not b1:
+                return True
+
+def copy(src, dst):
+    if os.path.isfile(dst) and cmp(src, dst):
+        return
+    shutil.copy(src, dst)
+
 def main():
     debug = "-d" in sys.argv
     build_all = "-a" in sys.argv
@@ -129,6 +150,7 @@
         do_script = "ms\\do_nasm"
         makefile="ms\\nt.mak"
         m32 = makefile
+        dirsuffix = "32"
     configure += " no-idea no-rc5 no-mdc2"
     make_flags = ""
     if build_all:
@@ -137,12 +159,12 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
-        print("No Perl installation was found. Existing Makefiles are used.")
-    else:
+    if perl:
         print("Found a working perl at '%s'" % (perl,))
+    else:
+        print("No Perl installation was found. Existing Makefiles are used.")
     sys.stdout.flush()
-    # Look for SSL 3 levels up from pcbuild - ie, same place zlib etc all live.
+    # Look for SSL 3 levels up from PC/VC6 - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..\\..",))
     if ssl_dir is None:
         sys.exit(1)
@@ -173,12 +195,21 @@
             #    os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
 
             fix_makefile(makefile)
-            shutil.copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
-            shutil.copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
+            copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
+            copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
+
+        # If the assembler files don't exist in tmpXX, copy them there
+        if perl is None:
+            if not os.path.exists("tmp"+dirsuffix):
+                os.mkdir("tmp"+dirsuffix)
+            for f in os.listdir("asm"+dirsuffix):
+                if not f.endswith(".asm"): continue
+                if os.path.isfile(r"tmp%s\%s" % (dirsuffix, f)): continue
+                shutil.copy(r"asm%s\%s" % (dirsuffix, f), "tmp"+dirsuffix)
 
         # Now run make.
-        shutil.copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h")
-        shutil.copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h")
+        copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h")
+        copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h")
 
         #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
         makeCommand = "nmake /nologo -f \"%s\"" % makefile

Modified: python/branches/release31-maint/PC/VC6/readme.txt
==============================================================================
--- python/branches/release31-maint/PC/VC6/readme.txt	(original)
+++ python/branches/release31-maint/PC/VC6/readme.txt	Thu Dec  9 10:25:38 2010
@@ -149,21 +149,27 @@
     Get the latest source code for OpenSSL from
         http://www.openssl.org
 
-    You (probably) don't want the "engine" code.  For example, get
-        openssl-0.9.8g.tar.gz
-    not
-        openssl-engine-0.9.8g.tar.gz
+    You (probably) don't want the "engine" code.  For example, don't get
+        openssl-engine-0.9.6g.tar.gz
 
     Unpack into the "dist" directory, retaining the folder name from
     the archive - for example, the latest stable OpenSSL will install as
-        dist/openssl-0.9.8g
+        dist/openssl-1.0.0a
 
     You can (theoretically) use any version of OpenSSL you like - the
     build process will automatically select the latest version.
 
-    You must also install ActivePerl from
-        http://www.activestate.com/Products/ActivePerl/
-    as this is used by the OpenSSL build process.  Complain to them .
+    You can install the NASM assembler from
+        http://www.nasm.us/
+    for x86 builds.  Put nasmw.exe anywhere in your PATH.
+    Note: recent releases of nasm only have nasm.exe. Just rename it to 
+    nasmw.exe.
+
+    You can also install ActivePerl from
+        http://www.activestate.com/activeperl/
+    if you like to use the official sources instead of the files from 
+    python's subversion repository. The svn version contains pre-build
+    makefiles and assembly files.
 
     The MSVC project simply invokes PC/VC6/build_ssl.py to perform
     the build.  This Python script locates and builds your OpenSSL

Modified: python/branches/release31-maint/PC/VS8.0/build_ssl.py
==============================================================================
--- python/branches/release31-maint/PC/VS8.0/build_ssl.py	(original)
+++ python/branches/release31-maint/PC/VS8.0/build_ssl.py	Thu Dec  9 10:25:38 2010
@@ -8,7 +8,7 @@
 #   directory.  It is likely you will already find the zlib library and
 #   any other external packages there.
 # * Install ActivePerl and ensure it is somewhere on your path.
-# * Run this script from the PCBuild directory.
+# * Run this script from the PC/VS8.0 directory.
 #
 # it should configure and build SSL, then build the _ssl and _hashlib
 # Python extensions without intervention.
@@ -46,7 +46,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -178,12 +178,12 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
+    if perl:
+        print("Found a working perl at '%s'" % (perl,))
+    else:
         print("No Perl installation was found. Existing Makefiles are used.")
-
-    print("Found a working perl at '%s'" % (perl,))
     sys.stdout.flush()
-    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
+    # Look for SSL 3 levels up from PC/VS8.0 - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..\\..",))
     if ssl_dir is None:
         sys.exit(1)

Modified: python/branches/release31-maint/PCbuild/build_ssl.py
==============================================================================
--- python/branches/release31-maint/PCbuild/build_ssl.py	(original)
+++ python/branches/release31-maint/PCbuild/build_ssl.py	Thu Dec  9 10:25:38 2010
@@ -46,7 +46,7 @@
 # is available.
 def find_working_perl(perls):
     for perl in perls:
-        fh = os.popen(perl + ' -e "use Win32;"')
+        fh = os.popen('"%s" -e "use Win32;"' % perl)
         fh.read()
         rc = fh.close()
         if rc:
@@ -186,10 +186,10 @@
     # as "well known" locations
     perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
     perl = find_working_perl(perls)
-    if perl is None:
+    if perl:
+        print("Found a working perl at '%s'" % (perl,))
+    else:
         print("No Perl installation was found. Existing Makefiles are used.")
-
-    print("Found a working perl at '%s'" % (perl,))
     sys.stdout.flush()
     # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
     ssl_dir = find_best_ssl_dir(("..\\..",))

Modified: python/branches/release31-maint/PCbuild/readme.txt
==============================================================================
--- python/branches/release31-maint/PCbuild/readme.txt	(original)
+++ python/branches/release31-maint/PCbuild/readme.txt	Thu Dec  9 10:25:38 2010
@@ -156,7 +156,7 @@
     nasmw.exe.
 
     You can also install ActivePerl from
-        http://www.activestate.com/Products/ActivePerl/
+        http://www.activestate.com/activeperl/
     if you like to use the official sources instead of the files from 
     python's subversion repository. The svn version contains pre-build
     makefiles and assembly files.

From python-checkins at python.org  Thu Dec  9 11:49:00 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 11:49:00 +0100 (CET)
Subject: [Python-checkins] r87140 - python/branches/py3k/Modules/_ssl.c
Message-ID: <20101209104900.CB39FEEA5D@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 11:49:00 2010
New Revision: 87140

Log:
Should call Py_INCREF for Py_None (Modules/_ssl.c: PySSL_cipher)


Modified:
   python/branches/py3k/Modules/_ssl.c

Modified: python/branches/py3k/Modules/_ssl.c
==============================================================================
--- python/branches/py3k/Modules/_ssl.c	(original)
+++ python/branches/py3k/Modules/_ssl.c	Thu Dec  9 11:49:00 2010
@@ -928,10 +928,10 @@
     char *cipher_protocol;
 
     if (self->ssl == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
     current = SSL_get_current_cipher(self->ssl);
     if (current == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
 
     retval = PyTuple_New(3);
     if (retval == NULL)
@@ -939,6 +939,7 @@
 
     cipher_name = (char *) SSL_CIPHER_get_name(current);
     if (cipher_name == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 0, Py_None);
     } else {
         v = PyUnicode_FromString(cipher_name);
@@ -948,6 +949,7 @@
     }
     cipher_protocol = SSL_CIPHER_get_version(current);
     if (cipher_protocol == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 1, Py_None);
     } else {
         v = PyUnicode_FromString(cipher_protocol);

From python-checkins at python.org  Thu Dec  9 12:13:31 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 12:13:31 +0100 (CET)
Subject: [Python-checkins] r87141 -
	python/branches/py3k/Lib/test/win_console_handler.py
Message-ID: <20101209111331.25AD1EE998@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 12:13:30 2010
New Revision: 87141

Log:
Fixed typo in comment.


Modified:
   python/branches/py3k/Lib/test/win_console_handler.py

Modified: python/branches/py3k/Lib/test/win_console_handler.py
==============================================================================
--- python/branches/py3k/Lib/test/win_console_handler.py	(original)
+++ python/branches/py3k/Lib/test/win_console_handler.py	Thu Dec  9 12:13:30 2010
@@ -40,7 +40,7 @@
         print("Unable to add SetConsoleCtrlHandler")
         exit(-1)
 
-    # Awaken mail process
+    # Awake main process
     m = mmap.mmap(-1, 1, sys.argv[1])
     m[0] = 1
 

From python-checkins at python.org  Thu Dec  9 13:12:42 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 13:12:42 +0100 (CET)
Subject: [Python-checkins] r87142 - in python/branches/release27-maint:
	Modules/_ssl.c
Message-ID: <20101209121242.6CF18EE982@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 13:12:42 2010
New Revision: 87142

Log:
Merged revisions 87140 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87140 | hirokazu.yamamoto | 2010-12-09 19:49:00 +0900 (?, 09 12 2010) | 2 lines
  
  Should call Py_INCREF for Py_None (Modules/_ssl.c: PySSL_cipher)
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Modules/_ssl.c

Modified: python/branches/release27-maint/Modules/_ssl.c
==============================================================================
--- python/branches/release27-maint/Modules/_ssl.c	(original)
+++ python/branches/release27-maint/Modules/_ssl.c	Thu Dec  9 13:12:42 2010
@@ -1046,10 +1046,10 @@
     char *cipher_protocol;
 
     if (self->ssl == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
     current = SSL_get_current_cipher(self->ssl);
     if (current == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
 
     retval = PyTuple_New(3);
     if (retval == NULL)
@@ -1057,6 +1057,7 @@
 
     cipher_name = (char *) SSL_CIPHER_get_name(current);
     if (cipher_name == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 0, Py_None);
     } else {
         v = PyString_FromString(cipher_name);
@@ -1066,6 +1067,7 @@
     }
     cipher_protocol = SSL_CIPHER_get_version(current);
     if (cipher_protocol == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 1, Py_None);
     } else {
         v = PyString_FromString(cipher_protocol);

From python-checkins at python.org  Thu Dec  9 13:13:38 2010
From: python-checkins at python.org (georg.brandl)
Date: Thu,  9 Dec 2010 13:13:38 +0100 (CET)
Subject: [Python-checkins] r87143 -
	python/branches/release27-maint/Doc/library/queue.rst
Message-ID: <20101209121338.5FB47EEA5A@mail.python.org>

Author: georg.brandl
Date: Thu Dec  9 13:13:38 2010
New Revision: 87143

Log:
#10658: Fix link.

Modified:
   python/branches/release27-maint/Doc/library/queue.rst

Modified: python/branches/release27-maint/Doc/library/queue.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/queue.rst	(original)
+++ python/branches/release27-maint/Doc/library/queue.rst	Thu Dec  9 13:13:38 2010
@@ -27,7 +27,7 @@
 .. seealso::
 
    Latest version of the `queue module Python source code
-   `_
+   `_.
 
 The :mod:`Queue` module defines the following classes and exceptions:
 

From python-checkins at python.org  Thu Dec  9 13:30:05 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu,  9 Dec 2010 13:30:05 +0100 (CET)
Subject: [Python-checkins] r87144 - in python/branches/release31-maint:
	Modules/_ssl.c
Message-ID: <20101209123005.814CAEEA13@mail.python.org>

Author: hirokazu.yamamoto
Date: Thu Dec  9 13:30:05 2010
New Revision: 87144

Log:
Merged revisions 87140 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87140 | hirokazu.yamamoto | 2010-12-09 19:49:00 +0900 (?, 09 12 2010) | 2 lines
  
  Should call Py_INCREF for Py_None (Modules/_ssl.c: PySSL_cipher)
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Modules/_ssl.c

Modified: python/branches/release31-maint/Modules/_ssl.c
==============================================================================
--- python/branches/release31-maint/Modules/_ssl.c	(original)
+++ python/branches/release31-maint/Modules/_ssl.c	Thu Dec  9 13:30:05 2010
@@ -1047,10 +1047,10 @@
     char *cipher_protocol;
 
     if (self->ssl == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
     current = SSL_get_current_cipher(self->ssl);
     if (current == NULL)
-        return Py_None;
+        Py_RETURN_NONE;
 
     retval = PyTuple_New(3);
     if (retval == NULL)
@@ -1058,6 +1058,7 @@
 
     cipher_name = (char *) SSL_CIPHER_get_name(current);
     if (cipher_name == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 0, Py_None);
     } else {
         v = PyUnicode_FromString(cipher_name);
@@ -1067,6 +1068,7 @@
     }
     cipher_protocol = SSL_CIPHER_get_version(current);
     if (cipher_protocol == NULL) {
+        Py_INCREF(Py_None);
         PyTuple_SET_ITEM(retval, 1, Py_None);
     } else {
         v = PyUnicode_FromString(cipher_protocol);

From python-checkins at python.org  Thu Dec  9 17:41:54 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu,  9 Dec 2010 17:41:54 +0100 (CET)
Subject: [Python-checkins] r87145 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101209164154.5A45DEEAA3@mail.python.org>

Author: raymond.hettinger
Date: Thu Dec  9 17:41:54 2010
New Revision: 87145

Log:
Entries for datetime, callable, and collections.Counter.


Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Thu Dec  9 17:41:54 2010
@@ -547,7 +547,12 @@
 
 * The :func:`callable` builtin function from Py2.x was resurrected.  It provides
   a concise, readable alternative to using an :term:`abstract base class` in an
-  expression like ``isinstance(x, collections.Callable)``.
+  expression like ``isinstance(x, collections.Callable)``:
+
+  >>> callable(max)
+  True
+  >>> callable(20)
+  False
 
   (See :issue:`10518`.)
 
@@ -588,7 +593,12 @@
   pointing to the original callable function.  This allows wrapped functions to
   be introspected.  It also copies :attr:`__annotations__` if defined.  And now
   it also gracefully skips over missing attributes such as :attr:`__doc__` which
-  might not be defined for the wrapped callable.
+  might not be defined for the wrapped callable:
+
+  >>> callable(max)
+  True
+  >>> callable(20)
+  False
 
   (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
   :issue:`8814`.)
@@ -609,26 +619,42 @@
   (Contributed by Raymond Hettinger and incorporating design suggestions
   from Mark Dickinson.)
 
-.. XXX: Add a section describing new feature added to datetime module
-
-   * The :mod:`datetime` received several new features including
-
-     - A new type, :class:`timezone` that implements :class:`tzinfo`
-       interface by returning fixed UTC offset and timezone name. This
-       makes it easier to create aware :class:datetime` objects::
-
-       >>> datetime.datetime.now(datetime.timezone.utc)
-       datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)
-
-       >>> datetime.datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
-       datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
+* The :class:`collections.Counter` class now has two forms of in-place
+  subtraction, the existing *-=* operator for `saturating subtraction
+  `_ and the new
+  :meth:`~collections.Counter.subtract` method for regular subtraction.  The
+  former is suitable for `multisets `_
+  which only have positive counts, and the latter is more suitable for counters
+  that allow negative counts:
+
+  >>> tally = Counter(dogs=5, cat=3)
+  >>> tally -= Counter(dogs=2, cats=8)    # saturating subtraction
+  >>> tally
+  Counter({'dogs': 3})
+
+  >>> tally = Counter(dogs=5, cats=3)
+  >>> tally.subtract(dogs=2, cats=8)      # regular subtraction
+  >>> tally
+  Counter({'dogs': 3, 'cats': -5})
+
+  (Contributed by Raymond Hettinger.)
+
+* The :mod:`datetime` module has a new type :class:`~datetime.timezone` that
+  implements the :class:`~datetime.tzinfo` interface by returning a fixed UTC
+  offset and timezone name. This makes it easier to create timezone aware
+  datetime objects:
+
+  >>> datetime.now(timezone.utc)
+  datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)
 
-      (See :issue:`5094` and :issue:`6641`.)
+  >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
+  datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
 
-     - :class: timedelta objects can now be multiplied by float and
-       divided by float and int objects.
+  Also, :class:`~datetime.timedelta` objects can now be multiplied by
+  :class:`float` and divided by :class:`float` and :class:`int` objects.
 
-       (See :issue:`1289118`.)
+  (Contributed by Alexander Belopolsky in :issue:`1289118`, :issue:`5094` and
+  :issue:`6641`.)
 
 * The :mod:`nntplib` module gets a revamped implementation with better bytes and
   unicode semantics as well as more practical APIs.  These improvements break

From python-checkins at python.org  Thu Dec  9 19:08:43 2010
From: python-checkins at python.org (georg.brandl)
Date: Thu,  9 Dec 2010 19:08:43 +0100 (CET)
Subject: [Python-checkins] r87146 - in python/branches/py3k:
	Doc/library/concurrent.futures.rst Lib/concurrent/futures/process.py
Message-ID: <20101209180843.DEEF7EE9F9@mail.python.org>

Author: georg.brandl
Date: Thu Dec  9 19:08:43 2010
New Revision: 87146

Log:
Fix "seperate".

Modified:
   python/branches/py3k/Doc/library/concurrent.futures.rst
   python/branches/py3k/Lib/concurrent/futures/process.py

Modified: python/branches/py3k/Doc/library/concurrent.futures.rst
==============================================================================
--- python/branches/py3k/Doc/library/concurrent.futures.rst	(original)
+++ python/branches/py3k/Doc/library/concurrent.futures.rst	Thu Dec  9 19:08:43 2010
@@ -10,7 +10,7 @@
 asynchronously executing callables.
 
 The asynchronous execution can be be performed with threads, using
-:class:`ThreadPoolExecutor`, or seperate processes, using
+:class:`ThreadPoolExecutor`, or separate processes, using
 :class:`ProcessPoolExecutor`.  Both implement the same interface, which is
 defined by the abstract :class:`Executor` class.
 

Modified: python/branches/py3k/Lib/concurrent/futures/process.py
==============================================================================
--- python/branches/py3k/Lib/concurrent/futures/process.py	(original)
+++ python/branches/py3k/Lib/concurrent/futures/process.py	Thu Dec  9 19:08:43 2010
@@ -118,7 +118,7 @@
 def _process_worker(call_queue, result_queue, shutdown):
     """Evaluates calls from call_queue and places the results in result_queue.
 
-    This worker is run in a seperate process.
+    This worker is run in a separate process.
 
     Args:
         call_queue: A multiprocessing.Queue of _CallItems that will be read and

From python-checkins at python.org  Thu Dec  9 19:10:28 2010
From: python-checkins at python.org (georg.brandl)
Date: Thu,  9 Dec 2010 19:10:28 +0100 (CET)
Subject: [Python-checkins] r87147 -
	python/branches/py3k/Lib/xml/etree/ElementTree.py
Message-ID: <20101209181028.125F0EEA7D@mail.python.org>

Author: georg.brandl
Date: Thu Dec  9 19:10:27 2010
New Revision: 87147

Log:
#10661: give QName a nicer repr.

Modified:
   python/branches/py3k/Lib/xml/etree/ElementTree.py

Modified: python/branches/py3k/Lib/xml/etree/ElementTree.py
==============================================================================
--- python/branches/py3k/Lib/xml/etree/ElementTree.py	(original)
+++ python/branches/py3k/Lib/xml/etree/ElementTree.py	Thu Dec  9 19:10:27 2010
@@ -584,6 +584,8 @@
         self.text = text_or_uri
     def __str__(self):
         return self.text
+    def __repr__(self):
+        return '' % self.text
     def __hash__(self):
         return hash(self.text)
     def __le__(self, other):

From python-checkins at python.org  Thu Dec  9 19:26:02 2010
From: python-checkins at python.org (georg.brandl)
Date: Thu,  9 Dec 2010 19:26:02 +0100 (CET)
Subject: [Python-checkins] r87148 -
	python/branches/py3k/Lib/xml/etree/ElementTree.py
Message-ID: <20101209182602.3649BEE983@mail.python.org>

Author: georg.brandl
Date: Thu Dec  9 19:26:02 2010
New Revision: 87148

Log:
Guard against rogue tuples.

Modified:
   python/branches/py3k/Lib/xml/etree/ElementTree.py

Modified: python/branches/py3k/Lib/xml/etree/ElementTree.py
==============================================================================
--- python/branches/py3k/Lib/xml/etree/ElementTree.py	(original)
+++ python/branches/py3k/Lib/xml/etree/ElementTree.py	Thu Dec  9 19:26:02 2010
@@ -585,7 +585,7 @@
     def __str__(self):
         return self.text
     def __repr__(self):
-        return '' % self.text
+        return '' % (self.text,)
     def __hash__(self):
         return hash(self.text)
     def __le__(self, other):

From ncoghlan at gmail.com  Thu Dec  9 23:18:00 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Fri, 10 Dec 2010 08:18:00 +1000
Subject: [Python-checkins] r87145 -
	python/branches/py3k/Doc/whatsnew/3.2.rst
In-Reply-To: <20101209164154.5A45DEEAA3@mail.python.org>
References: <20101209164154.5A45DEEAA3@mail.python.org>
Message-ID: 

On Fri, Dec 10, 2010 at 2:41 AM, raymond.hettinger
 wrote:
> @@ -588,7 +593,12 @@
> ? pointing to the original callable function. ?This allows wrapped functions to
> ? be introspected. ?It also copies :attr:`__annotations__` if defined. ?And now
> ? it also gracefully skips over missing attributes such as :attr:`__doc__` which
> - ?might not be defined for the wrapped callable.
> + ?might not be defined for the wrapped callable:
> +
> + ?>>> callable(max)
> + ?True
> + ?>>> callable(20)
> + ?False

Placeholder example?

Cheers,
Nick.

--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From raymond.hettinger at gmail.com  Thu Dec  9 23:45:57 2010
From: raymond.hettinger at gmail.com (Raymond Hettinger)
Date: Thu, 9 Dec 2010 14:45:57 -0800
Subject: [Python-checkins] r87145 -
	python/branches/py3k/Doc/whatsnew/3.2.rst
In-Reply-To: 
References: <20101209164154.5A45DEEAA3@mail.python.org>
	
Message-ID: <09990EAC-E8CA-4ADD-807B-93E6650215D7@gmail.com>


On Dec 9, 2010, at 2:18 PM, Nick Coghlan wrote:

> On Fri, Dec 10, 2010 at 2:41 AM, raymond.hettinger
>  wrote:
>> @@ -588,7 +593,12 @@
>>   pointing to the original callable function.  This allows wrapped functions to
>>   be introspected.  It also copies :attr:`__annotations__` if defined.  And now
>>   it also gracefully skips over missing attributes such as :attr:`__doc__` which
>> -  might not be defined for the wrapped callable.
>> +  might not be defined for the wrapped callable:
>> +
>> +  >>> callable(max)
>> +  True
>> +  >>> callable(20)
>> +  False
> 
> Placeholder example?
> 

Trivial function begets a trivial example :-)

If you think it warrants more, I'm open to suggestions.


Raymond


From eric at trueblade.com  Thu Dec  9 23:54:12 2010
From: eric at trueblade.com (Eric Smith)
Date: Thu, 09 Dec 2010 17:54:12 -0500
Subject: [Python-checkins] r87145
	-	python/branches/py3k/Doc/whatsnew/3.2.rst
In-Reply-To: <09990EAC-E8CA-4ADD-807B-93E6650215D7@gmail.com>
References: <20101209164154.5A45DEEAA3@mail.python.org>	
	<09990EAC-E8CA-4ADD-807B-93E6650215D7@gmail.com>
Message-ID: <4D015E14.3040807@trueblade.com>

On 12/9/2010 5:45 PM, Raymond Hettinger wrote:
>
> On Dec 9, 2010, at 2:18 PM, Nick Coghlan wrote:
>
>> On Fri, Dec 10, 2010 at 2:41 AM, raymond.hettinger
>>   wrote:
>>> @@ -588,7 +593,12 @@
>>>    pointing to the original callable function.  This allows wrapped functions to
>>>    be introspected.  It also copies :attr:`__annotations__` if defined.  And now
>>>    it also gracefully skips over missing attributes such as :attr:`__doc__` which
>>> -  might not be defined for the wrapped callable.
>>> +  might not be defined for the wrapped callable:
>>> +
>>> +>>>  callable(max)
>>> +  True
>>> +>>>  callable(20)
>>> +  False
>>
>> Placeholder example?
>>
>
> Trivial function begets a trivial example :-)
>
> If you think it warrants more, I'm open to suggestions.

I think the issue is that the section is talking about functools.wraps, 
the example is for callable().

From ncoghlan at gmail.com  Fri Dec 10 00:28:55 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Fri, 10 Dec 2010 09:28:55 +1000
Subject: [Python-checkins] r87145 -
	python/branches/py3k/Doc/whatsnew/3.2.rst
In-Reply-To: <4D015E14.3040807@trueblade.com>
References: <20101209164154.5A45DEEAA3@mail.python.org>
	
	<09990EAC-E8CA-4ADD-807B-93E6650215D7@gmail.com>
	<4D015E14.3040807@trueblade.com>
Message-ID: 

On Fri, Dec 10, 2010 at 8:54 AM, Eric Smith  wrote:
> On 12/9/2010 5:45 PM, Raymond Hettinger wrote:
>> Trivial function begets a trivial example :-)
>>
>> If you think it warrants more, I'm open to suggestions.
>
> I think the issue is that the section is talking about functools.wraps, the
> example is for callable().

Yeah, sorry about that - I should have been clearer as to what I was
asking about.

It looks like the callable example had been copied to get the
formatting started for the updated functools.wraps example, but the
actual example for the latter didn't get filled in.

Cheers,
Nick.

-- 
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From python-checkins at python.org  Fri Dec 10 00:43:34 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 10 Dec 2010 00:43:34 +0100 (CET)
Subject: [Python-checkins] r87149 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101209234334.D25ACEE982@mail.python.org>

Author: raymond.hettinger
Date: Fri Dec 10 00:43:34 2010
New Revision: 87149

Log:
Doh! Example pasted twice, but only once in the right place.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Fri Dec 10 00:43:34 2010
@@ -593,12 +593,7 @@
   pointing to the original callable function.  This allows wrapped functions to
   be introspected.  It also copies :attr:`__annotations__` if defined.  And now
   it also gracefully skips over missing attributes such as :attr:`__doc__` which
-  might not be defined for the wrapped callable:
-
-  >>> callable(max)
-  True
-  >>> callable(20)
-  False
+  might not be defined for the wrapped callable.
 
   (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
   :issue:`8814`.)

From nnorwitz at gmail.com  Fri Dec 10 00:49:51 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Thu, 9 Dec 2010 18:49:51 -0500
Subject: [Python-checkins] Python Regression Test Failures refleak (1)
Message-ID: <20101209234951.GA23571@kbk-i386-bb.dyndns.org>

More important issues:
----------------------
test_itertools leaked [0, 0, 32] references, sum=32

Less important issues:
----------------------
test_bz2 leaked [0, 84, -84] references, sum=0

From python-checkins at python.org  Fri Dec 10 02:09:02 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 10 Dec 2010 02:09:02 +0100 (CET)
Subject: [Python-checkins] r87150 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101210010902.13B4DEEA95@mail.python.org>

Author: raymond.hettinger
Date: Fri Dec 10 02:09:01 2010
New Revision: 87150

Log:
Overview of email module and recategorize various entries.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Fri Dec 10 02:09:01 2010
@@ -364,8 +364,12 @@
 Email
 =====
 
-The email package has been extended to parse and generate email messages
-in bytes format.
+The usability of the :mod:`email` package in Python 3 has been mostly fixed by
+the extensive efforts of R. David Murray.  The problem was that emails are
+typically read and stored in the form of :class:`bytes` rather than :class:`str`
+text, and they may contain multiple encodings within a single email.  So, the
+email package had to be extended to parse and generate email messages in bytes
+format.
 
 * New functions :func:`~email.message_from_bytes` and
   :func:`~email.message_from_binary_file`, and new classes
@@ -374,17 +378,19 @@
 
 * Given bytes input to the model, :meth:`~email.message.Message.get_payload`
   will by default decode a message body that has a
-  :mailheader:`Content-Transfer-Encoding` of ``8bit`` using the charset
+  :mailheader:`Content-Transfer-Encoding` of *8bit* using the charset
   specified in the MIME headers and return the resulting string.
 
 * Given bytes input to the model, :class:`~email.generator.Generator` will
   convert message bodies that have a :mailheader:`Content-Transfer-Encoding` of
-  8bit to instead have a 7bit Content-Transfer-Encoding.
+  *8bit* to instead have a *7bit* :mailheader:`Content-Transfer-Encoding`.
 
-* New class :class:`~email.generator.BytesGenerator` produces bytes
-  as output, preserving any unchanged non-ASCII data that was
-  present in the input used to build the model, including message bodies
-  with a :mailheader:`Content-Transfer-Encoding` of 8bit.
+* A new class :class:`~email.generator.BytesGenerator` produces bytes as output,
+  preserving any unchanged non-ASCII data that was present in the input used to
+  build the model, including message bodies with a
+  :mailheader:`Content-Transfer-Encoding` of *8bit*.
+
+.. XXX Update before 3.2rc1 to reflect all of the last work and add examples.
 
   (Proposed and implemented by R. David Murray, :issue:`4661`.)
 
@@ -394,9 +400,10 @@
 
 Some smaller changes made to the core Python language are:
 
-* :class:`bytes` and :class:`str` now have two net methods, *transform* and *untransform*.
-  These provided analogues to *encode* and *decode* but are used for general purpose
-  string-to-string and bytes-to-bytes transformations rather than Unicode codecs.
+* :class:`bytes` and :class:`str` now have two net methods, *transform* and
+  *untransform*.  These provide analogues to *encode* and *decode* but are used
+  for general purpose str-to-str and bytes-to-bytes transformations rather than
+  Unicode codecs for bytes-to-str and str-to-bytes.
 
   Along with the new methods, several non-unicode codecs been restored from Python 2.x
   including *base64*, *bz2*, *hex*, *quopri*, *rot13*, *uu*, and *zlib*.
@@ -441,7 +448,7 @@
   implement proxy objects.
 
   To support lookups without the possibility of activating a dynamic attribute,
-  the :mod:`inspect` module has a new function, :func:`getattr_static`.
+  the :mod:`inspect` module has a new function, :func:`~inspect.getattr_static`.
 
   (Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.
   The inspect function added by Michael Foord.)
@@ -458,9 +465,10 @@
 
   (Proposed and implemented by Mark Dickinson; :issue:`9337`.)
 
-* :class:`memoryview` objects now have a :meth:`release()` method and support
-  the context manager protocol.  This allows timely release of any resources
-  that were acquired when requesting a buffer from the original object.
+* :class:`memoryview` objects now have a :meth:`~memoryview.release()` method
+  and they also now support the context manager protocol.  This allows timely
+  release of any resources that were acquired when requesting a buffer from the
+  original object.
 
   >>> with memoryview(b'abcdefgh') as v:
   ...     print(v.tolist())
@@ -651,13 +659,6 @@
   (Contributed by Alexander Belopolsky in :issue:`1289118`, :issue:`5094` and
   :issue:`6641`.)
 
-* The :mod:`nntplib` module gets a revamped implementation with better bytes and
-  unicode semantics as well as more practical APIs.  These improvements break
-  compatibility with the nntplib version in Python 3.1, which was partly
-  dysfunctional in itself.
-
-  (Contributed by Antoine Pitrou in :issue:`9360`)
-
 * The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
   :func:`~abc.abstractstaticmethod`.
 
@@ -836,9 +837,9 @@
   >>> with self.assertWarns(DeprecationWarning):
   ...     legacy_function('XYZ')
 
-  Another new method, :meth:`~unittest.TestCase.assertCountEqual` is used to compare two iterables
-  to determine if their element counts are equal (are the same elements present
-  the same number of times::
+  Another new method, :meth:`~unittest.TestCase.assertCountEqual` is used to
+  compare two iterables to determine if their element counts are equal (are the
+  same elements present the same number of times::
 
      def test_anagram(self):
          self.assertCountEqual('algorithm', 'logarithm')
@@ -853,7 +854,11 @@
   In addition the naming in the module has undergone a number of clean-ups.  For
   example, :meth:`~unittest.TestCase.assertRegex` is the new name for
   :meth:`~unittest.TestCase.assertRegexpMatches` which was misnamed because the
-  test uses :func:`re.search`, not :func:`re.match`.
+  test uses :func:`re.search`, not :func:`re.match`.  Other methods using
+  regular expressions are now named using short form "Regex" in preference
+  to "Regexp" -- this matches the names used in other unittest implementations,
+  matches Python's old name for the :mod:`re` module, and it has unambiguous
+  camel-casing.
 
   To improve consistency, some of long-standing method aliases are being
   deprecated in favor of the preferred names:
@@ -1036,12 +1041,6 @@
 
   (Contributed by Antoine Pitrou.)
 
-* Recursive locks (created with the :func:`threading.RLock` API) now benefit
-  from a C implementation which makes them as fast as regular locks, and between
-  10x and 15x faster than their previous pure Python implementation.
-
-  (Contributed by Antoine Pitrou; :issue:`3001`.)
-
 * Regular and recursive locks now accept an optional *timeout* argument to their
   :meth:`acquire` method.  (Contributed by Antoine Pitrou; :issue:`7316`.)
 
@@ -1092,6 +1091,12 @@
   (Contributed by Antoine Pitrou in :issue:`7451` and by Raymond Hettinger and
   Antoine Pitrou in :issue:`10314`.)
 
+* Recursive locks (created with the :func:`threading.RLock` API) now benefit
+  from a C implementation which makes them as fast as regular locks, and between
+  10x and 15x faster than their previous pure Python implementation.
+
+  (Contributed by Antoine Pitrou; :issue:`3001`.)
+
 * The fast-search algorithm in stringlib is now used by the :meth:`split`,
   :meth:`rsplit`, :meth:`splitlines` and :meth:`replace` methods on
   :class:`bytes`, :class:`bytearray` and :class:`str` objects. Likewise, the
@@ -1251,3 +1256,11 @@
    string seeds.  To access the previous version of *seed* in order to
    reproduce Python 3.1 sequences, set the *version* argument to *1*,
    ``random.seed(s, version=1)``.
+
+* The :mod:`nntplib` module has a revamped implementation with better bytes and
+  unicode semantics as well as more practical APIs.  These improvements break
+  compatibility with the nntplib version in Python 3.1, which was partly
+  dysfunctional in itself.
+
+  (Contributed by Antoine Pitrou in :issue:`9360`)
+

From python-checkins at python.org  Fri Dec 10 02:19:15 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 10 Dec 2010 02:19:15 +0100 (CET)
Subject: [Python-checkins] r87151 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101210011915.30BECEEA97@mail.python.org>

Author: raymond.hettinger
Date: Fri Dec 10 02:19:15 2010
New Revision: 87151

Log:
Reclassify some entries and remove a couple of minor ones.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Fri Dec 10 02:19:15 2010
@@ -390,9 +390,15 @@
   build the model, including message bodies with a
   :mailheader:`Content-Transfer-Encoding` of *8bit*.
 
+* The :mod:`smtplib` :class:`~smtplib.SMTP` class now accepts a byte string
+  for the *msg* argument to the :meth:`~smtplib.SMTP.sendmail` method,
+  and a new method, :meth:`~smtplib.SMTP.send_message` accepts a
+  :class:`~email.message.Message` object and can optionally obtain the
+  *from_addr* and *to_addrs* addresses directly from the object.
+
 .. XXX Update before 3.2rc1 to reflect all of the last work and add examples.
 
-  (Proposed and implemented by R. David Murray, :issue:`4661`.)
+  (Proposed and implemented by R. David Murray, :issue:`4661` and :issue:`10321`.)
 
 
 Other Language Changes
@@ -668,20 +674,6 @@
 
   (Patch submitted by Daniel Urban; :issue:`5867`.)
 
-* The previously deprecated :func:`contextlib.nested` function has been removed
-  in favor of a plain :keyword:`with` statement which can accept multiple
-  context managers.  The latter technique is faster (because it is built-in),
-  and it does a better job finalizing multiple context managers when one of them
-  raises an exception::
-
-    >>> with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
-    ...     for line in infile:
-    ...         if '' in line:
-    ...             outfile.write(line)
-
-  (Contributed by Georg Brandl and Mattias Br?ndstr?m;
-  `appspot issue 53094 `_.)
-
 * The :class:`ftplib.FTP` class now supports the context manager protocol to
   unconditionally consume :exc:`socket.error` exceptions and to close the FTP
   connection when done::
@@ -734,16 +726,6 @@
   Aides and Brian Curtin in :issue:`9962`, :issue:`1675951`, :issue:`7471` and
   :issue:`2846`.)
 
-* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
-  constants for use with the :func:`~os.statvfs` function.
-
-  (Patch by Adam Jackson; :issue:`7647`.)
-
-* :func:`os.getppid` is now supported on Windows.  Note that it will continue to
-  return the same pid even after the parent process has exited.
-
-  (Patch by Jon Anglin; :issue:`6394`.)
-
 * The :func:`shutil.copytree` function has two new options:
 
   * *ignore_dangling_symlinks*: when ``symlinks=False`` so that the function
@@ -875,16 +857,6 @@
 
   (Contributed by Ezio Melotti; :issue:`9424`.)
 
-* The previously deprecated :func:`string.maketrans` function has been removed
-  in favor of the static methods, :meth:`bytes.maketrans` and
-  :meth:`bytearray.maketrans`.  This change solves the confusion around which
-  types were supported by the :mod:`string` module.  Now, :class:`str`,
-  :class:`bytes`, and :class:`bytearray` each have their own **maketrans** and
-  **translate** methods with intermediate translation tables of the appropriate
-  type.
-
-  (Contributed by Georg Brandl; :issue:`5675`.)
-
 * :class:`~poplib.POP3_SSL` class now accepts a *context* parameter, which is a
   :class:`ssl.SSLContext` object allowing bundling SSL configuration options,
   certificates and private keys into a single (potentially long-lived)
@@ -916,14 +888,6 @@
 
   (Contributed by Neil Schemenauer and Nick Coghlan; :issue:`5178`.)
 
-* The :mod:`smtplib` :class:`~smtplib.SMTP` class now accepts a byte string
-  for the *msg* argument to the :meth:`~smtplib.SMTP.sendmail` method,
-  and a new method, :meth:`~smtplib.SMTP.send_message` accepts a
-  :class:`~email.message.Message` object and can optionally obtain the
-  *from_addr* and *to_addrs* addresses directly from the object.
-
-  (Contributed by R. David Murray, :issue:`10321`.)
-
 * The :mod:`inspect` module has a new function :func:`getgenatorstate`
   to easily identify the current state of a generator as one of
   ``GEN_CREATED``, ``GEN_RUNNING``, ``GEN_SUSPENDED`` or ``GEN_CLOSED``.
@@ -1264,3 +1228,26 @@
 
   (Contributed by Antoine Pitrou in :issue:`9360`)
 
+* The previously deprecated :func:`string.maketrans` function has been removed
+  in favor of the static methods, :meth:`bytes.maketrans` and
+  :meth:`bytearray.maketrans`.  This change solves the confusion around which
+  types were supported by the :mod:`string` module.  Now, :class:`str`,
+  :class:`bytes`, and :class:`bytearray` each have their own **maketrans** and
+  **translate** methods with intermediate translation tables of the appropriate
+  type.
+
+  (Contributed by Georg Brandl; :issue:`5675`.)
+
+* The previously deprecated :func:`contextlib.nested` function has been removed
+  in favor of a plain :keyword:`with` statement which can accept multiple
+  context managers.  The latter technique is faster (because it is built-in),
+  and it does a better job finalizing multiple context managers when one of them
+  raises an exception::
+
+    >>> with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
+    ...     for line in infile:
+    ...         if '' in line:
+    ...             outfile.write(line)
+
+  (Contributed by Georg Brandl and Mattias Br?ndstr?m;
+  `appspot issue 53094 `_.)

From python-checkins at python.org  Fri Dec 10 03:32:06 2010
From: python-checkins at python.org (ezio.melotti)
Date: Fri, 10 Dec 2010 03:32:06 +0100 (CET)
Subject: [Python-checkins] r87152 - in python/branches/py3k/Lib/unittest:
	case.py test/test_assertions.py
Message-ID: <20101210023206.1F7D0EE981@mail.python.org>

Author: ezio.melotti
Date: Fri Dec 10 03:32:05 2010
New Revision: 87152

Log:
#10273: Remove a "Matches" that I missed in r86910. Thanks to RDM for noticing it.

Modified:
   python/branches/py3k/Lib/unittest/case.py
   python/branches/py3k/Lib/unittest/test/test_assertions.py

Modified: python/branches/py3k/Lib/unittest/case.py
==============================================================================
--- python/branches/py3k/Lib/unittest/case.py	(original)
+++ python/branches/py3k/Lib/unittest/case.py	Fri Dec 10 03:32:05 2010
@@ -1127,7 +1127,7 @@
             msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
             raise self.failureException(msg)
 
-    def assertNotRegexMatches(self, text, unexpected_regex, msg=None):
+    def assertNotRegex(self, text, unexpected_regex, msg=None):
         """Fail the test if the text matches the regular expression."""
         if isinstance(unexpected_regex, (str, bytes)):
             unexpected_regex = re.compile(unexpected_regex)

Modified: python/branches/py3k/Lib/unittest/test/test_assertions.py
==============================================================================
--- python/branches/py3k/Lib/unittest/test/test_assertions.py	(original)
+++ python/branches/py3k/Lib/unittest/test/test_assertions.py	Fri Dec 10 03:32:05 2010
@@ -92,15 +92,15 @@
         else:
             self.fail("assertRaises() didn't let exception pass through")
 
-    def testAssertNotRegexMatches(self):
-        self.assertNotRegexMatches('Ala ma kota', r'r+')
+    def testAssertNotRegex(self):
+        self.assertNotRegex('Ala ma kota', r'r+')
         try:
-            self.assertNotRegexMatches('Ala ma kota', r'k.t', 'Message')
+            self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
         except self.failureException as e:
             self.assertIn("'kot'", e.args[0])
             self.assertIn('Message', e.args[0])
         else:
-            self.fail('assertNotRegexMatches should have failed.')
+            self.fail('assertNotRegex should have failed.')
 
 
 class TestLongMessage(unittest.TestCase):

From solipsis at pitrou.net  Fri Dec 10 04:50:09 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Fri, 10 Dec 2010 04:50:09 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87151): sum=0
Message-ID: 

py3k results for svn r87151 (hg cset b19249664fbe)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog-ooJvL', '-x']

From python-checkins at python.org  Fri Dec 10 09:17:11 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 10 Dec 2010 09:17:11 +0100 (CET)
Subject: [Python-checkins] r87153 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101210081711.12B24EE9D6@mail.python.org>

Author: vinay.sajip
Date: Fri Dec 10 09:17:05 2010
New Revision: 87153

Log:
Minor documentation tweak.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Fri Dec 10 09:17:05 2010
@@ -41,8 +41,8 @@
 It is, of course, possible to log messages with different verbosity levels or to
 different destinations.  Support for writing log messages to files, HTTP
 GET/POST locations, email via SMTP, generic sockets, or OS-specific logging
-mechanisms are all supported by the standard module.  You can also create your
-own log destination class if you have special requirements not met by any of the
+mechanisms is included in the package.  You can also create your own log
+destination class if you have special requirements not met by any of the
 built-in classes.
 
 Simple examples

From python-checkins at python.org  Fri Dec 10 09:19:38 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 10 Dec 2010 09:19:38 +0100 (CET)
Subject: [Python-checkins] r87154 - in python/branches/py3k:
	Lib/test/support.py Misc/NEWS
Message-ID: <20101210081938.A669CEE996@mail.python.org>

Author: vinay.sajip
Date: Fri Dec 10 09:19:38 2010
New Revision: 87154

Log:
test.support: Added TestHandler and Matcher classes for better support of assertions about logging.

Modified:
   python/branches/py3k/Lib/test/support.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Fri Dec 10 09:19:38 2010
@@ -21,7 +21,7 @@
 import imp
 import time
 import sysconfig
-
+import logging.handlers
 
 try:
     import _thread
@@ -42,7 +42,8 @@
     "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
     "run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
     "reap_children", "cpython_only", "check_impl_detail", "get_attribute",
-    "swap_item", "swap_attr", "requires_IEEE_754"]
+    "swap_item", "swap_attr", "requires_IEEE_754",
+    "TestHandler", "Matr]
 
 
 class Error(Exception):
@@ -1343,3 +1344,68 @@
         if v > 0:
             args.append('-' + opt * v)
     return args
+
+#============================================================
+# Support for assertions about logging.
+#============================================================
+
+class TestHandler(logging.handlers.BufferingHandler):
+    def __init__(self, matcher):
+        # BufferingHandler takes a "capacity" argument
+        # so as to know when to flush. As we're overriding
+        # shouldFlush anyway, we can set a capacity of zero.
+        # You can call flush() manually to clear out the
+        # buffer.
+        logging.handlers.BufferingHandler.__init__(self, 0)
+        self.matcher = matcher
+
+    def shouldFlush(self):
+        return False
+
+    def emit(self, record):
+        self.format(record)
+        self.buffer.append(record.__dict__)
+
+    def matches(self, **kwargs):
+        """
+        Look for a saved dict whose keys/values match the supplied arguments.
+        """
+        result = False
+        for d in self.buffer:
+            if self.matcher.matches(d, **kwargs):
+                result = True
+                break
+        return result
+
+class Matcher(object):
+
+    _partial_matches = ('msg', 'message')
+
+    def matches(self, d, **kwargs):
+        """
+        Try to match a single dict with the supplied arguments.
+
+        Keys whose values are strings and which are in self._partial_matches
+        will be checked for partial (i.e. substring) matches. You can extend
+        this scheme to (for example) do regular expression matching, etc.
+        """
+        result = True
+        for k in kwargs:
+            v = kwargs[k]
+            dv = d.get(k)
+            if not self.match_value(k, dv, v):
+                result = False
+                break
+        return result
+
+    def match_value(self, k, dv, v):
+        """
+        Try to match a single stored value (dv) with a supplied value (v).
+        """
+        if type(v) != type(dv):
+            result = False
+        elif type(dv) is not str or k not in self._partial_matches:
+            result = (v == dv)
+        else:
+            result = dv.find(v) >= 0
+        return result

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Dec 10 09:19:38 2010
@@ -63,6 +63,9 @@
 Library
 -------
 
+- test.support: Added TestHandler and Matcher classes for better support of
+  assertions about logging.
+
 - Issue #4391: Use proper plural forms in argparse.
 
 - Issue #10601: sys.displayhook uses 'backslashreplace' error handler on

From python-checkins at python.org  Fri Dec 10 10:11:24 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 10 Dec 2010 10:11:24 +0100 (CET)
Subject: [Python-checkins] r87155 - python/branches/py3k/Lib/test/support.py
Message-ID: <20101210091124.1C7B1EE987@mail.python.org>

Author: vinay.sajip
Date: Fri Dec 10 10:11:23 2010
New Revision: 87155

Log:
Fied typo

Modified:
   python/branches/py3k/Lib/test/support.py

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Fri Dec 10 10:11:23 2010
@@ -43,7 +43,7 @@
     "run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
     "reap_children", "cpython_only", "check_impl_detail", "get_attribute",
     "swap_item", "swap_attr", "requires_IEEE_754",
-    "TestHandler", "Matr]
+    "TestHandler", "Matcher"]
 
 
 class Error(Exception):

From python-checkins at python.org  Fri Dec 10 11:01:44 2010
From: python-checkins at python.org (georg.brandl)
Date: Fri, 10 Dec 2010 11:01:44 +0100 (CET)
Subject: [Python-checkins] r87156 -
	python/branches/py3k/Lib/test/test_array.py
Message-ID: <20101210100144.8D639EE996@mail.python.org>

Author: georg.brandl
Date: Fri Dec 10 11:01:44 2010
New Revision: 87156

Log:
#10668: fix wrong call of __init__.

Modified:
   python/branches/py3k/Lib/test/test_array.py

Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py	(original)
+++ python/branches/py3k/Lib/test/test_array.py	Fri Dec 10 11:01:44 2010
@@ -22,7 +22,7 @@
 
 class ArraySubclassWithKwargs(array.array):
     def __init__(self, typecode, newarg=None):
-        array.array.__init__(typecode)
+        array.array.__init__(self, typecode)
 
 tests = [] # list to accumulate all tests
 typecodes = "ubBhHiIlLfd"

From python-checkins at python.org  Fri Dec 10 12:42:57 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 10 Dec 2010 12:42:57 +0100 (CET)
Subject: [Python-checkins] r87157 - in python/branches/py3k:
	Lib/logging/__init__.py Lib/test/test_logging.py Misc/NEWS
Message-ID: <20101210114257.EB346ED47@mail.python.org>

Author: vinay.sajip
Date: Fri Dec 10 12:42:57 2010
New Revision: 87157

Log:
logging: added handler of last resort.

Modified:
   python/branches/py3k/Lib/logging/__init__.py
   python/branches/py3k/Lib/test/test_logging.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py	(original)
+++ python/branches/py3k/Lib/logging/__init__.py	Fri Dec 10 12:42:57 2010
@@ -33,7 +33,7 @@
            'captureWarnings', 'critical', 'debug', 'disable', 'error',
            'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
            'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning',
-           'getLogRecordFactory', 'setLogRecordFactory']
+           'getLogRecordFactory', 'setLogRecordFactory', 'lastResort']
 
 try:
     import codecs
@@ -997,6 +997,26 @@
             self.stream = self._open()
         StreamHandler.emit(self, record)
 
+class _StderrHandler(StreamHandler):
+    """
+    This class is like a StreamHandler using sys.stderr, but always uses
+    whatever sys.stderr is currently set to rather than the value of
+    sys.stderr at handler construction time.
+    """
+    def __init__(self, level=NOTSET):
+        """
+        Initialize the handler.
+        """
+        Handler.__init__(self, level)
+
+    @property
+    def stream(self):
+        return sys.stderr
+
+
+_defaultLastResort = _StderrHandler(WARNING)
+lastResort = _defaultLastResort
+
 #---------------------------------------------------------------------------
 #   Manager classes and functions
 #---------------------------------------------------------------------------
@@ -1056,7 +1076,7 @@
         """
         self.root = rootnode
         self.disable = 0
-        self.emittedNoHandlerWarning = 0
+        self.emittedNoHandlerWarning = False
         self.loggerDict = {}
         self.loggerClass = None
         self.logRecordFactory = None
@@ -1415,10 +1435,13 @@
                 c = None    #break out
             else:
                 c = c.parent
-        if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
-            sys.stderr.write("No handlers could be found for logger"
-                             " \"%s\"\n" % self.name)
-            self.manager.emittedNoHandlerWarning = 1
+        if (found == 0):
+            if lastResort:
+                lastResort.handle(record)
+            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
+                sys.stderr.write("No handlers could be found for logger"
+                                 " \"%s\"\n" % self.name)
+                self.manager.emittedNoHandlerWarning = True
 
     def getEffectiveLevel(self):
         """
@@ -1676,7 +1699,9 @@
 
 def critical(msg, *args, **kwargs):
     """
-    Log a message with severity 'CRITICAL' on the root logger.
+    Log a message with severity 'CRITICAL' on the root logger. If the logger
+    has no handlers, call basicConfig() to add a console handler with a
+    pre-defined format.
     """
     if len(root.handlers) == 0:
         basicConfig()
@@ -1686,7 +1711,9 @@
 
 def error(msg, *args, **kwargs):
     """
-    Log a message with severity 'ERROR' on the root logger.
+    Log a message with severity 'ERROR' on the root logger. If the logger has
+    no handlers, call basicConfig() to add a console handler with a pre-defined
+    format.
     """
     if len(root.handlers) == 0:
         basicConfig()
@@ -1694,15 +1721,18 @@
 
 def exception(msg, *args, **kwargs):
     """
-    Log a message with severity 'ERROR' on the root logger,
-    with exception information.
+    Log a message with severity 'ERROR' on the root logger, with exception
+    information. If the logger has no handlers, basicConfig() is called to add
+    a console handler with a pre-defined format.
     """
     kwargs['exc_info'] = True
     error(msg, *args, **kwargs)
 
 def warning(msg, *args, **kwargs):
     """
-    Log a message with severity 'WARNING' on the root logger.
+    Log a message with severity 'WARNING' on the root logger. If the logger has
+    no handlers, call basicConfig() to add a console handler with a pre-defined
+    format.
     """
     if len(root.handlers) == 0:
         basicConfig()
@@ -1712,7 +1742,9 @@
 
 def info(msg, *args, **kwargs):
     """
-    Log a message with severity 'INFO' on the root logger.
+    Log a message with severity 'INFO' on the root logger. If the logger has
+    no handlers, call basicConfig() to add a console handler with a pre-defined
+    format.
     """
     if len(root.handlers) == 0:
         basicConfig()
@@ -1720,7 +1752,9 @@
 
 def debug(msg, *args, **kwargs):
     """
-    Log a message with severity 'DEBUG' on the root logger.
+    Log a message with severity 'DEBUG' on the root logger. If the logger has
+    no handlers, call basicConfig() to add a console handler with a pre-defined
+    format.
     """
     if len(root.handlers) == 0:
         basicConfig()
@@ -1728,7 +1762,9 @@
 
 def log(level, msg, *args, **kwargs):
     """
-    Log 'msg % args' with the integer severity 'level' on the root logger.
+    Log 'msg % args' with the integer severity 'level' on the root logger. If
+    the logger has no handlers, call basicConfig() to add a console handler
+    with a pre-defined format.
     """
     if len(root.handlers) == 0:
         basicConfig()

Modified: python/branches/py3k/Lib/test/test_logging.py
==============================================================================
--- python/branches/py3k/Lib/test/test_logging.py	(original)
+++ python/branches/py3k/Lib/test/test_logging.py	Fri Dec 10 12:42:57 2010
@@ -1927,6 +1927,40 @@
         f = logging.Formatter('asctime', style='$')
         self.assertFalse(f.usesTime())
 
+class LastResortTest(BaseTest):
+    def test_last_resort(self):
+        "Test the last resort handler"
+        root = self.root_logger
+        root.removeHandler(self.root_hdlr)
+        old_stderr = sys.stderr
+        old_lastresort = logging.lastResort
+        old_raise_exceptions = logging.raiseExceptions
+        try:
+            sys.stderr = sio = io.StringIO()
+            root.warning('This is your final chance!')
+            self.assertEqual(sio.getvalue(), 'This is your final chance!\n')
+            #No handlers and no last resort, so 'No handlers' message
+            logging.lastResort = None
+            sys.stderr = sio = io.StringIO()
+            root.warning('This is your final chance!')
+            self.assertEqual(sio.getvalue(), 'No handlers could be found for logger "root"\n')
+            # 'No handlers' message only printed once
+            sys.stderr = sio = io.StringIO()
+            root.warning('This is your final chance!')
+            self.assertEqual(sio.getvalue(), '')
+            root.manager.emittedNoHandlerWarning = False
+            #If raiseExceptions is False, no message is printed
+            logging.raiseExceptions = False
+            sys.stderr = sio = io.StringIO()
+            root.warning('This is your final chance!')
+            self.assertEqual(sio.getvalue(), '')
+        finally:
+            sys.stderr = old_stderr
+            root.addHandler(self.root_hdlr)
+            logging.lastResort = old_lastresort
+            logging.raiseExceptions = old_raise_exceptions
+
+
 class BaseFileTest(BaseTest):
     "Base class for handler tests that write log files"
 
@@ -2017,6 +2051,7 @@
                  FormatterTest,
                  LogRecordFactoryTest, ChildLoggerTest, QueueHandlerTest,
                  RotatingFileHandlerTest,
+                 LastResortTest,
                  #TimedRotatingFileHandlerTest
                 )
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Dec 10 12:42:57 2010
@@ -63,6 +63,8 @@
 Library
 -------
 
+- logging: added "handler of last resort". See http://bit.ly/last-resort-handler
+
 - test.support: Added TestHandler and Matcher classes for better support of
   assertions about logging.
 

From ncoghlan at gmail.com  Fri Dec 10 13:22:10 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Fri, 10 Dec 2010 22:22:10 +1000
Subject: [Python-checkins] r87157 - in python/branches/py3k:
 Lib/logging/__init__.py Lib/test/test_logging.py Misc/NEWS
In-Reply-To: <20101210114257.EB346ED47@mail.python.org>
References: <20101210114257.EB346ED47@mail.python.org>
Message-ID: 

On Fri, Dec 10, 2010 at 9:42 PM, vinay.sajip  wrote:
> Author: vinay.sajip
> Date: Fri Dec 10 12:42:57 2010
> New Revision: 87157
>
> Log:
> logging: added handler of last resort.

Nice, that ended up fitting in quite neatly.

Cheers,
Nick.

-- 
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From nnorwitz at gmail.com  Fri Dec 10 13:34:24 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Fri, 10 Dec 2010 07:34:24 -0500
Subject: [Python-checkins] Python Regression Test Failures doc (1)
Message-ID: <20101210123424.GA11080@kbk-i386-bb.dyndns.org>

rm -rf build/*
rm -rf tools/sphinx
rm -rf tools/pygments
rm -rf tools/jinja2
rm -rf tools/docutils
Checking out Sphinx...
svn: PROPFIND request failed on '/projects/external/Sphinx-0.6.5/sphinx'
svn: PROPFIND of '/projects/external/Sphinx-0.6.5/sphinx': could not connect to server (http://svn.python.org)
make: *** [checkout] Error 1

From nnorwitz at gmail.com  Fri Dec 10 10:21:45 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Fri, 10 Dec 2010 04:21:45 -0500
Subject: [Python-checkins] Python Regression Test Failures basics (1)
Message-ID: <20101210092145.GA31890@kbk-i386-bb.dyndns.org>

341 tests OK.
1 test failed:
    test_urllib2
42 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_bsddb3
    test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue
    test_linuxaudiodev test_macos test_macostools test_multiprocessing
    test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages
    test_smtpnet test_socketserver test_startfile test_sunaudiodev
    test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly
    test_unicode_file test_urllib2net test_urllibnet test_winreg
    test_winsound test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly

== CPython 2.7 (trunk:87154M, Dec 10 2010, 04:02:07) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)]
==   Linux-2.6.9-gentoo-r1-i686-AMD_Athlon-tm-_XP_3000+-with-gentoo-1.4.16 little-endian
==   /tmp/test_python_27768
test_grammar
test_opcodes
test_dict
test_builtin
test_exceptions
test_types
test_unittest
test_doctest
test_doctest2
test_MimeWriter
test_SimpleHTTPServer
test_StringIO
test___all__
test___future__
test__locale
test_abc
test_abstract_numbers
test_aepack
test_aepack skipped -- No module named aetypes
test_aifc
test_al
test_al skipped -- No module named al
test_anydbm
test_applesingle
test_applesingle skipped -- No module named MacOS
test_argparse
test_array
test_ascii_formatd
test_ast
test_asynchat
test_asyncore
test_atexit
test_audioop
test_augassign
test_base64
test_bastion
test_bigaddrspace
test_bigmem
test_binascii
test_binhex
test_binop
test_bisect
test_bool
test_bsddb
test_bsddb185
test_bsddb185 skipped -- No module named bsddb185
test_bsddb3
test_bsddb3 skipped -- Use of the `bsddb' resource not enabled
test_buffer
test_bufio
test_bytes
test_bz2
test_calendar
test_call
test_capi
test_cd
test_cd skipped -- No module named cd
test_cfgparser
test_cgi
test_charmapcodec
test_cl
test_cl skipped -- No module named cl
test_class
test_cmath
test_cmd
test_cmd_line
test_cmd_line_script
test_code
test_codeccallbacks
test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecmaps_cn
	fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ...
test_codecmaps_cn skipped -- Could not retrieve http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml
test_codecmaps_hk
	fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ...
test_codecmaps_hk skipped -- Could not retrieve http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT
test_codecmaps_jp
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ...
test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT
test_codecmaps_kr
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ...
test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT
test_codecmaps_tw
	fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ...
test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT
test_codecs
test_codeop
test_coding
test_coercion
test_collections
test_colorsys
test_commands
test_compare
test_compile
test_compileall
test_compiler
test_complex
test_complex_args
test_contains
test_contextlib
test_cookie
test_cookielib
test_copy
test_copy_reg
test_cpickle
test_cprofile
test_crypt
test_csv
test_ctypes
test_curses
test_curses skipped -- Use of the `curses' resource not enabled
test_datetime
test_dbm
test_decimal
test_decorators
test_defaultdict
test_deque
test_descr
test_descrtut
test_dictcomps
test_dictviews
test_difflib
test_dircache
test_dis
test_distutils
[19643 refs]
test_dl
test_docxmlrpc
test_dumbdbm
test_dummy_thread
test_dummy_threading
test_email
test_email_codecs
test_email_renamed
test_enumerate
test_eof
test_epoll
test_epoll skipped -- kernel doesn't support epoll()
test_errno
test_exception_variations
test_extcall
test_fcntl
test_file
test_file2k
test_filecmp
test_fileinput
test_fileio
test_float
test_fnmatch
test_fork1
test_format
test_fpformat
test_fractions
test_frozen
test_ftplib
test_funcattrs
test_functools
test_future
test_future3
test_future4
test_future5
test_future_builtins
test_gc
test_gdb
test_gdb skipped -- gdb versions before 7.0 didn't support python embedding Saw:
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-pc-linux-gnu".

test_gdbm
test_generators
test_genericpath
test_genexps
test_getargs
test_getargs2
test_getopt
test_gettext
test_gl
test_gl skipped -- No module named gl
test_glob
test_global
test_grp
test_gzip
test_hash
test_hashlib
test_heapq
test_hmac
test_hotshot
test_htmllib
test_htmlparser
test_httplib
test_httpservers
[15648 refs]
[15648 refs]
[15648 refs]
[25315 refs]
test_imageop
test_imaplib
test_imgfile
test_imgfile skipped -- No module named imgfile
test_imp
test_import
test_importhooks
test_importlib
test_index
test_inspect
test_int
test_int_literal
test_io
test_ioctl
test_ioctl skipped -- Unable to open /dev/tty
test_isinstance
test_iter
test_iterlen
test_itertools
test_json
test_kqueue
test_kqueue skipped -- test works only on BSD
test_largefile
test_lib2to3
test_linecache
test_linuxaudiodev
test_linuxaudiodev skipped -- Use of the `audio' resource not enabled
test_list
test_locale
test_logging
test_long
test_long_future
test_longexp
test_macos
test_macos skipped -- No module named MacOS
test_macostools
test_macostools skipped -- No module named MacOS
test_macpath
test_mailbox
test_marshal
test_math
test_md5
test_memoryio
test_memoryview
test_mhlib
test_mimetools
test_mimetypes
test_minidom
test_mmap
test_module
test_modulefinder
test_multibytecodec
test_multibytecodec_support
test_multifile
test_multiprocessing
test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
test_mutants
test_mutex
test_netrc
test_new
test_nis
test_normalization
	fetching http://www.unicode.org/Public/5.2.0/ucd/NormalizationTest.txt ...
test_ntpath
test_old_mailbox
test_openpty
test_operator
test_optparse
test_os
[15648 refs]
[15648 refs]
test_ossaudiodev
test_ossaudiodev skipped -- Use of the `audio' resource not enabled
test_parser
Expecting 's_push: parser stack overflow' in next line
s_push: parser stack overflow
test_pdb
test_peepholer
test_pep247
test_pep263
test_pep277
test_pep277 skipped -- only NT+ and systems with Unicode-friendly filesystem encoding
test_pep292
test_pep352
test_pickle
test_pickletools
test_pipes
test_pkg
test_pkgimport
test_pkgutil
test_platform
[17044 refs]
[17044 refs]
test_plistlib
test_poll
test_popen
[15653 refs]
[15653 refs]
[15653 refs]
test_popen2
test_poplib
test_posix
test_posixpath
test_pow
test_pprint
test_print
test_profile
test_profilehooks
test_property
test_pstats
test_pty
test_pwd
test_py3kwarn
test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag
test_pyclbr
test_pydoc
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20861 refs]
[20861 refs]
test_pyexpat
test_queue
test_quopri
[18479 refs]
[18479 refs]
test_random
test_re
test_readline
test_repr
test_resource
test_rfc822
test_richcmp
test_robotparser
test_runpy
test_sax
test_scope
test_scriptpackages
test_scriptpackages skipped -- No module named aetools
test_select
test_set
test_setcomps
test_sets
test_sgmllib
test_sha
test_shelve
test_shlex
test_shutil
test_signal
test_site
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
test_slice
test_smtplib
test_smtpnet
test_smtpnet skipped -- Use of the `network' resource not enabled
test_socket
test_socketserver
test_socketserver skipped -- Use of the `network' resource not enabled
test_softspace
test_sort
test_sqlite
test_ssl
test_startfile
test_startfile skipped -- module os has no attribute startfile
test_str
test_strftime
test_string
test_stringprep
test_strop
test_strptime
test_strtod
test_struct
test_structmembers
test_structseq
test_subprocess
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
test_sunaudiodev
test_sunaudiodev skipped -- No module named sunaudiodev
test_sundry
test_symtable
test_syntax
test_sys
[15648 refs]
[15648 refs]
[15648 refs]
[15877 refs]
[15671 refs]
test_sysconfig
[15648 refs]
[15648 refs]
test_tarfile
test_tcl
test_tcl skipped -- No module named _tkinter
test_telnetlib
test_tempfile
[15648 refs]
test_textwrap
test_thread
test_threaded_import
test_threadedtempfile
test_threading
[18948 refs]
[20223 refs]
[20035 refs]
[20035 refs]
[20035 refs]
[20035 refs]
test_threading_local
test_threadsignals
test_time
test_timeout
test_timeout skipped -- Use of the `network' resource not enabled
test_tk
test_tk skipped -- No module named _tkinter
test_tokenize
test_trace
test_traceback
test_transformer
test_ttk_guionly
test_ttk_guionly skipped -- No module named _tkinter
test_ttk_textonly
test_ttk_textonly skipped -- No module named _tkinter
test_tuple
test_typechecks
test_ucn
test_unary
test_undocumented_details
test_unicode
test_unicode_file
test_unicode_file skipped -- No Unicode filesystem semantics on this platform.
test_unicodedata
test_univnewlines
test_univnewlines2k
test_unpack
test_urllib
test_urllib2
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

Re-running test 'test_urllib2' in verbose mode
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/", "joe", "password")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/ni", "ni", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/foo", "foo", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/bar", "bar", "nini")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "first", "blah")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "second", "spam")
Expecting nothing
ok
Trying:
    add("a", "http://example.com", "1", "a")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://c.example.com:3128", "3", "c")
Expecting nothing
ok
Trying:
    add("Some Realm", "d.example.com", "4", "d")
Expecting nothing
ok
Trying:
    add("Some Realm", "e.example.com:3128", "5", "e")
Expecting nothing
ok
Trying:
    mgr.find_user_password("Some Realm", "example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/foo")
Expecting:
    ('foo', 'ni')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/bar")
Expecting:
    ('bar', 'nini')
ok
Trying:
    mgr.find_user_password("b", "http://example.com/")
Expecting:
    ('second', 'spam')
ok
Trying:
    mgr.find_user_password("a", "http://example.com/")
Expecting:
    ('1', 'a')
ok
Trying:
    mgr.find_user_password("a", "http://a.example.com/")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "d.example.com")
Expecting:
    ('4', 'd')
ok
Trying:
    mgr.find_user_password("Some Realm", "e.example.com:3128")
Expecting:
    ('5', 'e')
ok
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("f", "http://g.example.com:80", "10", "j")
Expecting nothing
ok
Trying:
    add("g", "http://h.example.com", "11", "k")
Expecting nothing
ok
Trying:
    add("h", "i.example.com:80", "12", "l")
Expecting nothing
ok
Trying:
    add("i", "j.example.com", "13", "m")
Expecting nothing
ok
Trying:
    mgr.find_user_password("f", "g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "g.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("g", "h.example.com")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "http://h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("h", "i.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("h", "i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("h", "http://i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("i", "j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    r = Request(url, headers={"Spam-eggs": "blah"})
Expecting nothing
ok
Trying:
    r.has_header("Spam-eggs")
Expecting:
    True
ok
Trying:
    r.header_items()
Expecting:
    [('Spam-eggs', 'blah')]
ok
Trying:
    r.add_header("Foo-Bar", "baz")
Expecting nothing
ok
Trying:
    items = r.header_items()
Expecting nothing
ok
Trying:
    items.sort()
Expecting nothing
ok
Trying:
    items
Expecting:
    [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
ok
Trying:
    r.has_header("Not-there")
Expecting:
    False
ok
Trying:
    print r.get_header("Not-there")
Expecting:
    None
ok
Trying:
    r.get_header("Not-there", "default")
Expecting:
    'default'
ok
93 items had no tests:
    test.test_urllib2
    test.test_urllib2.FakeMethod
    test.test_urllib2.FakeMethod.__call__
    test.test_urllib2.FakeMethod.__init__
    test.test_urllib2.HandlerTests
    test.test_urllib2.HandlerTests._test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_and_digest_auth_handlers
    test.test_urllib2.HandlerTests.test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_auth_with_single_quoted_realm
    test.test_urllib2.HandlerTests.test_cookie_redirect
    test.test_urllib2.HandlerTests.test_cookies
    test.test_urllib2.HandlerTests.test_errors
    test.test_urllib2.HandlerTests.test_file
    test.test_urllib2.HandlerTests.test_ftp
    test.test_urllib2.HandlerTests.test_http
    test.test_urllib2.HandlerTests.test_http_doubleslash
    test.test_urllib2.HandlerTests.test_proxy
    test.test_urllib2.HandlerTests.test_proxy_basic_auth
    test.test_urllib2.HandlerTests.test_proxy_https
    test.test_urllib2.HandlerTests.test_proxy_https_proxy_authorization
    test.test_urllib2.HandlerTests.test_proxy_no_proxy
    test.test_urllib2.HandlerTests.test_redirect
    test.test_urllib2.MiscTests
    test.test_urllib2.MiscTests.opener_has_handler
    test.test_urllib2.MiscTests.test_build_opener
    test.test_urllib2.MockCookieJar
    test.test_urllib2.MockCookieJar.add_cookie_header
    test.test_urllib2.MockCookieJar.extract_cookies
    test.test_urllib2.MockFile
    test.test_urllib2.MockFile.close
    test.test_urllib2.MockFile.read
    test.test_urllib2.MockFile.readline
    test.test_urllib2.MockHTTPClass
    test.test_urllib2.MockHTTPClass.__call__
    test.test_urllib2.MockHTTPClass.__init__
    test.test_urllib2.MockHTTPClass.getresponse
    test.test_urllib2.MockHTTPClass.request
    test.test_urllib2.MockHTTPClass.set_debuglevel
    test.test_urllib2.MockHTTPClass.set_tunnel
    test.test_urllib2.MockHTTPHandler
    test.test_urllib2.MockHTTPHandler.__init__
    test.test_urllib2.MockHTTPHandler.http_open
    test.test_urllib2.MockHTTPHandler.reset
    test.test_urllib2.MockHTTPResponse
    test.test_urllib2.MockHTTPResponse.__init__
    test.test_urllib2.MockHTTPResponse.read
    test.test_urllib2.MockHTTPSHandler
    test.test_urllib2.MockHTTPSHandler.__init__
    test.test_urllib2.MockHTTPSHandler.https_open
    test.test_urllib2.MockHandler
    test.test_urllib2.MockHandler.__init__
    test.test_urllib2.MockHandler.__lt__
    test.test_urllib2.MockHandler._define_methods
    test.test_urllib2.MockHandler.add_parent
    test.test_urllib2.MockHandler.close
    test.test_urllib2.MockHandler.handle
    test.test_urllib2.MockHeaders
    test.test_urllib2.MockHeaders.getheaders
    test.test_urllib2.MockOpener
    test.test_urllib2.MockOpener.error
    test.test_urllib2.MockOpener.open
    test.test_urllib2.MockPasswordManager
    test.test_urllib2.MockPasswordManager.add_password
    test.test_urllib2.MockPasswordManager.find_user_password
    test.test_urllib2.MockResponse
    test.test_urllib2.MockResponse.__init__
    test.test_urllib2.MockResponse.geturl
    test.test_urllib2.MockResponse.info
    test.test_urllib2.OpenerDirectorTests
    test.test_urllib2.OpenerDirectorTests.test_add_non_handler
    test.test_urllib2.OpenerDirectorTests.test_badly_named_methods
    test.test_urllib2.OpenerDirectorTests.test_handled
    test.test_urllib2.OpenerDirectorTests.test_handler_order
    test.test_urllib2.OpenerDirectorTests.test_http_error
    test.test_urllib2.OpenerDirectorTests.test_processors
    test.test_urllib2.OpenerDirectorTests.test_raise
    test.test_urllib2.RequestTests
    test.test_urllib2.RequestTests.setUp
    test.test_urllib2.RequestTests.test_add_data
    test.test_urllib2.RequestTests.test_get_full_url
    test.test_urllib2.RequestTests.test_get_host
    test.test_urllib2.RequestTests.test_get_host_unquote
    test.test_urllib2.RequestTests.test_get_type
    test.test_urllib2.RequestTests.test_method
    test.test_urllib2.RequestTests.test_proxy
    test.test_urllib2.RequestTests.test_selector
    test.test_urllib2.TrivialTests
    test.test_urllib2.TrivialTests.test_parse_http_list
    test.test_urllib2.TrivialTests.test_trivial
    test.test_urllib2.add_ordered_mock_handlers
    test.test_urllib2.build_test_opener
    test.test_urllib2.sanepathname2url
    test.test_urllib2.test_main
4 items passed all tests:
  27 tests in test.test_urllib2.test_password_manager
  22 tests in test.test_urllib2.test_password_manager_default_port
   3 tests in test.test_urllib2.test_request_headers_dict
  11 tests in test.test_urllib2.test_request_headers_methods
63 tests in 97 items.
63 passed and 0 failed.
Test passed.
doctest (test.test_urllib2) ... 63 tests with zero failures
Trying:
    _parse_proxy('file:/ftp.example.com/')
Expecting:
    Traceback (most recent call last):
    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
ok
Trying:
    _parse_proxy('proxy.example.com')
Expecting:
    (None, None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('proxy.example.com:3128')
Expecting:
    (None, None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com:3128')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://proxy.example.com/')
Expecting:
    ('http', None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://proxy.example.com:3128/')
Expecting:
    ('http', None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com/')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com:3128')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('ftp://joe:password at proxy.example.com/rubbish:3128')
Expecting:
    ('ftp', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
113 items had no tests:
    urllib2
    urllib2.AbstractBasicAuthHandler
    urllib2.AbstractBasicAuthHandler.__init__
    urllib2.AbstractBasicAuthHandler.http_error_auth_reqed
    urllib2.AbstractBasicAuthHandler.retry_http_basic_auth
    urllib2.AbstractDigestAuthHandler
    urllib2.AbstractDigestAuthHandler.__init__
    urllib2.AbstractDigestAuthHandler.get_algorithm_impls
    urllib2.AbstractDigestAuthHandler.get_authorization
    urllib2.AbstractDigestAuthHandler.get_cnonce
    urllib2.AbstractDigestAuthHandler.get_entity_digest
    urllib2.AbstractDigestAuthHandler.http_error_auth_reqed
    urllib2.AbstractDigestAuthHandler.reset_retry_count
    urllib2.AbstractDigestAuthHandler.retry_http_digest_auth
    urllib2.AbstractHTTPHandler
    urllib2.AbstractHTTPHandler.__init__
    urllib2.AbstractHTTPHandler.do_open
    urllib2.AbstractHTTPHandler.do_request_
    urllib2.AbstractHTTPHandler.set_http_debuglevel
    urllib2.BaseHandler
    urllib2.BaseHandler.__lt__
    urllib2.BaseHandler.add_parent
    urllib2.BaseHandler.close
    urllib2.CacheFTPHandler
    urllib2.CacheFTPHandler.__init__
    urllib2.CacheFTPHandler.check_cache
    urllib2.CacheFTPHandler.connect_ftp
    urllib2.CacheFTPHandler.setMaxConns
    urllib2.CacheFTPHandler.setTimeout
    urllib2.FTPHandler
    urllib2.FTPHandler.connect_ftp
    urllib2.FTPHandler.ftp_open
    urllib2.FileHandler
    urllib2.FileHandler.file_open
    urllib2.FileHandler.get_names
    urllib2.FileHandler.open_local_file
    urllib2.HTTPBasicAuthHandler
    urllib2.HTTPBasicAuthHandler.http_error_401
    urllib2.HTTPCookieProcessor
    urllib2.HTTPCookieProcessor.__init__
    urllib2.HTTPCookieProcessor.http_request
    urllib2.HTTPCookieProcessor.https_response
    urllib2.HTTPDefaultErrorHandler
    urllib2.HTTPDefaultErrorHandler.http_error_default
    urllib2.HTTPDigestAuthHandler
    urllib2.HTTPDigestAuthHandler.http_error_401
    urllib2.HTTPError
    urllib2.HTTPError.__init__
    urllib2.HTTPError.__str__
    urllib2.HTTPErrorProcessor
    urllib2.HTTPErrorProcessor.https_response
    urllib2.HTTPHandler
    urllib2.HTTPHandler.http_open
    urllib2.HTTPPasswordMgr
    urllib2.HTTPPasswordMgr.__init__
    urllib2.HTTPPasswordMgr.add_password
    urllib2.HTTPPasswordMgr.find_user_password
    urllib2.HTTPPasswordMgr.is_suburi
    urllib2.HTTPPasswordMgr.reduce_uri
    urllib2.HTTPPasswordMgrWithDefaultRealm
    urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password
    urllib2.HTTPRedirectHandler
    urllib2.HTTPRedirectHandler.http_error_307
    urllib2.HTTPRedirectHandler.redirect_request
    urllib2.HTTPSHandler
    urllib2.HTTPSHandler.https_open
    urllib2.OpenerDirector
    urllib2.OpenerDirector.__init__
    urllib2.OpenerDirector._call_chain
    urllib2.OpenerDirector._open
    urllib2.OpenerDirector.add_handler
    urllib2.OpenerDirector.close
    urllib2.OpenerDirector.error
    urllib2.OpenerDirector.open
    urllib2.ProxyBasicAuthHandler
    urllib2.ProxyBasicAuthHandler.http_error_407
    urllib2.ProxyDigestAuthHandler
    urllib2.ProxyDigestAuthHandler.http_error_407
    urllib2.ProxyHandler
    urllib2.ProxyHandler.__init__
    urllib2.ProxyHandler.proxy_open
    urllib2.Request
    urllib2.Request.__getattr__
    urllib2.Request.__init__
    urllib2.Request.add_data
    urllib2.Request.add_header
    urllib2.Request.add_unredirected_header
    urllib2.Request.get_data
    urllib2.Request.get_full_url
    urllib2.Request.get_header
    urllib2.Request.get_host
    urllib2.Request.get_method
    urllib2.Request.get_origin_req_host
    urllib2.Request.get_selector
    urllib2.Request.get_type
    urllib2.Request.has_data
    urllib2.Request.has_header
    urllib2.Request.has_proxy
    urllib2.Request.header_items
    urllib2.Request.is_unverifiable
    urllib2.Request.set_proxy
    urllib2.URLError
    urllib2.URLError.__init__
    urllib2.URLError.__str__
    urllib2.UnknownHandler
    urllib2.UnknownHandler.unknown_open
    urllib2.build_opener
    urllib2.install_opener
    urllib2.parse_http_list
    urllib2.parse_keqv_list
    urllib2.randombytes
    urllib2.request_host
    urllib2.urlopen
1 items passed all tests:
  11 tests in urllib2._parse_proxy
11 tests in 114 items.
11 passed and 0 failed.
Test passed.
doctest (urllib2) ... 11 tests with zero failures
test_parse_http_list (test.test_urllib2.TrivialTests) ... ok
test_trivial (test.test_urllib2.TrivialTests) ... ok
test_add_non_handler (test.test_urllib2.OpenerDirectorTests) ... ok
test_badly_named_methods (test.test_urllib2.OpenerDirectorTests) ... ok
test_handled (test.test_urllib2.OpenerDirectorTests) ... ok
test_handler_order (test.test_urllib2.OpenerDirectorTests) ... ok
test_http_error (test.test_urllib2.OpenerDirectorTests) ... ok
test_processors (test.test_urllib2.OpenerDirectorTests) ... ok
test_raise (test.test_urllib2.OpenerDirectorTests) ... ok
test_basic_and_digest_auth_handlers (test.test_urllib2.HandlerTests) ... ok
test_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_basic_auth_with_single_quoted_realm (test.test_urllib2.HandlerTests) ... ok
test_cookie_redirect (test.test_urllib2.HandlerTests) ... ok
test_cookies (test.test_urllib2.HandlerTests) ... ok
test_errors (test.test_urllib2.HandlerTests) ... ok
test_file (test.test_urllib2.HandlerTests) ... ERROR
test_ftp (test.test_urllib2.HandlerTests) ... ok
test_http (test.test_urllib2.HandlerTests) ... ok
test_http_doubleslash (test.test_urllib2.HandlerTests) ... ok
test_proxy (test.test_urllib2.HandlerTests) ... ok
test_proxy_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_proxy_https (test.test_urllib2.HandlerTests) ... ok
test_proxy_https_proxy_authorization (test.test_urllib2.HandlerTests) ... ok
test_proxy_no_proxy (test.test_urllib2.HandlerTests) ... ok
test_redirect (test.test_urllib2.HandlerTests) ... ok
test_build_opener (test.test_urllib2.MiscTests) ... ok
test_add_data (test.test_urllib2.RequestTests) ... ok
test_get_full_url (test.test_urllib2.RequestTests) ... ok
test_get_host (test.test_urllib2.RequestTests) ... ok
test_get_host_unquote (test.test_urllib2.RequestTests) ... ok
test_get_type (test.test_urllib2.RequestTests) ... ok
test_method (test.test_urllib2.RequestTests) ... ok
test_proxy (test.test_urllib2.RequestTests) ... ok
test_selector (test.test_urllib2.RequestTests) ... ok

======================================================================
ERROR: test_file (test.test_urllib2.HandlerTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

----------------------------------------------------------------------
Ran 34 tests in 19.671s

FAILED (errors=1)
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

test_urllib2_localnet
test_urllib2net
test_urllib2net skipped -- Use of the `network' resource not enabled
test_urllibnet
test_urllibnet skipped -- Use of the `network' resource not enabled
test_urlparse
test_userdict
test_userlist
test_userstring
test_uu
test_uuid
test_wait3
test_wait4
test_warnings
[15679 refs]
[15679 refs]
[15672 refs]
[15679 refs]
[15679 refs]
[15672 refs]
test_wave
test_weakref
test_weakset
test_whichdb
test_winreg
test_winreg skipped -- No module named _winreg
test_winsound
test_winsound skipped -- No module named winsound
test_with
test_wsgiref
test_xdrlib
test_xml_etree
test_xml_etree_c
test_xmllib
test_xmlrpc
test_xpickle
test_xpickle -- skipping backwards compat tests.
Use 'regrtest.py -u xpickle' to run them.
test_xrange
test_zipfile
test_zipfile64
test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run
test_zipimport
test_zipimport_support
test_zlib
341 tests OK.
1 test failed:
    test_urllib2
42 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_bsddb3
    test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue
    test_linuxaudiodev test_macos test_macostools test_multiprocessing
    test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages
    test_smtpnet test_socketserver test_startfile test_sunaudiodev
    test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly
    test_unicode_file test_urllib2net test_urllibnet test_winreg
    test_winsound test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly
[966901 refs]

From nnorwitz at gmail.com  Fri Dec 10 10:39:21 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Fri, 10 Dec 2010 04:39:21 -0500
Subject: [Python-checkins] Python Regression Test Failures opt (1)
Message-ID: <20101210093921.GA3553@kbk-i386-bb.dyndns.org>

341 tests OK.
1 test failed:
    test_urllib2
42 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_bsddb3
    test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue
    test_linuxaudiodev test_macos test_macostools test_multiprocessing
    test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages
    test_smtpnet test_socketserver test_startfile test_sunaudiodev
    test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly
    test_unicode_file test_urllib2net test_urllibnet test_winreg
    test_winsound test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly

== CPython 2.7 (trunk:87154M, Dec 10 2010, 04:02:07) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)]
==   Linux-2.6.9-gentoo-r1-i686-AMD_Athlon-tm-_XP_3000+-with-gentoo-1.4.16 little-endian
==   /tmp/test_python_31898
test_grammar
test_opcodes
test_dict
test_builtin
test_exceptions
test_types
test_unittest
test_doctest
test_doctest2
test_MimeWriter
test_SimpleHTTPServer
test_StringIO
test___all__
test___future__
test__locale
test_abc
test_abstract_numbers
test_aepack
test_aepack skipped -- No module named aetypes
test_aifc
test_al
test_al skipped -- No module named al
test_anydbm
test_applesingle
test_applesingle skipped -- No module named MacOS
test_argparse
test_array
test_ascii_formatd
test_ast
test_asynchat
test_asyncore
test_atexit
test_audioop
test_augassign
test_base64
test_bastion
test_bigaddrspace
test_bigmem
test_binascii
test_binhex
test_binop
test_bisect
test_bool
test_bsddb
test_bsddb185
test_bsddb185 skipped -- No module named bsddb185
test_bsddb3
test_bsddb3 skipped -- Use of the `bsddb' resource not enabled
test_buffer
test_bufio
test_bytes
test_bz2
test_calendar
test_call
test_capi
test_cd
test_cd skipped -- No module named cd
test_cfgparser
test_cgi
test_charmapcodec
test_cl
test_cl skipped -- No module named cl
test_class
test_cmath
test_cmd
test_cmd_line
test_cmd_line_script
test_code
test_codeccallbacks
test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecmaps_cn
	fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ...
test_codecmaps_cn skipped -- Could not retrieve http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml
test_codecmaps_hk
	fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ...
test_codecmaps_hk skipped -- Could not retrieve http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT
test_codecmaps_jp
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ...
test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT
test_codecmaps_kr
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ...
test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT
test_codecmaps_tw
	fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ...
test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT
test_codecs
test_codeop
test_coding
test_coercion
test_collections
test_colorsys
test_commands
test_compare
test_compile
test_compileall
test_compiler
test_complex
test_complex_args
test_contains
test_contextlib
test_cookie
test_cookielib
test_copy
test_copy_reg
test_cpickle
test_cprofile
test_crypt
test_csv
test_ctypes
test_curses
test_curses skipped -- Use of the `curses' resource not enabled
test_datetime
test_dbm
test_decimal
test_decorators
test_defaultdict
test_deque
test_descr
test_descrtut
test_dictcomps
test_dictviews
test_difflib
test_dircache
test_dis
test_distutils
[19646 refs]
[19646 refs]
[19646 refs]
[19646 refs]
[19643 refs]
test_dl
test_docxmlrpc
test_dumbdbm
test_dummy_thread
test_dummy_threading
test_email
test_email_codecs
test_email_renamed
test_enumerate
test_eof
test_epoll
test_epoll skipped -- kernel doesn't support epoll()
test_errno
test_exception_variations
test_extcall
test_fcntl
test_file
test_file2k
test_filecmp
test_fileinput
test_fileio
test_float
test_fnmatch
test_fork1
test_format
test_fpformat
test_fractions
test_frozen
test_ftplib
test_funcattrs
test_functools
test_future
test_future3
test_future4
test_future5
test_future_builtins
test_gc
test_gdb
test_gdb skipped -- gdb versions before 7.0 didn't support python embedding Saw:
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-pc-linux-gnu".

test_gdbm
test_generators
test_genericpath
test_genexps
test_getargs
test_getargs2
test_getopt
test_gettext
test_gl
test_gl skipped -- No module named gl
test_glob
test_global
test_grp
test_gzip
test_hash
test_hashlib
test_heapq
test_hmac
test_hotshot
test_htmllib
test_htmlparser
test_httplib
test_httpservers
[15648 refs]
[15648 refs]
[15648 refs]
[25315 refs]
test_imageop
test_imaplib
test_imgfile
test_imgfile skipped -- No module named imgfile
test_imp
test_import
test_importhooks
test_importlib
test_index
test_inspect
test_int
test_int_literal
test_io
test_ioctl
test_ioctl skipped -- Unable to open /dev/tty
test_isinstance
test_iter
test_iterlen
test_itertools
test_json
test_kqueue
test_kqueue skipped -- test works only on BSD
test_largefile
test_lib2to3
test_linecache
test_linuxaudiodev
test_linuxaudiodev skipped -- Use of the `audio' resource not enabled
test_list
test_locale
test_logging
test_long
test_long_future
test_longexp
test_macos
test_macos skipped -- No module named MacOS
test_macostools
test_macostools skipped -- No module named MacOS
test_macpath
test_mailbox
test_marshal
test_math
test_md5
test_memoryio
test_memoryview
test_mhlib
test_mimetools
test_mimetypes
test_minidom
test_mmap
test_module
test_modulefinder
test_multibytecodec
test_multibytecodec_support
test_multifile
test_multiprocessing
test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
test_mutants
test_mutex
test_netrc
test_new
test_nis
test_normalization
	fetching http://www.unicode.org/Public/5.2.0/ucd/NormalizationTest.txt ...
test_ntpath
test_old_mailbox
test_openpty
test_operator
test_optparse
test_os
[15648 refs]
[15648 refs]
test_ossaudiodev
test_ossaudiodev skipped -- Use of the `audio' resource not enabled
test_parser
Expecting 's_push: parser stack overflow' in next line
s_push: parser stack overflow
test_pdb
test_peepholer
test_pep247
test_pep263
test_pep277
test_pep277 skipped -- only NT+ and systems with Unicode-friendly filesystem encoding
test_pep292
test_pep352
test_pickle
test_pickletools
test_pipes
test_pkg
test_pkgimport
test_pkgutil
test_platform
[17044 refs]
[17044 refs]
test_plistlib
test_poll
test_popen
[15653 refs]
[15653 refs]
[15653 refs]
test_popen2
test_poplib
test_posix
test_posixpath
test_pow
test_pprint
test_print
test_profile
test_profilehooks
test_property
test_pstats
test_pty
test_pwd
test_py3kwarn
test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag
test_pyclbr
test_pydoc
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20861 refs]
[20861 refs]
test_pyexpat
test_queue
test_quopri
[18479 refs]
[18479 refs]
test_random
test_re
test_readline
test_repr
test_resource
test_rfc822
test_richcmp
test_robotparser
test_runpy
test_sax
test_scope
test_scriptpackages
test_scriptpackages skipped -- No module named aetools
test_select
test_set
test_setcomps
test_sets
test_sgmllib
test_sha
test_shelve
test_shlex
test_shutil
test_signal
test_site
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
test_slice
test_smtplib
test_smtpnet
test_smtpnet skipped -- Use of the `network' resource not enabled
test_socket
test_socketserver
test_socketserver skipped -- Use of the `network' resource not enabled
test_softspace
test_sort
test_sqlite
test_ssl
test_startfile
test_startfile skipped -- module os has no attribute startfile
test_str
test_strftime
test_string
test_stringprep
test_strop
test_strptime
test_strtod
test_struct
test_structmembers
test_structseq
test_subprocess
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
test_sunaudiodev
test_sunaudiodev skipped -- No module named sunaudiodev
test_sundry
test_symtable
test_syntax
test_sys
[15648 refs]
[15648 refs]
[15648 refs]
[15877 refs]
[15671 refs]
test_sysconfig
[15648 refs]
[15648 refs]
test_tarfile
test_tcl
test_tcl skipped -- No module named _tkinter
test_telnetlib
test_tempfile
[15648 refs]
test_textwrap
test_thread
test_threaded_import
test_threadedtempfile
test_threading
[18948 refs]
[20223 refs]
[20035 refs]
[20035 refs]
[20035 refs]
[20035 refs]
test_threading_local
test_threadsignals
test_time
test_timeout
test_timeout skipped -- Use of the `network' resource not enabled
test_tk
test_tk skipped -- No module named _tkinter
test_tokenize
test_trace
test_traceback
test_transformer
test_ttk_guionly
test_ttk_guionly skipped -- No module named _tkinter
test_ttk_textonly
test_ttk_textonly skipped -- No module named _tkinter
test_tuple
test_typechecks
test_ucn
test_unary
test_undocumented_details
test_unicode
test_unicode_file
test_unicode_file skipped -- No Unicode filesystem semantics on this platform.
test_unicodedata
test_univnewlines
test_univnewlines2k
test_unpack
test_urllib
test_urllib2
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

Re-running test 'test_urllib2' in verbose mode
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/", "joe", "password")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/ni", "ni", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/foo", "foo", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/bar", "bar", "nini")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "first", "blah")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "second", "spam")
Expecting nothing
ok
Trying:
    add("a", "http://example.com", "1", "a")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://c.example.com:3128", "3", "c")
Expecting nothing
ok
Trying:
    add("Some Realm", "d.example.com", "4", "d")
Expecting nothing
ok
Trying:
    add("Some Realm", "e.example.com:3128", "5", "e")
Expecting nothing
ok
Trying:
    mgr.find_user_password("Some Realm", "example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/foo")
Expecting:
    ('foo', 'ni')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/bar")
Expecting:
    ('bar', 'nini')
ok
Trying:
    mgr.find_user_password("b", "http://example.com/")
Expecting:
    ('second', 'spam')
ok
Trying:
    mgr.find_user_password("a", "http://example.com/")
Expecting:
    ('1', 'a')
ok
Trying:
    mgr.find_user_password("a", "http://a.example.com/")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "d.example.com")
Expecting:
    ('4', 'd')
ok
Trying:
    mgr.find_user_password("Some Realm", "e.example.com:3128")
Expecting:
    ('5', 'e')
ok
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("f", "http://g.example.com:80", "10", "j")
Expecting nothing
ok
Trying:
    add("g", "http://h.example.com", "11", "k")
Expecting nothing
ok
Trying:
    add("h", "i.example.com:80", "12", "l")
Expecting nothing
ok
Trying:
    add("i", "j.example.com", "13", "m")
Expecting nothing
ok
Trying:
    mgr.find_user_password("f", "g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "g.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("g", "h.example.com")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "http://h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("h", "i.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("h", "i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("h", "http://i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("i", "j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    r = Request(url, headers={"Spam-eggs": "blah"})
Expecting nothing
ok
Trying:
    r.has_header("Spam-eggs")
Expecting:
    True
ok
Trying:
    r.header_items()
Expecting:
    [('Spam-eggs', 'blah')]
ok
Trying:
    r.add_header("Foo-Bar", "baz")
Expecting nothing
ok
Trying:
    items = r.header_items()
Expecting nothing
ok
Trying:
    items.sort()
Expecting nothing
ok
Trying:
    items
Expecting:
    [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
ok
Trying:
    r.has_header("Not-there")
Expecting:
    False
ok
Trying:
    print r.get_header("Not-there")
Expecting:
    None
ok
Trying:
    r.get_header("Not-there", "default")
Expecting:
    'default'
ok
93 items had no tests:
    test.test_urllib2
    test.test_urllib2.FakeMethod
    test.test_urllib2.FakeMethod.__call__
    test.test_urllib2.FakeMethod.__init__
    test.test_urllib2.HandlerTests
    test.test_urllib2.HandlerTests._test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_and_digest_auth_handlers
    test.test_urllib2.HandlerTests.test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_auth_with_single_quoted_realm
    test.test_urllib2.HandlerTests.test_cookie_redirect
    test.test_urllib2.HandlerTests.test_cookies
    test.test_urllib2.HandlerTests.test_errors
    test.test_urllib2.HandlerTests.test_file
    test.test_urllib2.HandlerTests.test_ftp
    test.test_urllib2.HandlerTests.test_http
    test.test_urllib2.HandlerTests.test_http_doubleslash
    test.test_urllib2.HandlerTests.test_proxy
    test.test_urllib2.HandlerTests.test_proxy_basic_auth
    test.test_urllib2.HandlerTests.test_proxy_https
    test.test_urllib2.HandlerTests.test_proxy_https_proxy_authorization
    test.test_urllib2.HandlerTests.test_proxy_no_proxy
    test.test_urllib2.HandlerTests.test_redirect
    test.test_urllib2.MiscTests
    test.test_urllib2.MiscTests.opener_has_handler
    test.test_urllib2.MiscTests.test_build_opener
    test.test_urllib2.MockCookieJar
    test.test_urllib2.MockCookieJar.add_cookie_header
    test.test_urllib2.MockCookieJar.extract_cookies
    test.test_urllib2.MockFile
    test.test_urllib2.MockFile.close
    test.test_urllib2.MockFile.read
    test.test_urllib2.MockFile.readline
    test.test_urllib2.MockHTTPClass
    test.test_urllib2.MockHTTPClass.__call__
    test.test_urllib2.MockHTTPClass.__init__
    test.test_urllib2.MockHTTPClass.getresponse
    test.test_urllib2.MockHTTPClass.request
    test.test_urllib2.MockHTTPClass.set_debuglevel
    test.test_urllib2.MockHTTPClass.set_tunnel
    test.test_urllib2.MockHTTPHandler
    test.test_urllib2.MockHTTPHandler.__init__
    test.test_urllib2.MockHTTPHandler.http_open
    test.test_urllib2.MockHTTPHandler.reset
    test.test_urllib2.MockHTTPResponse
    test.test_urllib2.MockHTTPResponse.__init__
    test.test_urllib2.MockHTTPResponse.read
    test.test_urllib2.MockHTTPSHandler
    test.test_urllib2.MockHTTPSHandler.__init__
    test.test_urllib2.MockHTTPSHandler.https_open
    test.test_urllib2.MockHandler
    test.test_urllib2.MockHandler.__init__
    test.test_urllib2.MockHandler.__lt__
    test.test_urllib2.MockHandler._define_methods
    test.test_urllib2.MockHandler.add_parent
    test.test_urllib2.MockHandler.close
    test.test_urllib2.MockHandler.handle
    test.test_urllib2.MockHeaders
    test.test_urllib2.MockHeaders.getheaders
    test.test_urllib2.MockOpener
    test.test_urllib2.MockOpener.error
    test.test_urllib2.MockOpener.open
    test.test_urllib2.MockPasswordManager
    test.test_urllib2.MockPasswordManager.add_password
    test.test_urllib2.MockPasswordManager.find_user_password
    test.test_urllib2.MockResponse
    test.test_urllib2.MockResponse.__init__
    test.test_urllib2.MockResponse.geturl
    test.test_urllib2.MockResponse.info
    test.test_urllib2.OpenerDirectorTests
    test.test_urllib2.OpenerDirectorTests.test_add_non_handler
    test.test_urllib2.OpenerDirectorTests.test_badly_named_methods
    test.test_urllib2.OpenerDirectorTests.test_handled
    test.test_urllib2.OpenerDirectorTests.test_handler_order
    test.test_urllib2.OpenerDirectorTests.test_http_error
    test.test_urllib2.OpenerDirectorTests.test_processors
    test.test_urllib2.OpenerDirectorTests.test_raise
    test.test_urllib2.RequestTests
    test.test_urllib2.RequestTests.setUp
    test.test_urllib2.RequestTests.test_add_data
    test.test_urllib2.RequestTests.test_get_full_url
    test.test_urllib2.RequestTests.test_get_host
    test.test_urllib2.RequestTests.test_get_host_unquote
    test.test_urllib2.RequestTests.test_get_type
    test.test_urllib2.RequestTests.test_method
    test.test_urllib2.RequestTests.test_proxy
    test.test_urllib2.RequestTests.test_selector
    test.test_urllib2.TrivialTests
    test.test_urllib2.TrivialTests.test_parse_http_list
    test.test_urllib2.TrivialTests.test_trivial
    test.test_urllib2.add_ordered_mock_handlers
    test.test_urllib2.build_test_opener
    test.test_urllib2.sanepathname2url
    test.test_urllib2.test_main
4 items passed all tests:
  27 tests in test.test_urllib2.test_password_manager
  22 tests in test.test_urllib2.test_password_manager_default_port
   3 tests in test.test_urllib2.test_request_headers_dict
  11 tests in test.test_urllib2.test_request_headers_methods
63 tests in 97 items.
63 passed and 0 failed.
Test passed.
doctest (test.test_urllib2) ... 63 tests with zero failures
Trying:
    _parse_proxy('file:/ftp.example.com/')
Expecting:
    Traceback (most recent call last):
    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
ok
Trying:
    _parse_proxy('proxy.example.com')
Expecting:
    (None, None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('proxy.example.com:3128')
Expecting:
    (None, None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com:3128')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://proxy.example.com/')
Expecting:
    ('http', None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://proxy.example.com:3128/')
Expecting:
    ('http', None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com/')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com:3128')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('ftp://joe:password at proxy.example.com/rubbish:3128')
Expecting:
    ('ftp', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
113 items had no tests:
    urllib2
    urllib2.AbstractBasicAuthHandler
    urllib2.AbstractBasicAuthHandler.__init__
    urllib2.AbstractBasicAuthHandler.http_error_auth_reqed
    urllib2.AbstractBasicAuthHandler.retry_http_basic_auth
    urllib2.AbstractDigestAuthHandler
    urllib2.AbstractDigestAuthHandler.__init__
    urllib2.AbstractDigestAuthHandler.get_algorithm_impls
    urllib2.AbstractDigestAuthHandler.get_authorization
    urllib2.AbstractDigestAuthHandler.get_cnonce
    urllib2.AbstractDigestAuthHandler.get_entity_digest
    urllib2.AbstractDigestAuthHandler.http_error_auth_reqed
    urllib2.AbstractDigestAuthHandler.reset_retry_count
    urllib2.AbstractDigestAuthHandler.retry_http_digest_auth
    urllib2.AbstractHTTPHandler
    urllib2.AbstractHTTPHandler.__init__
    urllib2.AbstractHTTPHandler.do_open
    urllib2.AbstractHTTPHandler.do_request_
    urllib2.AbstractHTTPHandler.set_http_debuglevel
    urllib2.BaseHandler
    urllib2.BaseHandler.__lt__
    urllib2.BaseHandler.add_parent
    urllib2.BaseHandler.close
    urllib2.CacheFTPHandler
    urllib2.CacheFTPHandler.__init__
    urllib2.CacheFTPHandler.check_cache
    urllib2.CacheFTPHandler.connect_ftp
    urllib2.CacheFTPHandler.setMaxConns
    urllib2.CacheFTPHandler.setTimeout
    urllib2.FTPHandler
    urllib2.FTPHandler.connect_ftp
    urllib2.FTPHandler.ftp_open
    urllib2.FileHandler
    urllib2.FileHandler.file_open
    urllib2.FileHandler.get_names
    urllib2.FileHandler.open_local_file
    urllib2.HTTPBasicAuthHandler
    urllib2.HTTPBasicAuthHandler.http_error_401
    urllib2.HTTPCookieProcessor
    urllib2.HTTPCookieProcessor.__init__
    urllib2.HTTPCookieProcessor.http_request
    urllib2.HTTPCookieProcessor.https_response
    urllib2.HTTPDefaultErrorHandler
    urllib2.HTTPDefaultErrorHandler.http_error_default
    urllib2.HTTPDigestAuthHandler
    urllib2.HTTPDigestAuthHandler.http_error_401
    urllib2.HTTPError
    urllib2.HTTPError.__init__
    urllib2.HTTPError.__str__
    urllib2.HTTPErrorProcessor
    urllib2.HTTPErrorProcessor.https_response
    urllib2.HTTPHandler
    urllib2.HTTPHandler.http_open
    urllib2.HTTPPasswordMgr
    urllib2.HTTPPasswordMgr.__init__
    urllib2.HTTPPasswordMgr.add_password
    urllib2.HTTPPasswordMgr.find_user_password
    urllib2.HTTPPasswordMgr.is_suburi
    urllib2.HTTPPasswordMgr.reduce_uri
    urllib2.HTTPPasswordMgrWithDefaultRealm
    urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password
    urllib2.HTTPRedirectHandler
    urllib2.HTTPRedirectHandler.http_error_307
    urllib2.HTTPRedirectHandler.redirect_request
    urllib2.HTTPSHandler
    urllib2.HTTPSHandler.https_open
    urllib2.OpenerDirector
    urllib2.OpenerDirector.__init__
    urllib2.OpenerDirector._call_chain
    urllib2.OpenerDirector._open
    urllib2.OpenerDirector.add_handler
    urllib2.OpenerDirector.close
    urllib2.OpenerDirector.error
    urllib2.OpenerDirector.open
    urllib2.ProxyBasicAuthHandler
    urllib2.ProxyBasicAuthHandler.http_error_407
    urllib2.ProxyDigestAuthHandler
    urllib2.ProxyDigestAuthHandler.http_error_407
    urllib2.ProxyHandler
    urllib2.ProxyHandler.__init__
    urllib2.ProxyHandler.proxy_open
    urllib2.Request
    urllib2.Request.__getattr__
    urllib2.Request.__init__
    urllib2.Request.add_data
    urllib2.Request.add_header
    urllib2.Request.add_unredirected_header
    urllib2.Request.get_data
    urllib2.Request.get_full_url
    urllib2.Request.get_header
    urllib2.Request.get_host
    urllib2.Request.get_method
    urllib2.Request.get_origin_req_host
    urllib2.Request.get_selector
    urllib2.Request.get_type
    urllib2.Request.has_data
    urllib2.Request.has_header
    urllib2.Request.has_proxy
    urllib2.Request.header_items
    urllib2.Request.is_unverifiable
    urllib2.Request.set_proxy
    urllib2.URLError
    urllib2.URLError.__init__
    urllib2.URLError.__str__
    urllib2.UnknownHandler
    urllib2.UnknownHandler.unknown_open
    urllib2.build_opener
    urllib2.install_opener
    urllib2.parse_http_list
    urllib2.parse_keqv_list
    urllib2.randombytes
    urllib2.request_host
    urllib2.urlopen
1 items passed all tests:
  11 tests in urllib2._parse_proxy
11 tests in 114 items.
11 passed and 0 failed.
Test passed.
doctest (urllib2) ... 11 tests with zero failures
test_parse_http_list (test.test_urllib2.TrivialTests) ... ok
test_trivial (test.test_urllib2.TrivialTests) ... ok
test_add_non_handler (test.test_urllib2.OpenerDirectorTests) ... ok
test_badly_named_methods (test.test_urllib2.OpenerDirectorTests) ... ok
test_handled (test.test_urllib2.OpenerDirectorTests) ... ok
test_handler_order (test.test_urllib2.OpenerDirectorTests) ... ok
test_http_error (test.test_urllib2.OpenerDirectorTests) ... ok
test_processors (test.test_urllib2.OpenerDirectorTests) ... ok
test_raise (test.test_urllib2.OpenerDirectorTests) ... ok
test_basic_and_digest_auth_handlers (test.test_urllib2.HandlerTests) ... ok
test_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_basic_auth_with_single_quoted_realm (test.test_urllib2.HandlerTests) ... ok
test_cookie_redirect (test.test_urllib2.HandlerTests) ... ok
test_cookies (test.test_urllib2.HandlerTests) ... ok
test_errors (test.test_urllib2.HandlerTests) ... ok
test_file (test.test_urllib2.HandlerTests) ... ERROR
test_ftp (test.test_urllib2.HandlerTests) ... ok
test_http (test.test_urllib2.HandlerTests) ... ok
test_http_doubleslash (test.test_urllib2.HandlerTests) ... ok
test_proxy (test.test_urllib2.HandlerTests) ... ok
test_proxy_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_proxy_https (test.test_urllib2.HandlerTests) ... ok
test_proxy_https_proxy_authorization (test.test_urllib2.HandlerTests) ... ok
test_proxy_no_proxy (test.test_urllib2.HandlerTests) ... ok
test_redirect (test.test_urllib2.HandlerTests) ... ok
test_build_opener (test.test_urllib2.MiscTests) ... ok
test_add_data (test.test_urllib2.RequestTests) ... ok
test_get_full_url (test.test_urllib2.RequestTests) ... ok
test_get_host (test.test_urllib2.RequestTests) ... ok
test_get_host_unquote (test.test_urllib2.RequestTests) ... ok
test_get_type (test.test_urllib2.RequestTests) ... ok
test_method (test.test_urllib2.RequestTests) ... ok
test_proxy (test.test_urllib2.RequestTests) ... ok
test_selector (test.test_urllib2.RequestTests) ... ok

======================================================================
ERROR: test_file (test.test_urllib2.HandlerTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

----------------------------------------------------------------------
Ran 34 tests in 19.586s

FAILED (errors=1)
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

test_urllib2_localnet
test_urllib2net
test_urllib2net skipped -- Use of the `network' resource not enabled
test_urllibnet
test_urllibnet skipped -- Use of the `network' resource not enabled
test_urlparse
test_userdict
test_userlist
test_userstring
test_uu
test_uuid
test_wait3
test_wait4
test_warnings
[15679 refs]
[15679 refs]
[15672 refs]
[15679 refs]
[15679 refs]
[15672 refs]
test_wave
test_weakref
test_weakset
test_whichdb
test_winreg
test_winreg skipped -- No module named _winreg
test_winsound
test_winsound skipped -- No module named winsound
test_with
test_wsgiref
test_xdrlib
test_xml_etree
test_xml_etree_c
test_xmllib
test_xmlrpc
test_xpickle
test_xpickle -- skipping backwards compat tests.
Use 'regrtest.py -u xpickle' to run them.
test_xrange
test_zipfile
test_zipfile64
test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run
test_zipimport
test_zipimport_support
test_zlib
341 tests OK.
1 test failed:
    test_urllib2
42 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_bsddb3
    test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue
    test_linuxaudiodev test_macos test_macostools test_multiprocessing
    test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages
    test_smtpnet test_socketserver test_startfile test_sunaudiodev
    test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly
    test_unicode_file test_urllib2net test_urllibnet test_winreg
    test_winsound test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly
[965767 refs]

From nnorwitz at gmail.com  Fri Dec 10 13:33:38 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Fri, 10 Dec 2010 07:33:38 -0500
Subject: [Python-checkins] Python Regression Test Failures all (7)
Message-ID: <20101210123338.GA11058@kbk-i386-bb.dyndns.org>

341 tests OK.
7 tests failed:
    test_robotparser test_smtpnet test_ssl test_timeout test_urllib2
    test_urllib2net test_urllibnet
33 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_gl
    test_imgfile test_ioctl test_kqueue test_macos test_macostools
    test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages
    test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly
    test_ttk_textonly test_unicode_file test_winreg test_winsound
    test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly

== CPython 2.7 (trunk:87154M, Dec 10 2010, 04:02:07) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)]
==   Linux-2.6.9-gentoo-r1-i686-AMD_Athlon-tm-_XP_3000+-with-gentoo-1.4.16 little-endian
==   /tmp/test_python_3008
test_grammar
test_opcodes
test_dict
test_builtin
test_exceptions
test_types
test_unittest
test_doctest
test_doctest2
test_MimeWriter
test_SimpleHTTPServer
test_StringIO
test___all__
test___future__
test__locale
test_abc
test_abstract_numbers
test_aepack
test_aepack skipped -- No module named aetypes
test_aifc
test_al
test_al skipped -- No module named al
test_anydbm
test_applesingle
test_applesingle skipped -- No module named MacOS
test_argparse
test_array
test_ascii_formatd
test_ast
test_asynchat
test_asyncore
test_atexit
test_audioop
test_augassign
test_base64
test_bastion
test_bigaddrspace
test_bigmem
test_binascii
test_binhex
test_binop
test_bisect
test_bool
test_bsddb
test_bsddb185
test_bsddb185 skipped -- No module named bsddb185
test_bsddb3
Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002)
Test path prefix:  /tmp/z-test_bsddb3-3008
test_buffer
test_bufio
test_bytes
test_bz2
test_calendar
test_call
test_capi
test_cd
test_cd skipped -- No module named cd
test_cfgparser
test_cgi
test_charmapcodec
test_cl
test_cl skipped -- No module named cl
test_class
test_cmath
test_cmd
test_cmd_line
test_cmd_line_script
test_code
test_codeccallbacks
test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecmaps_cn
	fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ...
test_codecmaps_cn skipped -- Could not retrieve http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml
test_codecmaps_hk
	fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ...
test_codecmaps_hk skipped -- Could not retrieve http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT
test_codecmaps_jp
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ...
test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT
test_codecmaps_kr
	fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ...
test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT
test_codecmaps_tw
	fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ...
test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT
test_codecs
test_codeop
test_coding
test_coercion
test_collections
test_colorsys
test_commands
test_compare
test_compile
test_compileall
test_compiler
  testCompileLibrary still working, be patient...
test_complex
test_complex_args
test_contains
test_contextlib
test_cookie
test_cookielib
test_copy
test_copy_reg
test_cpickle
test_cprofile
test_crypt
test_csv
test_ctypes
test_datetime
test_dbm
test_decimal
test_decorators
test_defaultdict
test_deque
test_descr
test_descrtut
test_dictcomps
test_dictviews
test_difflib
test_dircache
test_dis
test_distutils
[19643 refs]
test_dl
test_docxmlrpc
test_dumbdbm
test_dummy_thread
test_dummy_threading
test_email
test_email_codecs
test_email_renamed
test_enumerate
test_eof
test_epoll
test_epoll skipped -- kernel doesn't support epoll()
test_errno
test_exception_variations
test_extcall
test_fcntl
test_file
test_file2k
test_filecmp
test_fileinput
test_fileio
test_float
test_fnmatch
test_fork1
test_format
test_fpformat
test_fractions
test_frozen
test_ftplib
test_funcattrs
test_functools
test_future
test_future3
test_future4
test_future5
test_future_builtins
test_gc
test_gdb
test_gdb skipped -- gdb versions before 7.0 didn't support python embedding Saw:
GNU gdb 6.2.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-pc-linux-gnu".

test_gdbm
test_generators
test_genericpath
test_genexps
test_getargs
test_getargs2
test_getopt
test_gettext
test_gl
test_gl skipped -- No module named gl
test_glob
test_global
test_grp
test_gzip
test_hash
test_hashlib
test_heapq
test_hmac
test_hotshot
test_htmllib
test_htmlparser
test_httplib
test_httpservers
[15648 refs]
[15648 refs]
[15648 refs]
[25315 refs]
test_imageop
test_imaplib
test_imgfile
test_imgfile skipped -- No module named imgfile
test_imp
test_import
test_importhooks
test_importlib
test_index
test_inspect
test_int
test_int_literal
test_io
test_ioctl
test_ioctl skipped -- Unable to open /dev/tty
test_isinstance
test_iter
test_iterlen
test_itertools
test_json
test_kqueue
test_kqueue skipped -- test works only on BSD
test_largefile
test_lib2to3
test_linecache
test_list
test_locale
test_logging
test_long
test_long_future
test_longexp
test_macos
test_macos skipped -- No module named MacOS
test_macostools
test_macostools skipped -- No module named MacOS
test_macpath
test_mailbox
test_marshal
test_math
test_md5
test_memoryio
test_memoryview
test_mhlib
test_mimetools
test_mimetypes
test_minidom
test_mmap
test_module
test_modulefinder
test_multibytecodec
test_multibytecodec_support
test_multifile
test_multiprocessing
test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
test_mutants
test_mutex
test_netrc
test_new
test_nis
test_normalization
	fetching http://www.unicode.org/Public/5.2.0/ucd/NormalizationTest.txt ...
test_ntpath
test_old_mailbox
test_openpty
test_operator
test_optparse
test_os
[15648 refs]
[15648 refs]
test_parser
Expecting 's_push: parser stack overflow' in next line
s_push: parser stack overflow
test_pdb
test_peepholer
test_pep247
test_pep263
test_pep277
test_pep277 skipped -- only NT+ and systems with Unicode-friendly filesystem encoding
test_pep292
test_pep352
test_pickle
test_pickletools
test_pipes
test_pkg
test_pkgimport
test_pkgutil
test_platform
[17044 refs]
[17044 refs]
test_plistlib
test_poll
test_popen
[15653 refs]
[15653 refs]
[15653 refs]
test_popen2
test_poplib
test_posix
test_posixpath
test_pow
test_pprint
test_print
test_profile
test_profilehooks
test_property
test_pstats
test_pty
test_pwd
test_py3kwarn
test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag
test_pyclbr
test_pydoc
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20862 refs]
[20861 refs]
[20861 refs]
test_pyexpat
test_queue
test_quopri
[18479 refs]
[18479 refs]
test_random
test_re
test_readline
test_repr
test_resource
test_rfc822
test_richcmp
test_robotparser
test test_robotparser failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_robotparser.py", line 224, in testPythonOrg
    parser.read()
  File "/tmp/python-test/local/lib/python2.7/robotparser.py", line 57, in read
    f = opener.open(self.url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 342, in open_http
    h.endheaders(data)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 940, in endheaders
    self._send_output(message_body)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 803, in _send_output
    self.send(msg)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 755, in send
    self.connect()
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 736, in connect
    self.timeout, self.source_address)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 567, in create_connection
    raise error, msg
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

Re-running test 'test_robotparser' in verbose mode
RobotTest(1, good, /) ... ok
RobotTest(1, good, /test.html) ... ok
RobotTest(1, bad, /cyberworld/map/index.html) ... ok
RobotTest(1, bad, /tmp/xxx) ... ok
RobotTest(1, bad, /foo.html) ... ok
RobotTest(2, good, /) ... ok
RobotTest(2, good, /test.html) ... ok
RobotTest(2, good, ('cybermapper', '/cyberworld/map/index.html')) ... ok
RobotTest(2, bad, /cyberworld/map/index.html) ... ok
RobotTest(3, bad, /cyberworld/map/index.html) ... ok
RobotTest(3, bad, /) ... ok
RobotTest(3, bad, /tmp/) ... ok
RobotTest(4, bad, /tmp) ... ok
RobotTest(4, bad, /tmp.html) ... ok
RobotTest(4, bad, /tmp/a.html) ... ok
RobotTest(4, bad, /a%3cd.html) ... ok
RobotTest(4, bad, /a%3Cd.html) ... ok
RobotTest(4, bad, /a%2fb.html) ... ok
RobotTest(4, bad, /~joe/index.html) ... ok
RobotTest(5, bad, /tmp) ... ok
RobotTest(5, bad, /tmp.html) ... ok
RobotTest(5, bad, /tmp/a.html) ... ok
RobotTest(5, bad, /a%3cd.html) ... ok
RobotTest(5, bad, /a%3Cd.html) ... ok
RobotTest(5, bad, /a%2fb.html) ... ok
RobotTest(5, bad, /~joe/index.html) ... ok
RobotTest(6, good, /tmp) ... ok
RobotTest(6, bad, /tmp/) ... ok
RobotTest(6, bad, /tmp/a.html) ... ok
RobotTest(6, bad, /a%3cd.html) ... ok
RobotTest(6, bad, /a%3Cd.html) ... ok
RobotTest(6, bad, /a/b.html) ... ok
RobotTest(6, bad, /%7Ejoe/index.html) ... ok
RobotTest(7, good, /foo.html) ... ok
RobotTest(8, good, /folder1/myfile.html) ... ok
RobotTest(8, bad, /folder1/anotherfile.html) ... ok
RobotTest(9, bad, /something.jpg) ... ok
RobotTest(10, bad, /something.jpg) ... ok
RobotTest(11, bad, /something.jpg) ... ok
RobotTest(12, good, /something.jpg) ... ok
RobotTest(13, good, /folder1/myfile.html) ... ok
RobotTest(13, bad, /folder1/anotherfile.html) ... ok

----------------------------------------------------------------------
Ran 42 tests in 0.012s

OK
testPasswordProtectedSite (test.test_robotparser.NetworkTestCase) ... skipped 'http://mueblesmoraleda.com is unavailable'
testPythonOrg (test.test_robotparser.NetworkTestCase) ... ERROR

======================================================================
ERROR: testPythonOrg (test.test_robotparser.NetworkTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_robotparser.py", line 224, in testPythonOrg
    parser.read()
  File "/tmp/python-test/local/lib/python2.7/robotparser.py", line 57, in read
    f = opener.open(self.url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 342, in open_http
    h.endheaders(data)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 940, in endheaders
    self._send_output(message_body)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 803, in _send_output
    self.send(msg)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 755, in send
    self.connect()
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 736, in connect
    self.timeout, self.source_address)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 567, in create_connection
    raise error, msg
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

----------------------------------------------------------------------
Ran 2 tests in 398.010s

FAILED (errors=1, skipped=1)
test test_robotparser failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_robotparser.py", line 224, in testPythonOrg
    parser.read()
  File "/tmp/python-test/local/lib/python2.7/robotparser.py", line 57, in read
    f = opener.open(self.url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 342, in open_http
    h.endheaders(data)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 940, in endheaders
    self._send_output(message_body)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 803, in _send_output
    self.send(msg)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 755, in send
    self.connect()
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 736, in connect
    self.timeout, self.source_address)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 567, in create_connection
    raise error, msg
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

test_runpy
test_sax
test_scope
test_scriptpackages
test_scriptpackages skipped -- No module named aetools
test_select
test_set
test_setcomps
test_sets
test_sgmllib
test_sha
test_shelve
test_shlex
test_shutil
test_signal
test_site
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
test_slice
test_smtplib
test_smtpnet
test test_smtpnet failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_smtpnet.py", line 15, in test_connect
    server = smtplib.SMTP_SSL(self.testServer, self.remotePort)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 752, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 757, in _get_socket
    new_socket = socket.create_connection((host, port), timeout)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 551, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno -3] Temporary failure in name resolution

Re-running test 'test_smtpnet' in verbose mode
test_connect (test.test_smtpnet.SmtpSSLTest) ... ERROR

======================================================================
ERROR: test_connect (test.test_smtpnet.SmtpSSLTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_smtpnet.py", line 15, in test_connect
    server = smtplib.SMTP_SSL(self.testServer, self.remotePort)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 752, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 757, in _get_socket
    new_socket = socket.create_connection((host, port), timeout)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 551, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno -3] Temporary failure in name resolution

----------------------------------------------------------------------
Ran 1 test in 54.950s

FAILED (errors=1)
test test_smtpnet failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_smtpnet.py", line 15, in test_connect
    server = smtplib.SMTP_SSL(self.testServer, self.remotePort)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 752, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 239, in __init__
    (code, msg) = self.connect(host, port)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 295, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 757, in _get_socket
    new_socket = socket.create_connection((host, port), timeout)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 551, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno -3] Temporary failure in name resolution

test_socket
test_socketserver
test_softspace
test_sort
test_sqlite
test_ssl
test test_ssl failed -- multiple errors occurred; run in verbose mode for details
Re-running test 'test_ssl' in verbose mode
test_DER_to_PEM (test.test_ssl.BasicTests) ... ok
test_ciphers (test.test_ssl.BasicTests) ... ERROR
test_constants (test.test_ssl.BasicTests) ... ok
test_openssl_version (test.test_ssl.BasicTests) ... ok
test_parse_cert (test.test_ssl.BasicTests) ... 
{'notAfter': 'Feb 16 16:54:50 2013 GMT',
 'subject': ((('countryName', u'US'),),
             (('stateOrProvinceName', u'Delaware'),),
             (('localityName', u'Wilmington'),),
             (('organizationName', u'Python Software Foundation'),),
             (('organizationalUnitName', u'SSL'),),
             (('commonName', u'somemachine.python.org'),))}
ok
test_random (test.test_ssl.BasicTests) ... 
 RAND_status is 1 (sufficient randomness)
ok
test_refcycle (test.test_ssl.BasicTests) ... ok
test_sslwrap_simple (test.test_ssl.BasicTests) ... ok
test_algorithms (test.test_ssl.NetworkedTests) ... skipped "SHA256 not available on 'OpenSSL 0.9.7d 17 Mar 2004'"
test_connect (test.test_ssl.NetworkedTests) ... ERROR
test_get_server_certificate (test.test_ssl.NetworkedTests) ... ERROR
test_makefile_close (test.test_ssl.NetworkedTests) ... ERROR
test_non_blocking_handshake (test.test_ssl.NetworkedTests) ... ERROR
test_asyncore_server (test.test_ssl.ThreadedTests)
Check the example asyncore integration. ... 
 server:  new connection from 127.0.0.1:56008
 client:  sending 'TEST MESSAGE of mixed case\n'...
 client:  read 'test message of mixed case\n'
 client:  closing connection.
 server:  closed connection 
ok
test_echo (test.test_ssl.ThreadedTests)
Basic test of an SSL client connecting to a server ... 
 server:  new connection from ('127.0.0.1', 56010)
 client:  sending 'FOO\n'...
 server: connection cipher is now ('AES256-SHA', 'TLSv1/SSLv3', 256)
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  sending bytearray(b'FOO\n')...
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  sending ...
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  closing connection.
 server: client closed connection
ok
test_empty_cert (test.test_ssl.ThreadedTests)
Connecting with an empty cert file ... 
SSLError is _ssl.c:347: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
ok
test_getpeercert (test.test_ssl.ThreadedTests) ... 
{'notAfter': 'Feb 16 16:54:50 2013 GMT',
 'subject': ((('countryName', u'US'),),
             (('stateOrProvinceName', u'Delaware'),),
             (('localityName', u'Wilmington'),),
             (('organizationName', u'Python Software Foundation'),),
             (('organizationalUnitName', u'SSL'),),
             (('commonName', u'somemachine.python.org'),))}
Connection cipher is ('AES256-SHA', 'TLSv1/SSLv3', 256).
ok
test_handshake_timeout (test.test_ssl.ThreadedTests) ... ok
test_malformed_cert (test.test_ssl.ThreadedTests)
Connecting with a badly formatted certificate (syntax error) ... 
SSLError is _ssl.c:361: error:140DC009:SSL routines:SSL_CTX_use_certificate_chain_file:PEM lib
ok
test_malformed_key (test.test_ssl.ThreadedTests)
Connecting with a badly formatted key (syntax error) ... 
SSLError is _ssl.c:347: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
ok
test_nonexisting_cert (test.test_ssl.ThreadedTests)
Connecting with a non-existing cert file ... 
SSLError is _ssl.c:499: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
ok
test_protocol_sslv2 (test.test_ssl.ThreadedTests)
Connecting to an SSLv2 server with various client options ... 
 SSLv2->SSLv2 CERT_NONE
 SSLv2->SSLv2 CERT_OPTIONAL
 SSLv2->SSLv2 CERT_REQUIRED
 SSLv23->SSLv2 CERT_NONE
 {SSLv3->SSLv2} CERT_NONE
 {TLSv1->SSLv2} CERT_NONE
ok
test_protocol_sslv23 (test.test_ssl.ThreadedTests)
Connecting to an SSLv23 server with various client options ... 
 SSLv2->SSLv23 CERT_NONE
 SSLv3->SSLv23 CERT_NONE
 SSLv23->SSLv23 CERT_NONE
 TLSv1->SSLv23 CERT_NONE
 SSLv3->SSLv23 CERT_OPTIONAL
 SSLv23->SSLv23 CERT_OPTIONAL
 TLSv1->SSLv23 CERT_OPTIONAL
 SSLv3->SSLv23 CERT_REQUIRED
 SSLv23->SSLv23 CERT_REQUIRED
 TLSv1->SSLv23 CERT_REQUIRED
ok
test_protocol_sslv3 (test.test_ssl.ThreadedTests)
Connecting to an SSLv3 server with various client options ... 
 SSLv3->SSLv3 CERT_NONE
 SSLv3->SSLv3 CERT_OPTIONAL
 SSLv3->SSLv3 CERT_REQUIRED
 {SSLv2->SSLv3} CERT_NONE
 {SSLv23->SSLv3} CERT_NONE
 {TLSv1->SSLv3} CERT_NONE
ok
test_protocol_tlsv1 (test.test_ssl.ThreadedTests)
Connecting to a TLSv1 server with various client options ... 
 TLSv1->TLSv1 CERT_NONE
 TLSv1->TLSv1 CERT_OPTIONAL
 TLSv1->TLSv1 CERT_REQUIRED
 {SSLv2->TLSv1} CERT_NONE
 {SSLv3->TLSv1} CERT_NONE
 {SSLv23->TLSv1} CERT_NONE
ok
test_recv_send (test.test_ssl.ThreadedTests)
Test recv(), send() and friends. ... 
 server:  new connection from ('127.0.0.1', 56081)
 server: connection cipher is now ('AES256-SHA', 'TLSv1/SSLv3', 256)
ok
test_rude_shutdown (test.test_ssl.ThreadedTests)
A brutal shutdown of an SSL server should raise an IOError ... ok
test_socketserver (test.test_ssl.ThreadedTests)
Using a SocketServer to create and manage SSL connections. ... 
 server (('127.0.0.1', 56084):56084 ('AES256-SHA', 'TLSv1/SSLv3', 256)):
   [10/Dec/2010 07:18:39] "GET /keycert.pem HTTP/1.0" 200 -
 client: read 1872 bytes from remote server '>'
ok
test_starttls (test.test_ssl.ThreadedTests)
Switching from clear text to encrypted and back again. ... 
 client:  sending 'msg 1'...
 server:  new connection from ('127.0.0.1', 56087)
 server: read 'msg 1' (unencrypted), sending back 'msg 1' (unencrypted)...
 client:  read 'msg 1' from server
 client:  sending 'MSG 2'...
 server: read 'MSG 2' (unencrypted), sending back 'msg 2' (unencrypted)...
 client:  read 'msg 2' from server
 client:  sending 'STARTTLS'...
 server: read STARTTLS from client, sending OK...
 client:  read 'OK\n' from server, starting TLS...
 client:  sending 'MSG 3'...
 server: read 'MSG 3' (encrypted), sending back 'msg 3' (encrypted)...
 client:  read 'msg 3' from server
 client:  sending 'msg 4'...
 server: read 'msg 4' (encrypted), sending back 'msg 4' (encrypted)...
 client:  read 'msg 4' from server
 client:  sending 'ENDTLS'...
 server: read ENDTLS from client, sending OK...
 client:  read 'OK\n' from server, ending TLS...
 client:  sending 'msg 5'...
 server: connection is now unencrypted...
 server: read 'msg 5' (unencrypted), sending back 'msg 5' (unencrypted)...
 client:  read 'msg 5' from server
 client:  sending 'msg 6'...
 server: read 'msg 6' (unencrypted), sending back 'msg 6' (unencrypted)...
 client:  read 'msg 6' from server
 client:  closing connection.
 server: client closed connection
ok
test_wrapped_accept (test.test_ssl.ThreadedTests)
Check the accept() method on SSL sockets. ... 
 server:  wrapped server socket as 
 client:  sending 'FOO\n'...
 server:  new connection from ('127.0.0.1', 56089)
 client cert is {'notAfter': 'Feb 16 16:54:50 2013 GMT',
 'subject': ((('countryName', u'US'),),
             (('stateOrProvinceName', u'Delaware'),),
             (('localityName', u'Wilmington'),),
             (('organizationName', u'Python Software Foundation'),),
             (('organizationalUnitName', u'SSL'),),
             (('commonName', u'somemachine.python.org'),))}
 cert binary is 683 bytes
 server: connection cipher is now ('AES256-SHA', 'TLSv1/SSLv3', 256)
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  sending bytearray(b'FOO\n')...
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  sending ...
 server: read 'FOO\n' (encrypted), sending back 'foo\n' (encrypted)...
 client:  read 'foo\n'
 client:  closing connection.
 server: client closed connection
ok

======================================================================
ERROR: test_ciphers (test.test_ssl.BasicTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_ssl.py", line 133, in test_ciphers
    s.connect(remote)
  File "/tmp/python-test/local/lib/python2.7/ssl.py", line 292, in connect
    socket.connect(self, addr)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

======================================================================
ERROR: test_connect (test.test_ssl.NetworkedTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_ssl.py", line 160, in test_connect
    s.connect(("svn.python.org", 443))
  File "/tmp/python-test/local/lib/python2.7/ssl.py", line 292, in connect
    socket.connect(self, addr)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

======================================================================
ERROR: test_get_server_certificate (test.test_ssl.NetworkedTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_ssl.py", line 229, in test_get_server_certificate
    pem = ssl.get_server_certificate(("svn.python.org", 443))
  File "/tmp/python-test/local/lib/python2.7/ssl.py", line 403, in get_server_certificate
    s.connect(addr)
  File "/tmp/python-test/local/lib/python2.7/ssl.py", line 292, in connect
    socket.connect(self, addr)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

======================================================================
ERROR: test_makefile_close (test.test_ssl.NetworkedTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_ssl.py", line 191, in test_makefile_close
    ss.connect(("svn.python.org", 443))
  File "/tmp/python-test/local/lib/python2.7/ssl.py", line 292, in connect
    socket.connect(self, addr)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

======================================================================
ERROR: test_non_blocking_handshake (test.test_ssl.NetworkedTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_ssl.py", line 206, in test_non_blocking_handshake
    s.connect(("svn.python.org", 443))
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

----------------------------------------------------------------------
Ran 30 tests in 2.476s

FAILED (errors=5, skipped=1)
test test_ssl failed -- multiple errors occurred
test_startfile
test_startfile skipped -- module os has no attribute startfile
test_str
test_strftime
test_string
test_stringprep
test_strop
test_strptime
test_strtod
test_struct
test_structmembers
test_structseq
test_subprocess
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15863 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
[15648 refs]
.
[15648 refs]
[15648 refs]
    this bit of output is from a test of stdout in a different process ...
[15648 refs]
[15648 refs]
[15863 refs]
test_sunaudiodev
test_sunaudiodev skipped -- No module named sunaudiodev
test_sundry
test_symtable
test_syntax
test_sys
[15648 refs]
[15648 refs]
[15648 refs]
[15877 refs]
[15671 refs]
test_sysconfig
[15648 refs]
[15648 refs]
test_tarfile
test_tcl
test_tcl skipped -- No module named _tkinter
test_telnetlib
test_tempfile
[15648 refs]
test_textwrap
test_thread
test_threaded_import
test_threadedtempfile
test_threading
[18948 refs]
[20223 refs]
[20035 refs]
[20035 refs]
[20035 refs]
[20035 refs]
test_threading_local
test_threadsignals
test_time
test_timeout
test test_timeout failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_timeout.py", line 133, in testRecvTimeout
    self.sock.connect(self.addr_remote)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 110] Connection timed out

Re-running test 'test_timeout' in verbose mode
testBlockingThenTimeout (test.test_timeout.CreationTestCase) ... ok
testFloatReturnValue (test.test_timeout.CreationTestCase) ... ok
testObjectCreation (test.test_timeout.CreationTestCase) ... ok
testRangeCheck (test.test_timeout.CreationTestCase) ... ok
testReturnType (test.test_timeout.CreationTestCase) ... ok
testTimeoutThenBlocking (test.test_timeout.CreationTestCase) ... ok
testTypeCheck (test.test_timeout.CreationTestCase) ... ok
testAcceptTimeout (test.test_timeout.TimeoutTestCase) ... ok
testConnectTimeout (test.test_timeout.TimeoutTestCase) ... ok
testRecvTimeout (test.test_timeout.TimeoutTestCase) ... ERROR
testRecvfromTimeout (test.test_timeout.TimeoutTestCase) ... ok
testSend (test.test_timeout.TimeoutTestCase) ... ok
testSendall (test.test_timeout.TimeoutTestCase) ... ok
testSendto (test.test_timeout.TimeoutTestCase) ... ok

======================================================================
ERROR: testRecvTimeout (test.test_timeout.TimeoutTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_timeout.py", line 133, in testRecvTimeout
    self.sock.connect(self.addr_remote)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

----------------------------------------------------------------------
Ran 14 tests in 4.044s

FAILED (errors=1)
test test_timeout failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_timeout.py", line 133, in testRecvTimeout
    self.sock.connect(self.addr_remote)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 222, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 113] No route to host

test_tk
test_tk skipped -- No module named _tkinter
test_tokenize
test_trace
test_traceback
test_transformer
test_ttk_guionly
test_ttk_guionly skipped -- No module named _tkinter
test_ttk_textonly
test_ttk_textonly skipped -- No module named _tkinter
test_tuple
test_typechecks
test_ucn
test_unary
test_undocumented_details
test_unicode
test_unicode_file
test_unicode_file skipped -- No Unicode filesystem semantics on this platform.
test_unicodedata
test_univnewlines
test_univnewlines2k
test_unpack
test_urllib
test_urllib2
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

Re-running test 'test_urllib2' in verbose mode
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/", "joe", "password")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://example.com/ni", "ni", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/foo", "foo", "ni")
Expecting nothing
ok
Trying:
    add("c", "http://example.com/bar", "bar", "nini")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "first", "blah")
Expecting nothing
ok
Trying:
    add("b", "http://example.com/", "second", "spam")
Expecting nothing
ok
Trying:
    add("a", "http://example.com", "1", "a")
Expecting nothing
ok
Trying:
    add("Some Realm", "http://c.example.com:3128", "3", "c")
Expecting nothing
ok
Trying:
    add("Some Realm", "d.example.com", "4", "d")
Expecting nothing
ok
Trying:
    add("Some Realm", "e.example.com:3128", "5", "e")
Expecting nothing
ok
Trying:
    mgr.find_user_password("Some Realm", "example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://example.com/spam/spam")
Expecting:
    ('joe', 'password')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/foo")
Expecting:
    ('foo', 'ni')
ok
Trying:
    mgr.find_user_password("c", "http://example.com/bar")
Expecting:
    ('bar', 'nini')
ok
Trying:
    mgr.find_user_password("b", "http://example.com/")
Expecting:
    ('second', 'spam')
ok
Trying:
    mgr.find_user_password("a", "http://example.com/")
Expecting:
    ('1', 'a')
ok
Trying:
    mgr.find_user_password("a", "http://a.example.com/")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("Some Realm", "c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "http://c.example.com:3128")
Expecting:
    ('3', 'c')
ok
Trying:
    mgr.find_user_password("Some Realm", "d.example.com")
Expecting:
    ('4', 'd')
ok
Trying:
    mgr.find_user_password("Some Realm", "e.example.com:3128")
Expecting:
    ('5', 'e')
ok
Trying:
    mgr = urllib2.HTTPPasswordMgr()
Expecting nothing
ok
Trying:
    add = mgr.add_password
Expecting nothing
ok
Trying:
    add("f", "http://g.example.com:80", "10", "j")
Expecting nothing
ok
Trying:
    add("g", "http://h.example.com", "11", "k")
Expecting nothing
ok
Trying:
    add("h", "i.example.com:80", "12", "l")
Expecting nothing
ok
Trying:
    add("i", "j.example.com", "13", "m")
Expecting nothing
ok
Trying:
    mgr.find_user_password("f", "g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "g.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:100")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com:80")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("f", "http://g.example.com")
Expecting:
    ('10', 'j')
ok
Trying:
    mgr.find_user_password("g", "h.example.com")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("g", "http://h.example.com:80")
Expecting:
    ('11', 'k')
ok
Trying:
    mgr.find_user_password("h", "i.example.com")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("h", "i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("h", "http://i.example.com:80")
Expecting:
    ('12', 'l')
ok
Trying:
    mgr.find_user_password("i", "j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com")
Expecting:
    ('13', 'm')
ok
Trying:
    mgr.find_user_password("i", "http://j.example.com:80")
Expecting:
    (None, None)
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    Request(url, headers={"Spam-eggs": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    Request(url, headers={"spam-EggS": "blah"}).headers["Spam-eggs"]
Expecting:
    'blah'
ok
Trying:
    url = "http://example.com"
Expecting nothing
ok
Trying:
    r = Request(url, headers={"Spam-eggs": "blah"})
Expecting nothing
ok
Trying:
    r.has_header("Spam-eggs")
Expecting:
    True
ok
Trying:
    r.header_items()
Expecting:
    [('Spam-eggs', 'blah')]
ok
Trying:
    r.add_header("Foo-Bar", "baz")
Expecting nothing
ok
Trying:
    items = r.header_items()
Expecting nothing
ok
Trying:
    items.sort()
Expecting nothing
ok
Trying:
    items
Expecting:
    [('Foo-bar', 'baz'), ('Spam-eggs', 'blah')]
ok
Trying:
    r.has_header("Not-there")
Expecting:
    False
ok
Trying:
    print r.get_header("Not-there")
Expecting:
    None
ok
Trying:
    r.get_header("Not-there", "default")
Expecting:
    'default'
ok
93 items had no tests:
    test.test_urllib2
    test.test_urllib2.FakeMethod
    test.test_urllib2.FakeMethod.__call__
    test.test_urllib2.FakeMethod.__init__
    test.test_urllib2.HandlerTests
    test.test_urllib2.HandlerTests._test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_and_digest_auth_handlers
    test.test_urllib2.HandlerTests.test_basic_auth
    test.test_urllib2.HandlerTests.test_basic_auth_with_single_quoted_realm
    test.test_urllib2.HandlerTests.test_cookie_redirect
    test.test_urllib2.HandlerTests.test_cookies
    test.test_urllib2.HandlerTests.test_errors
    test.test_urllib2.HandlerTests.test_file
    test.test_urllib2.HandlerTests.test_ftp
    test.test_urllib2.HandlerTests.test_http
    test.test_urllib2.HandlerTests.test_http_doubleslash
    test.test_urllib2.HandlerTests.test_proxy
    test.test_urllib2.HandlerTests.test_proxy_basic_auth
    test.test_urllib2.HandlerTests.test_proxy_https
    test.test_urllib2.HandlerTests.test_proxy_https_proxy_authorization
    test.test_urllib2.HandlerTests.test_proxy_no_proxy
    test.test_urllib2.HandlerTests.test_redirect
    test.test_urllib2.MiscTests
    test.test_urllib2.MiscTests.opener_has_handler
    test.test_urllib2.MiscTests.test_build_opener
    test.test_urllib2.MockCookieJar
    test.test_urllib2.MockCookieJar.add_cookie_header
    test.test_urllib2.MockCookieJar.extract_cookies
    test.test_urllib2.MockFile
    test.test_urllib2.MockFile.close
    test.test_urllib2.MockFile.read
    test.test_urllib2.MockFile.readline
    test.test_urllib2.MockHTTPClass
    test.test_urllib2.MockHTTPClass.__call__
    test.test_urllib2.MockHTTPClass.__init__
    test.test_urllib2.MockHTTPClass.getresponse
    test.test_urllib2.MockHTTPClass.request
    test.test_urllib2.MockHTTPClass.set_debuglevel
    test.test_urllib2.MockHTTPClass.set_tunnel
    test.test_urllib2.MockHTTPHandler
    test.test_urllib2.MockHTTPHandler.__init__
    test.test_urllib2.MockHTTPHandler.http_open
    test.test_urllib2.MockHTTPHandler.reset
    test.test_urllib2.MockHTTPResponse
    test.test_urllib2.MockHTTPResponse.__init__
    test.test_urllib2.MockHTTPResponse.read
    test.test_urllib2.MockHTTPSHandler
    test.test_urllib2.MockHTTPSHandler.__init__
    test.test_urllib2.MockHTTPSHandler.https_open
    test.test_urllib2.MockHandler
    test.test_urllib2.MockHandler.__init__
    test.test_urllib2.MockHandler.__lt__
    test.test_urllib2.MockHandler._define_methods
    test.test_urllib2.MockHandler.add_parent
    test.test_urllib2.MockHandler.close
    test.test_urllib2.MockHandler.handle
    test.test_urllib2.MockHeaders
    test.test_urllib2.MockHeaders.getheaders
    test.test_urllib2.MockOpener
    test.test_urllib2.MockOpener.error
    test.test_urllib2.MockOpener.open
    test.test_urllib2.MockPasswordManager
    test.test_urllib2.MockPasswordManager.add_password
    test.test_urllib2.MockPasswordManager.find_user_password
    test.test_urllib2.MockResponse
    test.test_urllib2.MockResponse.__init__
    test.test_urllib2.MockResponse.geturl
    test.test_urllib2.MockResponse.info
    test.test_urllib2.OpenerDirectorTests
    test.test_urllib2.OpenerDirectorTests.test_add_non_handler
    test.test_urllib2.OpenerDirectorTests.test_badly_named_methods
    test.test_urllib2.OpenerDirectorTests.test_handled
    test.test_urllib2.OpenerDirectorTests.test_handler_order
    test.test_urllib2.OpenerDirectorTests.test_http_error
    test.test_urllib2.OpenerDirectorTests.test_processors
    test.test_urllib2.OpenerDirectorTests.test_raise
    test.test_urllib2.RequestTests
    test.test_urllib2.RequestTests.setUp
    test.test_urllib2.RequestTests.test_add_data
    test.test_urllib2.RequestTests.test_get_full_url
    test.test_urllib2.RequestTests.test_get_host
    test.test_urllib2.RequestTests.test_get_host_unquote
    test.test_urllib2.RequestTests.test_get_type
    test.test_urllib2.RequestTests.test_method
    test.test_urllib2.RequestTests.test_proxy
    test.test_urllib2.RequestTests.test_selector
    test.test_urllib2.TrivialTests
    test.test_urllib2.TrivialTests.test_parse_http_list
    test.test_urllib2.TrivialTests.test_trivial
    test.test_urllib2.add_ordered_mock_handlers
    test.test_urllib2.build_test_opener
    test.test_urllib2.sanepathname2url
    test.test_urllib2.test_main
4 items passed all tests:
  27 tests in test.test_urllib2.test_password_manager
  22 tests in test.test_urllib2.test_password_manager_default_port
   3 tests in test.test_urllib2.test_request_headers_dict
  11 tests in test.test_urllib2.test_request_headers_methods
63 tests in 97 items.
63 passed and 0 failed.
Test passed.
doctest (test.test_urllib2) ... 63 tests with zero failures
Trying:
    _parse_proxy('file:/ftp.example.com/')
Expecting:
    Traceback (most recent call last):
    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
ok
Trying:
    _parse_proxy('proxy.example.com')
Expecting:
    (None, None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('proxy.example.com:3128')
Expecting:
    (None, None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('joe:password at proxy.example.com:3128')
Expecting:
    (None, 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://proxy.example.com/')
Expecting:
    ('http', None, None, 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://proxy.example.com:3128/')
Expecting:
    ('http', None, None, 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com/')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com:3128')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com:3128')
ok
Trying:
    _parse_proxy('ftp://joe:password at proxy.example.com/rubbish:3128')
Expecting:
    ('ftp', 'joe', 'password', 'proxy.example.com')
ok
Trying:
    _parse_proxy('http://joe:password at proxy.example.com')
Expecting:
    ('http', 'joe', 'password', 'proxy.example.com')
ok
113 items had no tests:
    urllib2
    urllib2.AbstractBasicAuthHandler
    urllib2.AbstractBasicAuthHandler.__init__
    urllib2.AbstractBasicAuthHandler.http_error_auth_reqed
    urllib2.AbstractBasicAuthHandler.retry_http_basic_auth
    urllib2.AbstractDigestAuthHandler
    urllib2.AbstractDigestAuthHandler.__init__
    urllib2.AbstractDigestAuthHandler.get_algorithm_impls
    urllib2.AbstractDigestAuthHandler.get_authorization
    urllib2.AbstractDigestAuthHandler.get_cnonce
    urllib2.AbstractDigestAuthHandler.get_entity_digest
    urllib2.AbstractDigestAuthHandler.http_error_auth_reqed
    urllib2.AbstractDigestAuthHandler.reset_retry_count
    urllib2.AbstractDigestAuthHandler.retry_http_digest_auth
    urllib2.AbstractHTTPHandler
    urllib2.AbstractHTTPHandler.__init__
    urllib2.AbstractHTTPHandler.do_open
    urllib2.AbstractHTTPHandler.do_request_
    urllib2.AbstractHTTPHandler.set_http_debuglevel
    urllib2.BaseHandler
    urllib2.BaseHandler.__lt__
    urllib2.BaseHandler.add_parent
    urllib2.BaseHandler.close
    urllib2.CacheFTPHandler
    urllib2.CacheFTPHandler.__init__
    urllib2.CacheFTPHandler.check_cache
    urllib2.CacheFTPHandler.connect_ftp
    urllib2.CacheFTPHandler.setMaxConns
    urllib2.CacheFTPHandler.setTimeout
    urllib2.FTPHandler
    urllib2.FTPHandler.connect_ftp
    urllib2.FTPHandler.ftp_open
    urllib2.FileHandler
    urllib2.FileHandler.file_open
    urllib2.FileHandler.get_names
    urllib2.FileHandler.open_local_file
    urllib2.HTTPBasicAuthHandler
    urllib2.HTTPBasicAuthHandler.http_error_401
    urllib2.HTTPCookieProcessor
    urllib2.HTTPCookieProcessor.__init__
    urllib2.HTTPCookieProcessor.http_request
    urllib2.HTTPCookieProcessor.https_response
    urllib2.HTTPDefaultErrorHandler
    urllib2.HTTPDefaultErrorHandler.http_error_default
    urllib2.HTTPDigestAuthHandler
    urllib2.HTTPDigestAuthHandler.http_error_401
    urllib2.HTTPError
    urllib2.HTTPError.__init__
    urllib2.HTTPError.__str__
    urllib2.HTTPErrorProcessor
    urllib2.HTTPErrorProcessor.https_response
    urllib2.HTTPHandler
    urllib2.HTTPHandler.http_open
    urllib2.HTTPPasswordMgr
    urllib2.HTTPPasswordMgr.__init__
    urllib2.HTTPPasswordMgr.add_password
    urllib2.HTTPPasswordMgr.find_user_password
    urllib2.HTTPPasswordMgr.is_suburi
    urllib2.HTTPPasswordMgr.reduce_uri
    urllib2.HTTPPasswordMgrWithDefaultRealm
    urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password
    urllib2.HTTPRedirectHandler
    urllib2.HTTPRedirectHandler.http_error_307
    urllib2.HTTPRedirectHandler.redirect_request
    urllib2.HTTPSHandler
    urllib2.HTTPSHandler.https_open
    urllib2.OpenerDirector
    urllib2.OpenerDirector.__init__
    urllib2.OpenerDirector._call_chain
    urllib2.OpenerDirector._open
    urllib2.OpenerDirector.add_handler
    urllib2.OpenerDirector.close
    urllib2.OpenerDirector.error
    urllib2.OpenerDirector.open
    urllib2.ProxyBasicAuthHandler
    urllib2.ProxyBasicAuthHandler.http_error_407
    urllib2.ProxyDigestAuthHandler
    urllib2.ProxyDigestAuthHandler.http_error_407
    urllib2.ProxyHandler
    urllib2.ProxyHandler.__init__
    urllib2.ProxyHandler.proxy_open
    urllib2.Request
    urllib2.Request.__getattr__
    urllib2.Request.__init__
    urllib2.Request.add_data
    urllib2.Request.add_header
    urllib2.Request.add_unredirected_header
    urllib2.Request.get_data
    urllib2.Request.get_full_url
    urllib2.Request.get_header
    urllib2.Request.get_host
    urllib2.Request.get_method
    urllib2.Request.get_origin_req_host
    urllib2.Request.get_selector
    urllib2.Request.get_type
    urllib2.Request.has_data
    urllib2.Request.has_header
    urllib2.Request.has_proxy
    urllib2.Request.header_items
    urllib2.Request.is_unverifiable
    urllib2.Request.set_proxy
    urllib2.URLError
    urllib2.URLError.__init__
    urllib2.URLError.__str__
    urllib2.UnknownHandler
    urllib2.UnknownHandler.unknown_open
    urllib2.build_opener
    urllib2.install_opener
    urllib2.parse_http_list
    urllib2.parse_keqv_list
    urllib2.randombytes
    urllib2.request_host
    urllib2.urlopen
1 items passed all tests:
  11 tests in urllib2._parse_proxy
11 tests in 114 items.
11 passed and 0 failed.
Test passed.
doctest (urllib2) ... 11 tests with zero failures
test_parse_http_list (test.test_urllib2.TrivialTests) ... ok
test_trivial (test.test_urllib2.TrivialTests) ... ok
test_add_non_handler (test.test_urllib2.OpenerDirectorTests) ... ok
test_badly_named_methods (test.test_urllib2.OpenerDirectorTests) ... ok
test_handled (test.test_urllib2.OpenerDirectorTests) ... ok
test_handler_order (test.test_urllib2.OpenerDirectorTests) ... ok
test_http_error (test.test_urllib2.OpenerDirectorTests) ... ok
test_processors (test.test_urllib2.OpenerDirectorTests) ... ok
test_raise (test.test_urllib2.OpenerDirectorTests) ... ok
test_basic_and_digest_auth_handlers (test.test_urllib2.HandlerTests) ... ok
test_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_basic_auth_with_single_quoted_realm (test.test_urllib2.HandlerTests) ... ok
test_cookie_redirect (test.test_urllib2.HandlerTests) ... ok
test_cookies (test.test_urllib2.HandlerTests) ... ok
test_errors (test.test_urllib2.HandlerTests) ... ok
test_file (test.test_urllib2.HandlerTests) ... ERROR
test_ftp (test.test_urllib2.HandlerTests) ... ok
test_http (test.test_urllib2.HandlerTests) ... ok
test_http_doubleslash (test.test_urllib2.HandlerTests) ... ok
test_proxy (test.test_urllib2.HandlerTests) ... ok
test_proxy_basic_auth (test.test_urllib2.HandlerTests) ... ok
test_proxy_https (test.test_urllib2.HandlerTests) ... ok
test_proxy_https_proxy_authorization (test.test_urllib2.HandlerTests) ... ok
test_proxy_no_proxy (test.test_urllib2.HandlerTests) ... ok
test_redirect (test.test_urllib2.HandlerTests) ... ok
test_build_opener (test.test_urllib2.MiscTests) ... ok
test_add_data (test.test_urllib2.RequestTests) ... ok
test_get_full_url (test.test_urllib2.RequestTests) ... ok
test_get_host (test.test_urllib2.RequestTests) ... ok
test_get_host_unquote (test.test_urllib2.RequestTests) ... ok
test_get_type (test.test_urllib2.RequestTests) ... ok
test_method (test.test_urllib2.RequestTests) ... ok
test_proxy (test.test_urllib2.RequestTests) ... ok
test_selector (test.test_urllib2.RequestTests) ... ok

======================================================================
ERROR: test_file (test.test_urllib2.HandlerTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

----------------------------------------------------------------------
Ran 34 tests in 0.334s

FAILED (errors=1)
test test_urllib2 failed -- Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2.py", line 711, in test_file
    h.file_open, Request(url))
  File "/tmp/python-test/local/lib/python2.7/unittest/case.py", line 456, in assertRaises
    callableObj(*args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1269, in file_open
    return self.open_local_file(req)
  File "/tmp/python-test/local/lib/python2.7/urllib2.py", line 1301, in open_local_file
    (not port and socket.gethostbyname(host) in self.get_names()):
gaierror: [Errno -2] Name or service not known

test_urllib2_localnet
test_urllib2net
test test_urllib2net failed -- multiple errors occurred; run in verbose mode for details
Re-running test 'test_urllib2net' in verbose mode
test_file (test.test_urllib2net.OtherNetworkTests) ... ok
test_ftp (test.test_urllib2net.OtherNetworkTests) ... ok
test_close (test.test_urllib2net.CloseSocketTest) ... ERROR
test_ftp_basic (test.test_urllib2net.TimeoutTest) ... ERROR
test_ftp_default_timeout (test.test_urllib2net.TimeoutTest) ... ERROR
test_ftp_no_timeout (test.test_urllib2net.TimeoutTest) ... ERROR
test_ftp_timeout (test.test_urllib2net.TimeoutTest) ... ERROR
test_http_basic (test.test_urllib2net.TimeoutTest) ... ERROR
test_http_default_timeout (test.test_urllib2net.TimeoutTest) ... ERROR
test_http_no_timeout (test.test_urllib2net.TimeoutTest) ... ERROR
test_http_timeout (test.test_urllib2net.TimeoutTest) ... ERROR

======================================================================
ERROR: test_close (test.test_urllib2net.CloseSocketTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 83, in test_close
    response = _urlopen_with_retry("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_ftp_basic (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 239, in test_ftp_basic
    u = _urlopen_with_retry(self.FTP_HOST)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_ftp_default_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 246, in test_ftp_default_timeout
    u = _urlopen_with_retry(self.FTP_HOST)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_ftp_no_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 255, in test_ftp_no_timeout
    u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_ftp_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 261, in test_ftp_timeout
    u = _urlopen_with_retry(self.FTP_HOST, timeout=60)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_http_basic (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 210, in test_http_basic
    u = _urlopen_with_retry("http://www.python.org")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_http_default_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 217, in test_http_default_timeout
    u = _urlopen_with_retry("http://www.python.org")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_http_no_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 226, in test_http_no_timeout
    u = _urlopen_with_retry("http://www.python.org", timeout=None)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

======================================================================
ERROR: test_http_timeout (test.test_urllib2net.TimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 232, in test_http_timeout
    u = _urlopen_with_retry("http://www.python.org", timeout=120)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 27, in wrapped
    return _retry_thrice(func, exc, *args, **kwargs)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllib2net.py", line 23, in _retry_thrice
    raise last_exc
URLError: 

----------------------------------------------------------------------
Ran 11 tests in 36.631s

FAILED (errors=9)
test test_urllib2net failed -- multiple errors occurred
test_urllibnet
test test_urllibnet failed -- multiple errors occurred; run in verbose mode for details
Re-running test 'test_urllibnet' in verbose mode
testURLread (test.test_urllibnet.URLTimeoutTest) ... ERROR
test_bad_address (test.test_urllibnet.urlopenNetworkTests) ... ok
test_basic (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_fileno (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_getcode (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_geturl (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_info (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_readlines (test.test_urllibnet.urlopenNetworkTests) ... ERROR
test_basic (test.test_urllibnet.urlretrieveNetworkTests) ... ERROR
test_data_header (test.test_urllibnet.urlretrieveNetworkTests) ... ERROR
test_header (test.test_urllibnet.urlretrieveNetworkTests) ... ERROR
test_specified_path (test.test_urllibnet.urlretrieveNetworkTests) ... ERROR

======================================================================
ERROR: testURLread (test.test_urllibnet.URLTimeoutTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 39, in testURLread
    f = _open_with_retry(urllib.urlopen, "http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_basic (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 62, in test_basic
    open_url = self.urlopen("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 58, in urlopen
    return _open_with_retry(urllib.urlopen, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_fileno (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 122, in test_fileno
    open_url = self.urlopen("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 58, in urlopen
    return _open_with_retry(urllib.urlopen, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_getcode (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 108, in test_getcode
    open_url = urllib.FancyURLopener().open(URL)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "/tmp/python-test/local/lib/python2.7/urllib.py", line 342, in open_http
    h.endheaders(data)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 940, in endheaders
    self._send_output(message_body)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 803, in _send_output
    self.send(msg)
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 755, in send
    self.connect()
  File "/tmp/python-test/local/lib/python2.7/httplib.py", line 736, in connect
    self.timeout, self.source_address)
  File "/tmp/python-test/local/lib/python2.7/socket.py", line 567, in create_connection
    raise error, msg
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_geturl (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 98, in test_geturl
    open_url = self.urlopen(URL)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 58, in urlopen
    return _open_with_retry(urllib.urlopen, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_info (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 85, in test_info
    open_url = self.urlopen("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 58, in urlopen
    return _open_with_retry(urllib.urlopen, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_readlines (test.test_urllibnet.urlopenNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 74, in test_readlines
    open_url = self.urlopen("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 58, in urlopen
    return _open_with_retry(urllib.urlopen, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_basic (test.test_urllibnet.urlretrieveNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 152, in test_basic
    file_location,info = self.urlretrieve("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 148, in urlretrieve
    return _open_with_retry(urllib.urlretrieve, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_data_header (test.test_urllibnet.urlretrieveNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 185, in test_data_header
    file_location, fileheaders = self.urlretrieve(logo)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 148, in urlretrieve
    return _open_with_retry(urllib.urlretrieve, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_header (test.test_urllibnet.urlretrieveNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 178, in test_header
    file_location, header = self.urlretrieve("http://www.python.org/")
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 148, in urlretrieve
    return _open_with_retry(urllib.urlretrieve, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

======================================================================
ERROR: test_specified_path (test.test_urllibnet.urlretrieveNetworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 166, in test_specified_path
    test_support.TESTFN)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 148, in urlretrieve
    return _open_with_retry(urllib.urlretrieve, *args)
  File "/tmp/python-test/local/lib/python2.7/test/test_urllibnet.py", line 25, in _open_with_retry
    raise last_exc
IOError: [Errno socket error] [Errno 97] Address family not supported by protocol

----------------------------------------------------------------------
Ran 12 tests in 1.342s

FAILED (errors=11)
test test_urllibnet failed -- multiple errors occurred
test_urlparse
test_userdict
test_userlist
test_userstring
test_uu
test_uuid
test_wait3
test_wait4
test_warnings
[15679 refs]
[15679 refs]
[15672 refs]
[15679 refs]
[15679 refs]
[15672 refs]
test_wave
test_weakref
test_weakset
test_whichdb
test_winreg
test_winreg skipped -- No module named _winreg
test_winsound
test_winsound skipped -- No module named winsound
test_with
test_wsgiref
test_xdrlib
test_xml_etree
test_xml_etree_c
test_xmllib
test_xmlrpc
test_xpickle
sh: line 1: python2.4: command not found
sh: line 1: python2.6: command not found
test_xrange
test_zipfile
test_zipfile64
test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run
test_zipimport
test_zipimport_support
test_zlib
341 tests OK.
7 tests failed:
    test_robotparser test_smtpnet test_ssl test_timeout test_urllib2
    test_urllib2net test_urllibnet
33 tests skipped:
    test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_gl
    test_imgfile test_ioctl test_kqueue test_macos test_macostools
    test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages
    test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly
    test_ttk_textonly test_unicode_file test_winreg test_winsound
    test_zipfile64
12 skips unexpected on linux2:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_epoll test_gdb test_ioctl
    test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly
[984052 refs]

From python-checkins at python.org  Fri Dec 10 18:45:13 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 10 Dec 2010 18:45:13 +0100 (CET)
Subject: [Python-checkins] r87158 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101210174513.6A99EEE987@mail.python.org>

Author: raymond.hettinger
Date: Fri Dec 10 18:45:13 2010
New Revision: 87158

Log:
Move nntp entry back to changed modules section and add entry for non-ascii import directories.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Fri Dec 10 18:45:13 2010
@@ -570,6 +570,12 @@
 
   (See :issue:`10518`.)
 
+* Python's import mechanism can now load module installed in directories with
+  non-ASCII characters in the path name.
+
+  (Required extensive work by Victor Stinner in :issue:`9425`.)
+
+
 New, Improved, and Deprecated Modules
 =====================================
 
@@ -794,6 +800,13 @@
   5-tuple), and :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer).  (Added by
   Antoine Pitrou; :issue:`8321`.)
 
+* The :mod:`nntplib` module has a revamped implementation with better bytes and
+  unicode semantics as well as more practical APIs.  These improvements break
+  compatibility with the nntplib version in Python 3.1, which was partly
+  dysfunctional in itself.
+
+  (Contributed by Antoine Pitrou in :issue:`9360`)
+
 * :class:`http.client.HTTPSConnection`, :class:`urllib.request.HTTPSHandler`
   and :func:`urllib.request.urlopen` now take optional arguments to allow for
   server certificate checking against a set of Certificate Authorities,
@@ -1221,13 +1234,6 @@
    reproduce Python 3.1 sequences, set the *version* argument to *1*,
    ``random.seed(s, version=1)``.
 
-* The :mod:`nntplib` module has a revamped implementation with better bytes and
-  unicode semantics as well as more practical APIs.  These improvements break
-  compatibility with the nntplib version in Python 3.1, which was partly
-  dysfunctional in itself.
-
-  (Contributed by Antoine Pitrou in :issue:`9360`)
-
 * The previously deprecated :func:`string.maketrans` function has been removed
   in favor of the static methods, :meth:`bytes.maketrans` and
   :meth:`bytearray.maketrans`.  This change solves the confusion around which

From python-checkins at python.org  Fri Dec 10 19:11:24 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Fri, 10 Dec 2010 19:11:24 +0100 (CET)
Subject: [Python-checkins] r87159 - in python/branches/py3k:
	Doc/library/unicodedata.rst Modules/_lsprof.c Objects/moduleobject.c
Message-ID: <20101210181124.DCA48EE982@mail.python.org>

Author: alexander.belopolsky
Date: Fri Dec 10 19:11:24 2010
New Revision: 87159

Log:
Updated UCD version and unicode.org links to Unicode 6.0.0

Modified:
   python/branches/py3k/Doc/library/unicodedata.rst
   python/branches/py3k/Modules/_lsprof.c
   python/branches/py3k/Objects/moduleobject.c

Modified: python/branches/py3k/Doc/library/unicodedata.rst
==============================================================================
--- python/branches/py3k/Doc/library/unicodedata.rst	(original)
+++ python/branches/py3k/Doc/library/unicodedata.rst	Fri Dec 10 19:11:24 2010
@@ -13,14 +13,15 @@
    single: character
    pair: Unicode; database
 
-This module provides access to the Unicode Character Database which defines
-character properties for all Unicode characters. The data in this database is
-based on the :file:`UnicodeData.txt` file version 5.2.0 which is publicly
-available from ftp://ftp.unicode.org/.
-
-The module uses the same names and symbols as defined by the UnicodeData File
-Format 5.2.0 (see http://www.unicode.org/reports/tr44/tr44-4.html).
-It defines the following functions:
+This module provides access to the Unicode Character Database (UCD) which
+defines character properties for all Unicode characters. The data contained in
+this database is compiled from the `UCD version 6.0.0
+`_.
+
+The module uses the same names and symbols as defined by Unicode
+Standard Annex #44, `"Unicode Character Database"
+`_.  It defines the
+following functions:
 
 
 .. function:: lookup(name)

Modified: python/branches/py3k/Modules/_lsprof.c
==============================================================================
--- python/branches/py3k/Modules/_lsprof.c	(original)
+++ python/branches/py3k/Modules/_lsprof.c	Fri Dec 10 19:11:24 2010
@@ -176,31 +176,21 @@
     if (fn->m_self == NULL) {
         /* built-in function: look up the module name */
         PyObject *mod = fn->m_module;
-        const char *modname;
-        if (mod && PyUnicode_Check(mod)) {
-            /* XXX: The following will truncate module names with embedded
-             * null-characters.  It is unlikely that this can happen in
-             * practice and the concequences are not serious enough to
-             * introduce extra checks here.
-             */
-            modname = _PyUnicode_AsString(mod);
-            if (modname == NULL) {
-                modname = "";
-                PyErr_Clear();
+        PyObject *modname;
+        if (mod != NULL) {
+            if (PyUnicode_Check(mod)) {
+                modname = mod;
+                Py_INCREF(modname);
             }
-        }
-        else if (mod && PyModule_Check(mod)) {
-            modname = PyModule_GetName(mod);
-            if (modname == NULL) {
-                PyErr_Clear();
-                modname = "builtins";
+            else if (PyModule_Check(mod)) {
+                modname = PyModule_GetNameObject(mod);
+                if (modname == NULL)
+                    PyErr_Clear();
             }
         }
-        else {
-            modname = "builtins";
-        }
-        if (strcmp(modname, "builtins") != 0)
-            return PyUnicode_FromFormat("<%s.%s>",
+        if (modname != NULL && 
+            PyUnicode_CompareWithASCIIString(modname, "builtins") != 0)
+            return PyUnicode_FromFormat("<%U.%s>",
                                         modname,
                                         fn->m_ml->ml_name);
         else

Modified: python/branches/py3k/Objects/moduleobject.c
==============================================================================
--- python/branches/py3k/Objects/moduleobject.c	(original)
+++ python/branches/py3k/Objects/moduleobject.c	Fri Dec 10 19:11:24 2010
@@ -168,8 +168,8 @@
     return d;
 }
 
-const char *
-PyModule_GetName(PyObject *m)
+PyObject *
+PyModule_GetNameObject(PyObject *m)
 {
     PyObject *d;
     PyObject *nameobj;
@@ -185,7 +185,21 @@
         PyErr_SetString(PyExc_SystemError, "nameless module");
         return NULL;
     }
-    return _PyUnicode_AsString(nameobj);
+    Py_INCREF(nameobj);
+    return nameobj;
+}
+
+const char *
+PyModule_GetName(PyObject *m)
+{
+    PyObject *nameobj;
+    char *utf8;
+    nameobj = PyModule_GetNameObject(m);
+    if (nameobj == NULL)
+        return NULL;
+    utf8 = _PyUnicode_AsString(nameobj);
+    Py_DECREF(nameobj);
+    return utf8;
 }
 
 PyObject*

From python-checkins at python.org  Fri Dec 10 19:14:16 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Fri, 10 Dec 2010 19:14:16 +0100 (CET)
Subject: [Python-checkins] r87160 - in python/branches/py3k:
	Modules/_lsprof.c Objects/moduleobject.c
Message-ID: <20101210181416.4940CEE98D@mail.python.org>

Author: alexander.belopolsky
Date: Fri Dec 10 19:14:16 2010
New Revision: 87160

Log:
Reverted accidental commit (from r87159)

Modified:
   python/branches/py3k/Modules/_lsprof.c
   python/branches/py3k/Objects/moduleobject.c

Modified: python/branches/py3k/Modules/_lsprof.c
==============================================================================
--- python/branches/py3k/Modules/_lsprof.c	(original)
+++ python/branches/py3k/Modules/_lsprof.c	Fri Dec 10 19:14:16 2010
@@ -176,21 +176,31 @@
     if (fn->m_self == NULL) {
         /* built-in function: look up the module name */
         PyObject *mod = fn->m_module;
-        PyObject *modname;
-        if (mod != NULL) {
-            if (PyUnicode_Check(mod)) {
-                modname = mod;
-                Py_INCREF(modname);
+        const char *modname;
+        if (mod && PyUnicode_Check(mod)) {
+            /* XXX: The following will truncate module names with embedded
+             * null-characters.  It is unlikely that this can happen in
+             * practice and the concequences are not serious enough to
+             * introduce extra checks here.
+             */
+            modname = _PyUnicode_AsString(mod);
+            if (modname == NULL) {
+                modname = "";
+                PyErr_Clear();
             }
-            else if (PyModule_Check(mod)) {
-                modname = PyModule_GetNameObject(mod);
-                if (modname == NULL)
-                    PyErr_Clear();
+        }
+        else if (mod && PyModule_Check(mod)) {
+            modname = PyModule_GetName(mod);
+            if (modname == NULL) {
+                PyErr_Clear();
+                modname = "builtins";
             }
         }
-        if (modname != NULL && 
-            PyUnicode_CompareWithASCIIString(modname, "builtins") != 0)
-            return PyUnicode_FromFormat("<%U.%s>",
+        else {
+            modname = "builtins";
+        }
+        if (strcmp(modname, "builtins") != 0)
+            return PyUnicode_FromFormat("<%s.%s>",
                                         modname,
                                         fn->m_ml->ml_name);
         else

Modified: python/branches/py3k/Objects/moduleobject.c
==============================================================================
--- python/branches/py3k/Objects/moduleobject.c	(original)
+++ python/branches/py3k/Objects/moduleobject.c	Fri Dec 10 19:14:16 2010
@@ -168,8 +168,8 @@
     return d;
 }
 
-PyObject *
-PyModule_GetNameObject(PyObject *m)
+const char *
+PyModule_GetName(PyObject *m)
 {
     PyObject *d;
     PyObject *nameobj;
@@ -185,21 +185,7 @@
         PyErr_SetString(PyExc_SystemError, "nameless module");
         return NULL;
     }
-    Py_INCREF(nameobj);
-    return nameobj;
-}
-
-const char *
-PyModule_GetName(PyObject *m)
-{
-    PyObject *nameobj;
-    char *utf8;
-    nameobj = PyModule_GetNameObject(m);
-    if (nameobj == NULL)
-        return NULL;
-    utf8 = _PyUnicode_AsString(nameobj);
-    Py_DECREF(nameobj);
-    return utf8;
+    return _PyUnicode_AsString(nameobj);
 }
 
 PyObject*

From python-checkins at python.org  Fri Dec 10 20:22:11 2010
From: python-checkins at python.org (georg.brandl)
Date: Fri, 10 Dec 2010 20:22:11 +0100 (CET)
Subject: [Python-checkins] r87161 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101210192211.694F7EE9F0@mail.python.org>

Author: georg.brandl
Date: Fri Dec 10 20:22:11 2010
New Revision: 87161

Log:
Fix typo.

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Fri Dec 10 20:22:11 2010
@@ -1165,8 +1165,8 @@
 IDLE
 ====
 
-* The format menu now has an option to clean-up source files by strip trailing
-  whitespace (:issue:`5150`).
+* The format menu now has an option to clean-up source files by stripping
+  trailing whitespace (:issue:`5150`).
 
 
 Build and C API Changes

From python-checkins at python.org  Sat Dec 11 01:41:02 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sat, 11 Dec 2010 01:41:02 +0100 (CET)
Subject: [Python-checkins] r87162 -
	python/branches/release27-maint/Doc/library/stdtypes.rst
Message-ID: <20101211004102.E773DEE98A@mail.python.org>

Author: raymond.hettinger
Date: Sat Dec 11 01:41:02 2010
New Revision: 87162

Log:
Issue 2690:  Doc fixup.  xrange() objects are slicable.


Modified:
   python/branches/release27-maint/Doc/library/stdtypes.rst

Modified: python/branches/release27-maint/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/stdtypes.rst	(original)
+++ python/branches/release27-maint/Doc/library/stdtypes.rst	Sat Dec 11 01:41:02 2010
@@ -699,7 +699,7 @@
 
 Objects of type xrange are similar to buffers in that there is no specific syntax to
 create them, but they are created using the :func:`xrange` function.  They don't
-support slicing, concatenation or repetition, and using ``in``, ``not in``,
+support concatenation or repetition, and using ``in``, ``not in``,
 :func:`min` or :func:`max` on them is inefficient.
 
 Most sequence types support the following operations.  The ``in`` and ``not in``

From python-checkins at python.org  Sat Dec 11 03:05:33 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Dec 2010 03:05:33 +0100 (CET)
Subject: [Python-checkins] r87163 - in python/branches/release31-maint:
	Misc/NEWS Modules/mmapmodule.c
Message-ID: <20101211020533.392A8EE986@mail.python.org>

Author: r.david.murray
Date: Sat Dec 11 03:05:32 2010
New Revision: 87163

Log:
Merged revisions 85678 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85678 | r.david.murray | 2010-10-17 21:14:06 -0400 (Sun, 17 Oct 2010) | 5 lines
  
  #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
  
  Patch by S?bastien Sabl?.  This solves a test_mmap failure on AIX.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Modules/mmapmodule.c

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Sat Dec 11 03:05:32 2010
@@ -29,6 +29,11 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+Extensions
+----------
+
+- Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
+
 Tests
 -----
 

Modified: python/branches/release31-maint/Modules/mmapmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/mmapmodule.c	(original)
+++ python/branches/release31-maint/Modules/mmapmodule.c	Sat Dec 11 03:05:32 2010
@@ -125,7 +125,8 @@
     if (m_obj->fd >= 0)
         (void) close(m_obj->fd);
     if (m_obj->data!=NULL) {
-        msync(m_obj->data, m_obj->size, MS_SYNC);
+        if (m_obj->access != ACCESS_READ && m_obj->access != ACCESS_COPY)
+            msync(m_obj->data, m_obj->size, MS_SYNC);
         munmap(m_obj->data, m_obj->size);
     }
 #endif /* UNIX */
@@ -570,6 +571,10 @@
         PyErr_SetString(PyExc_ValueError, "flush values out of range");
         return NULL;
     }
+
+    if (self->access == ACCESS_READ || self->access == ACCESS_COPY)
+        return PyLong_FromLong(0);
+
 #ifdef MS_WINDOWS
     return PyLong_FromLong((long) FlushViewOfFile(self->data+offset, size));
 #elif defined(UNIX)

From python-checkins at python.org  Sat Dec 11 03:13:04 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Dec 2010 03:13:04 +0100 (CET)
Subject: [Python-checkins] r87164 - in python/branches/release27-maint:
	Misc/NEWS Modules/mmapmodule.c
Message-ID: <20101211021304.A7DC0EE986@mail.python.org>

Author: r.david.murray
Date: Sat Dec 11 03:13:04 2010
New Revision: 87164

Log:
Merged revisions 85678 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r85678 | r.david.murray | 2010-10-17 21:14:06 -0400 (Sun, 17 Oct 2010) | 5 lines
  
  #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
  
  Patch by S?bastien Sabl?.  This solves a test_mmap failure on AIX.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Misc/NEWS
   python/branches/release27-maint/Modules/mmapmodule.c

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sat Dec 11 03:13:04 2010
@@ -29,6 +29,11 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+Extension Modules
+-----------------
+
+- Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY.
+
 Tests
 -----
 

Modified: python/branches/release27-maint/Modules/mmapmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/mmapmodule.c	(original)
+++ python/branches/release27-maint/Modules/mmapmodule.c	Sat Dec 11 03:13:04 2010
@@ -124,7 +124,8 @@
     if (m_obj->fd >= 0)
         (void) close(m_obj->fd);
     if (m_obj->data!=NULL) {
-        msync(m_obj->data, m_obj->size, MS_SYNC);
+        if (m_obj->access != ACCESS_READ && m_obj->access != ACCESS_COPY)
+            msync(m_obj->data, m_obj->size, MS_SYNC);
         munmap(m_obj->data, m_obj->size);
     }
 #endif /* UNIX */
@@ -559,6 +560,10 @@
         PyErr_SetString(PyExc_ValueError, "flush values out of range");
         return NULL;
     }
+
+    if (self->access == ACCESS_READ || self->access == ACCESS_COPY)
+        return PyLong_FromLong(0);
+
 #ifdef MS_WINDOWS
     return PyInt_FromLong((long) FlushViewOfFile(self->data+offset, size));
 #elif defined(UNIX)

From python-checkins at python.org  Sat Dec 11 03:26:37 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Dec 2010 03:26:37 +0100 (CET)
Subject: [Python-checkins] r87165 - python/branches/release31-maint
Message-ID: <20101211022637.BA47EEE986@mail.python.org>

Author: r.david.murray
Date: Sat Dec 11 03:26:37 2010
New Revision: 87165

Log:
Blocked revisions 83675,85087,85178 via svnmerge

........
  r83675 | r.david.murray | 2010-08-03 13:56:09 -0400 (Tue, 03 Aug 2010) | 12 lines
  
  #9444: use first of prefix_chars for help opt instead of raising error
  
  An argparse option parser created with a prefix_chars that did not
  include a '-' would happily add -h and --help options, and then throw
  an error when it tried to format the help because the - was an invalid
  prefix character.  This patch makes it use the first character of
  prefix_chars as the character for the help options if and only if '-'
  is not one of the valid prefix_chars.
  
  Fix by Theodore Turocy, unit tests by Catherine Devlin.
........
  r85087 | r.david.murray | 2010-09-28 21:22:20 -0400 (Tue, 28 Sep 2010) | 2 lines
  
  Have test_sqlite print version info when run in verbose mode.
........
  r85178 | r.david.murray | 2010-10-02 09:29:13 -0400 (Sat, 02 Oct 2010) | 2 lines
  
  Make the printing of sqlite version in verbose mode work with regrtest -w.
........


Modified:
   python/branches/release31-maint/   (props changed)

From python-checkins at python.org  Sat Dec 11 03:29:48 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Dec 2010 03:29:48 +0100 (CET)
Subject: [Python-checkins] r87166 - python/branches/release27-maint
Message-ID: <20101211022948.8DA86EE986@mail.python.org>

Author: r.david.murray
Date: Sat Dec 11 03:29:48 2010
New Revision: 87166

Log:
Blocked revisions 85087,85178 via svnmerge

........
  r85087 | r.david.murray | 2010-09-28 21:22:20 -0400 (Tue, 28 Sep 2010) | 2 lines
  
  Have test_sqlite print version info when run in verbose mode.
........
  r85178 | r.david.murray | 2010-10-02 09:29:13 -0400 (Sat, 02 Oct 2010) | 2 lines
  
  Make the printing of sqlite version in verbose mode work with regrtest -w.
........


Modified:
   python/branches/release27-maint/   (props changed)

From solipsis at pitrou.net  Sat Dec 11 04:49:47 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sat, 11 Dec 2010 04:49:47 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87161): sum=0
Message-ID: 

py3k results for svn r87161 (hg cset 60e0b62cef6d)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogRfz9Ko', '-x']

From python-checkins at python.org  Sat Dec 11 05:25:57 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Dec 2010 05:25:57 +0100 (CET)
Subject: [Python-checkins] r87167 - in python/branches/release27-maint:
	Grammar/Grammar Include/graminit.h Misc/NEWS Python/graminit.c
Message-ID: <20101211042557.9AE25EE982@mail.python.org>

Author: benjamin.peterson
Date: Sat Dec 11 05:25:57 2010
New Revision: 87167

Log:
remove dictmaker rule; it's unused

Modified:
   python/branches/release27-maint/Grammar/Grammar
   python/branches/release27-maint/Include/graminit.h
   python/branches/release27-maint/Misc/NEWS
   python/branches/release27-maint/Python/graminit.c

Modified: python/branches/release27-maint/Grammar/Grammar
==============================================================================
--- python/branches/release27-maint/Grammar/Grammar	(original)
+++ python/branches/release27-maint/Grammar/Grammar	Sat Dec 11 05:25:57 2010
@@ -114,7 +114,6 @@
 sliceop: ':' [test]
 exprlist: expr (',' expr)* [',']
 testlist: test (',' test)* [',']
-dictmaker: test ':' test (',' test ':' test)* [',']
 dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
                   (test (comp_for | (',' test)* [','])) )
 

Modified: python/branches/release27-maint/Include/graminit.h
==============================================================================
--- python/branches/release27-maint/Include/graminit.h	(original)
+++ python/branches/release27-maint/Include/graminit.h	Sat Dec 11 05:25:57 2010
@@ -72,17 +72,16 @@
 #define sliceop 325
 #define exprlist 326
 #define testlist 327
-#define dictmaker 328
-#define dictorsetmaker 329
-#define classdef 330
-#define arglist 331
-#define argument 332
-#define list_iter 333
-#define list_for 334
-#define list_if 335
-#define comp_iter 336
-#define comp_for 337
-#define comp_if 338
-#define testlist1 339
-#define encoding_decl 340
-#define yield_expr 341
+#define dictorsetmaker 328
+#define classdef 329
+#define arglist 330
+#define argument 331
+#define list_iter 332
+#define list_for 333
+#define list_if 334
+#define comp_iter 335
+#define comp_for 336
+#define comp_if 337
+#define testlist1 338
+#define encoding_decl 339
+#define yield_expr 340

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sat Dec 11 05:25:57 2010
@@ -9,6 +9,8 @@
 Core and Builtins
 -----------------
 
+- Issue #10674: Remove unused 'dictmaker' rule from grammar.
+
 - Issue #10596: Fix float.__mod__ to have the same behaviour as
   float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
   0.0, not -0.0.

Modified: python/branches/release27-maint/Python/graminit.c
==============================================================================
--- python/branches/release27-maint/Python/graminit.c	(original)
+++ python/branches/release27-maint/Python/graminit.c	Sat Dec 11 05:25:57 2010
@@ -1526,335 +1526,311 @@
 static arc arcs_72_0[1] = {
     {28, 1},
 };
-static arc arcs_72_1[1] = {
-    {23, 2},
-};
-static arc arcs_72_2[1] = {
-    {28, 3},
-};
-static arc arcs_72_3[2] = {
-    {29, 4},
-    {0, 3},
-};
-static arc arcs_72_4[2] = {
-    {28, 1},
-    {0, 4},
-};
-static state states_72[5] = {
-    {1, arcs_72_0},
-    {1, arcs_72_1},
-    {1, arcs_72_2},
-    {2, arcs_72_3},
-    {2, arcs_72_4},
-};
-static arc arcs_73_0[1] = {
-    {28, 1},
-};
-static arc arcs_73_1[4] = {
+static arc arcs_72_1[4] = {
     {23, 2},
     {157, 3},
     {29, 4},
     {0, 1},
 };
-static arc arcs_73_2[1] = {
+static arc arcs_72_2[1] = {
     {28, 5},
 };
-static arc arcs_73_3[1] = {
+static arc arcs_72_3[1] = {
     {0, 3},
 };
-static arc arcs_73_4[2] = {
+static arc arcs_72_4[2] = {
     {28, 6},
     {0, 4},
 };
-static arc arcs_73_5[3] = {
+static arc arcs_72_5[3] = {
     {157, 3},
     {29, 7},
     {0, 5},
 };
-static arc arcs_73_6[2] = {
+static arc arcs_72_6[2] = {
     {29, 4},
     {0, 6},
 };
-static arc arcs_73_7[2] = {
+static arc arcs_72_7[2] = {
     {28, 8},
     {0, 7},
 };
-static arc arcs_73_8[1] = {
+static arc arcs_72_8[1] = {
     {23, 9},
 };
-static arc arcs_73_9[1] = {
+static arc arcs_72_9[1] = {
     {28, 10},
 };
-static arc arcs_73_10[2] = {
+static arc arcs_72_10[2] = {
     {29, 7},
     {0, 10},
 };
-static state states_73[11] = {
-    {1, arcs_73_0},
-    {4, arcs_73_1},
-    {1, arcs_73_2},
-    {1, arcs_73_3},
-    {2, arcs_73_4},
-    {3, arcs_73_5},
-    {2, arcs_73_6},
-    {2, arcs_73_7},
-    {1, arcs_73_8},
-    {1, arcs_73_9},
-    {2, arcs_73_10},
+static state states_72[11] = {
+    {1, arcs_72_0},
+    {4, arcs_72_1},
+    {1, arcs_72_2},
+    {1, arcs_72_3},
+    {2, arcs_72_4},
+    {3, arcs_72_5},
+    {2, arcs_72_6},
+    {2, arcs_72_7},
+    {1, arcs_72_8},
+    {1, arcs_72_9},
+    {2, arcs_72_10},
 };
-static arc arcs_74_0[1] = {
-    {162, 1},
+static arc arcs_73_0[1] = {
+    {161, 1},
 };
-static arc arcs_74_1[1] = {
+static arc arcs_73_1[1] = {
     {21, 2},
 };
-static arc arcs_74_2[2] = {
+static arc arcs_73_2[2] = {
     {13, 3},
     {23, 4},
 };
-static arc arcs_74_3[2] = {
+static arc arcs_73_3[2] = {
     {9, 5},
     {15, 6},
 };
-static arc arcs_74_4[1] = {
+static arc arcs_73_4[1] = {
     {24, 7},
 };
-static arc arcs_74_5[1] = {
+static arc arcs_73_5[1] = {
     {15, 6},
 };
-static arc arcs_74_6[1] = {
+static arc arcs_73_6[1] = {
     {23, 4},
 };
-static arc arcs_74_7[1] = {
+static arc arcs_73_7[1] = {
     {0, 7},
 };
-static state states_74[8] = {
-    {1, arcs_74_0},
-    {1, arcs_74_1},
-    {2, arcs_74_2},
-    {2, arcs_74_3},
-    {1, arcs_74_4},
-    {1, arcs_74_5},
-    {1, arcs_74_6},
-    {1, arcs_74_7},
+static state states_73[8] = {
+    {1, arcs_73_0},
+    {1, arcs_73_1},
+    {2, arcs_73_2},
+    {2, arcs_73_3},
+    {1, arcs_73_4},
+    {1, arcs_73_5},
+    {1, arcs_73_6},
+    {1, arcs_73_7},
 };
-static arc arcs_75_0[3] = {
-    {163, 1},
+static arc arcs_74_0[3] = {
+    {162, 1},
     {30, 2},
     {31, 3},
 };
-static arc arcs_75_1[2] = {
+static arc arcs_74_1[2] = {
     {29, 4},
     {0, 1},
 };
-static arc arcs_75_2[1] = {
+static arc arcs_74_2[1] = {
     {28, 5},
 };
-static arc arcs_75_3[1] = {
+static arc arcs_74_3[1] = {
     {28, 6},
 };
-static arc arcs_75_4[4] = {
-    {163, 1},
+static arc arcs_74_4[4] = {
+    {162, 1},
     {30, 2},
     {31, 3},
     {0, 4},
 };
-static arc arcs_75_5[2] = {
+static arc arcs_74_5[2] = {
     {29, 7},
     {0, 5},
 };
-static arc arcs_75_6[1] = {
+static arc arcs_74_6[1] = {
     {0, 6},
 };
-static arc arcs_75_7[2] = {
-    {163, 5},
+static arc arcs_74_7[2] = {
+    {162, 5},
     {31, 3},
 };
-static state states_75[8] = {
-    {3, arcs_75_0},
-    {2, arcs_75_1},
-    {1, arcs_75_2},
-    {1, arcs_75_3},
-    {4, arcs_75_4},
-    {2, arcs_75_5},
-    {1, arcs_75_6},
-    {2, arcs_75_7},
+static state states_74[8] = {
+    {3, arcs_74_0},
+    {2, arcs_74_1},
+    {1, arcs_74_2},
+    {1, arcs_74_3},
+    {4, arcs_74_4},
+    {2, arcs_74_5},
+    {1, arcs_74_6},
+    {2, arcs_74_7},
 };
-static arc arcs_76_0[1] = {
+static arc arcs_75_0[1] = {
     {28, 1},
 };
-static arc arcs_76_1[3] = {
+static arc arcs_75_1[3] = {
     {157, 2},
     {27, 3},
     {0, 1},
 };
-static arc arcs_76_2[1] = {
+static arc arcs_75_2[1] = {
     {0, 2},
 };
-static arc arcs_76_3[1] = {
+static arc arcs_75_3[1] = {
     {28, 2},
 };
-static state states_76[4] = {
-    {1, arcs_76_0},
-    {3, arcs_76_1},
-    {1, arcs_76_2},
-    {1, arcs_76_3},
+static state states_75[4] = {
+    {1, arcs_75_0},
+    {3, arcs_75_1},
+    {1, arcs_75_2},
+    {1, arcs_75_3},
 };
-static arc arcs_77_0[2] = {
+static arc arcs_76_0[2] = {
     {156, 1},
-    {165, 1},
+    {164, 1},
 };
-static arc arcs_77_1[1] = {
+static arc arcs_76_1[1] = {
     {0, 1},
 };
-static state states_77[2] = {
-    {2, arcs_77_0},
-    {1, arcs_77_1},
+static state states_76[2] = {
+    {2, arcs_76_0},
+    {1, arcs_76_1},
 };
-static arc arcs_78_0[1] = {
+static arc arcs_77_0[1] = {
     {96, 1},
 };
-static arc arcs_78_1[1] = {
+static arc arcs_77_1[1] = {
     {61, 2},
 };
-static arc arcs_78_2[1] = {
+static arc arcs_77_2[1] = {
     {85, 3},
 };
-static arc arcs_78_3[1] = {
+static arc arcs_77_3[1] = {
     {105, 4},
 };
-static arc arcs_78_4[2] = {
-    {164, 5},
+static arc arcs_77_4[2] = {
+    {163, 5},
     {0, 4},
 };
-static arc arcs_78_5[1] = {
+static arc arcs_77_5[1] = {
     {0, 5},
 };
-static state states_78[6] = {
-    {1, arcs_78_0},
-    {1, arcs_78_1},
-    {1, arcs_78_2},
-    {1, arcs_78_3},
-    {2, arcs_78_4},
-    {1, arcs_78_5},
+static state states_77[6] = {
+    {1, arcs_77_0},
+    {1, arcs_77_1},
+    {1, arcs_77_2},
+    {1, arcs_77_3},
+    {2, arcs_77_4},
+    {1, arcs_77_5},
 };
-static arc arcs_79_0[1] = {
+static arc arcs_78_0[1] = {
     {92, 1},
 };
-static arc arcs_79_1[1] = {
+static arc arcs_78_1[1] = {
     {106, 2},
 };
-static arc arcs_79_2[2] = {
-    {164, 3},
+static arc arcs_78_2[2] = {
+    {163, 3},
     {0, 2},
 };
-static arc arcs_79_3[1] = {
+static arc arcs_78_3[1] = {
     {0, 3},
 };
-static state states_79[4] = {
-    {1, arcs_79_0},
-    {1, arcs_79_1},
-    {2, arcs_79_2},
-    {1, arcs_79_3},
+static state states_78[4] = {
+    {1, arcs_78_0},
+    {1, arcs_78_1},
+    {2, arcs_78_2},
+    {1, arcs_78_3},
 };
-static arc arcs_80_0[2] = {
+static arc arcs_79_0[2] = {
     {157, 1},
-    {167, 1},
+    {166, 1},
 };
-static arc arcs_80_1[1] = {
+static arc arcs_79_1[1] = {
     {0, 1},
 };
-static state states_80[2] = {
-    {2, arcs_80_0},
-    {1, arcs_80_1},
+static state states_79[2] = {
+    {2, arcs_79_0},
+    {1, arcs_79_1},
 };
-static arc arcs_81_0[1] = {
+static arc arcs_80_0[1] = {
     {96, 1},
 };
-static arc arcs_81_1[1] = {
+static arc arcs_80_1[1] = {
     {61, 2},
 };
-static arc arcs_81_2[1] = {
+static arc arcs_80_2[1] = {
     {85, 3},
 };
-static arc arcs_81_3[1] = {
+static arc arcs_80_3[1] = {
     {107, 4},
 };
-static arc arcs_81_4[2] = {
-    {166, 5},
+static arc arcs_80_4[2] = {
+    {165, 5},
     {0, 4},
 };
-static arc arcs_81_5[1] = {
+static arc arcs_80_5[1] = {
     {0, 5},
 };
-static state states_81[6] = {
-    {1, arcs_81_0},
-    {1, arcs_81_1},
-    {1, arcs_81_2},
-    {1, arcs_81_3},
-    {2, arcs_81_4},
-    {1, arcs_81_5},
+static state states_80[6] = {
+    {1, arcs_80_0},
+    {1, arcs_80_1},
+    {1, arcs_80_2},
+    {1, arcs_80_3},
+    {2, arcs_80_4},
+    {1, arcs_80_5},
 };
-static arc arcs_82_0[1] = {
+static arc arcs_81_0[1] = {
     {92, 1},
 };
-static arc arcs_82_1[1] = {
+static arc arcs_81_1[1] = {
     {106, 2},
 };
-static arc arcs_82_2[2] = {
-    {166, 3},
+static arc arcs_81_2[2] = {
+    {165, 3},
     {0, 2},
 };
-static arc arcs_82_3[1] = {
+static arc arcs_81_3[1] = {
     {0, 3},
 };
-static state states_82[4] = {
-    {1, arcs_82_0},
-    {1, arcs_82_1},
-    {2, arcs_82_2},
-    {1, arcs_82_3},
+static state states_81[4] = {
+    {1, arcs_81_0},
+    {1, arcs_81_1},
+    {2, arcs_81_2},
+    {1, arcs_81_3},
 };
-static arc arcs_83_0[1] = {
+static arc arcs_82_0[1] = {
     {28, 1},
 };
-static arc arcs_83_1[2] = {
+static arc arcs_82_1[2] = {
     {29, 0},
     {0, 1},
 };
-static state states_83[2] = {
-    {1, arcs_83_0},
-    {2, arcs_83_1},
+static state states_82[2] = {
+    {1, arcs_82_0},
+    {2, arcs_82_1},
 };
-static arc arcs_84_0[1] = {
+static arc arcs_83_0[1] = {
     {21, 1},
 };
-static arc arcs_84_1[1] = {
+static arc arcs_83_1[1] = {
     {0, 1},
 };
-static state states_84[2] = {
-    {1, arcs_84_0},
-    {1, arcs_84_1},
+static state states_83[2] = {
+    {1, arcs_83_0},
+    {1, arcs_83_1},
 };
-static arc arcs_85_0[1] = {
-    {169, 1},
+static arc arcs_84_0[1] = {
+    {168, 1},
 };
-static arc arcs_85_1[2] = {
+static arc arcs_84_1[2] = {
     {9, 2},
     {0, 1},
 };
-static arc arcs_85_2[1] = {
+static arc arcs_84_2[1] = {
     {0, 2},
 };
-static state states_85[3] = {
-    {1, arcs_85_0},
-    {2, arcs_85_1},
-    {1, arcs_85_2},
+static state states_84[3] = {
+    {1, arcs_84_0},
+    {2, arcs_84_1},
+    {1, arcs_84_2},
 };
-static dfa dfas[86] = {
+static dfa dfas[85] = {
     {256, "single_input", 0, 3, states_0,
-     "\004\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\004\002"},
+     "\004\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\002\001"},
     {257, "file_input", 0, 2, states_1,
-     "\204\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\004\002"},
+     "\204\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\002\001"},
     {258, "eval_input", 0, 3, states_2,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
     {259, "decorator", 0, 7, states_3,
@@ -1874,11 +1850,11 @@
     {266, "fplist", 0, 3, states_10,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
     {267, "stmt", 0, 2, states_11,
-     "\000\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\004\002"},
+     "\000\050\060\000\000\000\000\124\360\024\114\220\023\040\010\000\200\041\044\015\002\001"},
     {268, "simple_stmt", 0, 4, states_12,
-     "\000\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\002"},
+     "\000\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\001"},
     {269, "small_stmt", 0, 2, states_13,
-     "\000\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\002"},
+     "\000\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\001"},
     {270, "expr_stmt", 0, 6, states_14,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
     {271, "augassign", 0, 2, states_15,
@@ -1890,7 +1866,7 @@
     {274, "pass_stmt", 0, 2, states_18,
      "\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
     {275, "flow_stmt", 0, 2, states_19,
-     "\000\000\000\000\000\000\000\000\360\000\000\000\000\000\000\000\000\000\000\000\000\002"},
+     "\000\000\000\000\000\000\000\000\360\000\000\000\000\000\000\000\000\000\000\000\000\001"},
     {276, "break_stmt", 0, 2, states_20,
      "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000"},
     {277, "continue_stmt", 0, 2, states_21,
@@ -1898,7 +1874,7 @@
     {278, "return_stmt", 0, 3, states_22,
      "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000"},
     {279, "yield_stmt", 0, 2, states_23,
-     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"},
+     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"},
     {280, "raise_stmt", 0, 7, states_24,
      "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"},
     {281, "import_stmt", 0, 2, states_25,
@@ -1924,7 +1900,7 @@
     {291, "assert_stmt", 0, 5, states_35,
      "\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"},
     {292, "compound_stmt", 0, 2, states_36,
-     "\000\010\020\000\000\000\000\000\000\000\000\220\023\000\000\000\000\000\000\000\004\000"},
+     "\000\010\020\000\000\000\000\000\000\000\000\220\023\000\000\000\000\000\000\000\002\000"},
     {293, "if_stmt", 0, 8, states_37,
      "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
     {294, "while_stmt", 0, 8, states_38,
@@ -1940,7 +1916,7 @@
     {299, "except_clause", 0, 5, states_43,
      "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
     {300, "suite", 0, 5, states_44,
-     "\004\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\002"},
+     "\004\040\040\000\000\000\000\124\360\024\114\000\000\040\010\000\200\041\044\015\000\001"},
     {301, "testlist_safe", 0, 5, states_45,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
     {302, "old_test", 0, 2, states_46,
@@ -1995,36 +1971,34 @@
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\000\000\000\200\041\044\015\000\000"},
     {327, "testlist", 0, 3, states_71,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {328, "dictmaker", 0, 5, states_72,
+    {328, "dictorsetmaker", 0, 11, states_72,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {329, "dictorsetmaker", 0, 11, states_73,
-     "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {330, "classdef", 0, 8, states_74,
-     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"},
-    {331, "arglist", 0, 8, states_75,
+    {329, "classdef", 0, 8, states_73,
+     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000"},
+    {330, "arglist", 0, 8, states_74,
      "\000\040\040\300\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {332, "argument", 0, 4, states_76,
+    {331, "argument", 0, 4, states_75,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {333, "list_iter", 0, 2, states_77,
+    {332, "list_iter", 0, 2, states_76,
      "\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"},
-    {334, "list_for", 0, 6, states_78,
+    {333, "list_for", 0, 6, states_77,
      "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"},
-    {335, "list_if", 0, 4, states_79,
+    {334, "list_if", 0, 4, states_78,
      "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
-    {336, "comp_iter", 0, 2, states_80,
+    {335, "comp_iter", 0, 2, states_79,
      "\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"},
-    {337, "comp_for", 0, 6, states_81,
+    {336, "comp_for", 0, 6, states_80,
      "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"},
-    {338, "comp_if", 0, 4, states_82,
+    {337, "comp_if", 0, 4, states_81,
      "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
-    {339, "testlist1", 0, 2, states_83,
+    {338, "testlist1", 0, 2, states_82,
      "\000\040\040\000\000\000\000\000\000\000\000\000\000\040\010\000\200\041\044\015\000\000"},
-    {340, "encoding_decl", 0, 2, states_84,
+    {339, "encoding_decl", 0, 2, states_83,
      "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
-    {341, "yield_expr", 0, 3, states_85,
-     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"},
+    {340, "yield_expr", 0, 3, states_84,
+     "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"},
 };
-static label labels[170] = {
+static label labels[169] = {
     {0, "EMPTY"},
     {256, 0},
     {4, 0},
@@ -2039,11 +2013,11 @@
     {50, 0},
     {288, 0},
     {7, 0},
-    {331, 0},
+    {330, 0},
     {8, 0},
     {260, 0},
     {261, 0},
-    {330, 0},
+    {329, 0},
     {262, 0},
     {1, "def"},
     {1, 0},
@@ -2070,7 +2044,7 @@
     {290, 0},
     {291, 0},
     {271, 0},
-    {341, 0},
+    {340, 0},
     {37, 0},
     {38, 0},
     {39, 0},
@@ -2175,30 +2149,29 @@
     {319, 0},
     {10, 0},
     {26, 0},
-    {329, 0},
+    {328, 0},
     {27, 0},
     {25, 0},
-    {339, 0},
+    {338, 0},
     {2, 0},
     {3, 0},
-    {334, 0},
-    {337, 0},
+    {333, 0},
+    {336, 0},
     {323, 0},
     {324, 0},
     {325, 0},
-    {328, 0},
     {1, "class"},
+    {331, 0},
     {332, 0},
-    {333, 0},
+    {334, 0},
     {335, 0},
-    {336, 0},
-    {338, 0},
-    {340, 0},
+    {337, 0},
+    {339, 0},
     {1, "yield"},
 };
 grammar _PyParser_Grammar = {
-    86,
+    85,
     dfas,
-    {170, labels},
+    {169, labels},
     256
 };

From python-checkins at python.org  Sat Dec 11 05:38:25 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Dec 2010 05:38:25 +0100 (CET)
Subject: [Python-checkins] r87168 -
	python/branches/release27-maint/Lib/symbol.py
Message-ID: <20101211043825.09459EE984@mail.python.org>

Author: benjamin.peterson
Date: Sat Dec 11 05:38:24 2010
New Revision: 87168

Log:
regenerate symbol.py

Modified:
   python/branches/release27-maint/Lib/symbol.py

Modified: python/branches/release27-maint/Lib/symbol.py
==============================================================================
--- python/branches/release27-maint/Lib/symbol.py	(original)
+++ python/branches/release27-maint/Lib/symbol.py	Sat Dec 11 05:38:24 2010
@@ -82,20 +82,19 @@
 sliceop = 325
 exprlist = 326
 testlist = 327
-dictmaker = 328
-dictorsetmaker = 329
-classdef = 330
-arglist = 331
-argument = 332
-list_iter = 333
-list_for = 334
-list_if = 335
-comp_iter = 336
-comp_for = 337
-comp_if = 338
-testlist1 = 339
-encoding_decl = 340
-yield_expr = 341
+dictorsetmaker = 328
+classdef = 329
+arglist = 330
+argument = 331
+list_iter = 332
+list_for = 333
+list_if = 334
+comp_iter = 335
+comp_for = 336
+comp_if = 337
+testlist1 = 338
+encoding_decl = 339
+yield_expr = 340
 #--end constants--
 
 sym_name = {}

From ncoghlan at gmail.com  Sat Dec 11 06:38:52 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Sat, 11 Dec 2010 15:38:52 +1000
Subject: [Python-checkins] r87162 -
	python/branches/release27-maint/Doc/library/stdtypes.rst
In-Reply-To: <20101211004102.E773DEE98A@mail.python.org>
References: <20101211004102.E773DEE98A@mail.python.org>
Message-ID: 

On Sat, Dec 11, 2010 at 10:41 AM, raymond.hettinger
 wrote:
> Author: raymond.hettinger
> Date: Sat Dec 11 01:41:02 2010
> New Revision: 87162
>
> Log:
> Issue 2690: ?Doc fixup. ?xrange() objects are slicable.
>
>
> Modified:
> ? python/branches/release27-maint/Doc/library/stdtypes.rst

Are you sure about that one?

Python 2.7.0+ (trunk:86033, Nov  1 2010, 00:42:57)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> xrange(10)[1:2]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: sequence index must be integer, not 'slice'

Cheers,
Nick.

-- 
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From python-checkins at python.org  Sat Dec 11 09:10:37 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Dec 2010 09:10:37 +0100 (CET)
Subject: [Python-checkins] r87169 -
	python/branches/release27-maint/Doc/library/stdtypes.rst
Message-ID: <20101211081037.6CA29EA5E@mail.python.org>

Author: georg.brandl
Date: Sat Dec 11 09:10:37 2010
New Revision: 87169

Log:
#10676: fix bad wording in parallel with the lang ref.

Modified:
   python/branches/release27-maint/Doc/library/stdtypes.rst

Modified: python/branches/release27-maint/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/stdtypes.rst	(original)
+++ python/branches/release27-maint/Doc/library/stdtypes.rst	Sat Dec 11 09:10:37 2010
@@ -360,10 +360,10 @@
    See :ref:`built-in-funcs` for a full description.
 
 (4)
-   Complex floor division operator, modulo operator, and :func:`divmod`.
-
    .. deprecated:: 2.3
-      Instead convert to float using :func:`abs` if appropriate.
+      The floor division operator, the modulo operator, and the :func:`divmod`
+      function are no longer defined for complex numbers.  Instead, convert to
+      a floating point number using the :func:`abs` function if appropriate.
 
 (5)
    Also referred to as integer division.  The resultant value is a whole integer,

From python-checkins at python.org  Sat Dec 11 16:56:33 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Dec 2010 16:56:33 +0100 (CET)
Subject: [Python-checkins] r87170 - peps/trunk/pep-3143.txt
Message-ID: <20101211155633.92625EE982@mail.python.org>

Author: georg.brandl
Date: Sat Dec 11 16:56:33 2010
New Revision: 87170

Log:
Update target version.

Modified:
   peps/trunk/pep-3143.txt

Modified: peps/trunk/pep-3143.txt
==============================================================================
--- peps/trunk/pep-3143.txt	(original)
+++ peps/trunk/pep-3143.txt	Sat Dec 11 16:56:33 2010
@@ -7,7 +7,7 @@
 Type:              Standards Track
 Content-Type:      text/x-rst
 Created:           2009-01-26
-Python-Version:    3.2
+Python-Version:    3.x
 Post-History:
 
 

From python-checkins at python.org  Sat Dec 11 19:17:22 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat, 11 Dec 2010 19:17:22 +0100 (CET)
Subject: [Python-checkins] r87171 - python/branches/py3k/Doc/c-api/slice.rst
Message-ID: <20101211181722.35C25EE982@mail.python.org>

Author: martin.v.loewis
Date: Sat Dec 11 19:17:22 2010
New Revision: 87171

Log:
Adjust PySlice_GetIndices documentation to signature change.


Modified:
   python/branches/py3k/Doc/c-api/slice.rst

Modified: python/branches/py3k/Doc/c-api/slice.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/slice.rst	(original)
+++ python/branches/py3k/Doc/c-api/slice.rst	Sat Dec 11 19:17:22 2010
@@ -26,7 +26,7 @@
    the new object could not be allocated.
 
 
-.. c:function:: int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
+.. c:function:: int PySlice_GetIndices(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
 
    Retrieve the start, stop and step indices from the slice object *slice*,
    assuming a sequence of length *length*. Treats indices greater than
@@ -39,7 +39,7 @@
    You probably do not want to use this function.
 
 
-.. c:function:: int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+.. c:function:: int PySlice_GetIndicesEx(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
 
    Usable replacement for :c:func:`PySlice_GetIndices`.  Retrieve the start,
    stop, and step indices from the slice object *slice* assuming a sequence of

From python-checkins at python.org  Sat Dec 11 20:10:31 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Dec 2010 20:10:31 +0100 (CET)
Subject: [Python-checkins] r87172 - python/branches/py3k/Lib/tempfile.py
Message-ID: <20101211191031.22F40EE992@mail.python.org>

Author: georg.brandl
Date: Sat Dec 11 20:10:30 2010
New Revision: 87172

Log:
Avoid AttributeError(_closed) when a TemporaryDirectory is deallocated whose mkdtemp call failed.

Modified:
   python/branches/py3k/Lib/tempfile.py

Modified: python/branches/py3k/Lib/tempfile.py
==============================================================================
--- python/branches/py3k/Lib/tempfile.py	(original)
+++ python/branches/py3k/Lib/tempfile.py	Sat Dec 11 20:10:30 2010
@@ -617,6 +617,8 @@
     """
 
     def __init__(self, suffix="", prefix=template, dir=None):
+        # cleanup() needs this and is called even when mkdtemp fails
+        self._closed = True
         self.name = mkdtemp(suffix, prefix, dir)
         self._closed = False
 

From python-checkins at python.org  Sat Dec 11 20:22:05 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat, 11 Dec 2010 20:22:05 +0100 (CET)
Subject: [Python-checkins] r87173 - python/branches/py3k/Doc/c-api/slice.rst
Message-ID: <20101211192205.25BA4EE9AB@mail.python.org>

Author: martin.v.loewis
Date: Sat Dec 11 20:22:04 2010
New Revision: 87173

Log:
Add versionchanged for parameter type changes.


Modified:
   python/branches/py3k/Doc/c-api/slice.rst

Modified: python/branches/py3k/Doc/c-api/slice.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/slice.rst	(original)
+++ python/branches/py3k/Doc/c-api/slice.rst	Sat Dec 11 20:22:04 2010
@@ -38,6 +38,9 @@
 
    You probably do not want to use this function.
 
+   .. versionchanged:: 3.2
+      The parameter type for the *slice* parameter was PySliceObject* before.
+
 
 .. c:function:: int PySlice_GetIndicesEx(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
 
@@ -49,3 +52,5 @@
 
    Returns 0 on success and -1 on error with exception set.
 
+   .. versionchanged:: 3.2
+      The parameter type for the *slice* parameter was PySliceObject* before.

From python-checkins at python.org  Sat Dec 11 22:32:01 2010
From: python-checkins at python.org (barry.warsaw)
Date: Sat, 11 Dec 2010 22:32:01 +0100 (CET)
Subject: [Python-checkins] r87174 - python/branches/py3k/Makefile.pre.in
Message-ID: <20101211213201.78287EE27@mail.python.org>

Author: barry.warsaw
Date: Sat Dec 11 22:32:01 2010
New Revision: 87174

Log:
Create the hardlink between python-3.2m and python-3.2 in altbininstall target
instead of bininstall target so it shows up when you do 'make altinstall'.
Closes issue 10677.


Modified:
   python/branches/py3k/Makefile.pre.in

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Sat Dec 11 22:32:01 2010
@@ -836,6 +836,11 @@
 		fi; \
 	done
 	$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE)
+	-if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE); \
+	then rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \
+	else true; \
+	fi
+	(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE))
 	if test -f $(LDLIBRARY); then \
 		if test -n "$(DLLLIBRARY)" ; then \
 			$(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \
@@ -853,11 +858,6 @@
 	then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON)3$(EXE); \
 	else true; \
 	fi
-	-if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE); \
-	then rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \
-	else true; \
-	fi
-	(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE))
 	(cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3$(EXE))
 	-rm -f $(DESTDIR)$(BINDIR)/python3-config
 	-rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-config

From python-checkins at python.org  Sat Dec 11 23:19:35 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Dec 2010 23:19:35 +0100 (CET)
Subject: [Python-checkins] r87175 - python/branches/py3k/Doc/c-api/slice.rst
Message-ID: <20101211221935.1C67CEE99A@mail.python.org>

Author: georg.brandl
Date: Sat Dec 11 23:19:34 2010
New Revision: 87175

Log:
Fix markup.

Modified:
   python/branches/py3k/Doc/c-api/slice.rst

Modified: python/branches/py3k/Doc/c-api/slice.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/slice.rst	(original)
+++ python/branches/py3k/Doc/c-api/slice.rst	Sat Dec 11 23:19:34 2010
@@ -39,7 +39,8 @@
    You probably do not want to use this function.
 
    .. versionchanged:: 3.2
-      The parameter type for the *slice* parameter was PySliceObject* before.
+      The parameter type for the *slice* parameter was ``PySliceObject*``
+      before.
 
 
 .. c:function:: int PySlice_GetIndicesEx(PyObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
@@ -53,4 +54,5 @@
    Returns 0 on success and -1 on error with exception set.
 
    .. versionchanged:: 3.2
-      The parameter type for the *slice* parameter was PySliceObject* before.
+      The parameter type for the *slice* parameter was ``PySliceObject*``
+      before.

From python-checkins at python.org  Sun Dec 12 02:33:05 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Dec 2010 02:33:05 +0100 (CET)
Subject: [Python-checkins] r87176 - in python/branches/py3k:
	Doc/library/codecs.rst Doc/library/stdtypes.rst
	Doc/whatsnew/3.2.rst Lib/test/test_bytes.py
	Lib/test/test_codecs.py Misc/NEWS Objects/bytearrayobject.c
	Objects/bytesobject.c Objects/unicodeobject.c
Message-ID: <20101212013305.33A83EE98A@mail.python.org>

Author: benjamin.peterson
Date: Sun Dec 12 02:33:04 2010
New Revision: 87176

Log:
remove (un)transform methods

Modified:
   python/branches/py3k/Doc/library/codecs.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/whatsnew/3.2.rst
   python/branches/py3k/Lib/test/test_bytes.py
   python/branches/py3k/Lib/test/test_codecs.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/bytearrayobject.c
   python/branches/py3k/Objects/bytesobject.c
   python/branches/py3k/Objects/unicodeobject.c

Modified: python/branches/py3k/Doc/library/codecs.rst
==============================================================================
--- python/branches/py3k/Doc/library/codecs.rst	(original)
+++ python/branches/py3k/Doc/library/codecs.rst	Sun Dec 12 02:33:04 2010
@@ -1165,8 +1165,7 @@
 |                    |         | operand                   |
 +--------------------+---------+---------------------------+
 
-The following codecs provide bytes-to-bytes mappings.  They can be used with
-:meth:`bytes.transform` and :meth:`bytes.untransform`.
+The following codecs provide bytes-to-bytes mappings.
 
 +--------------------+---------------------------+---------------------------+
 | Codec              | Aliases                   | Purpose                   |
@@ -1192,8 +1191,7 @@
 |                    |                           | using gzip                |
 +--------------------+---------------------------+---------------------------+
 
-The following codecs provide string-to-string mappings.  They can be used with
-:meth:`str.transform` and :meth:`str.untransform`.
+The following codecs provide string-to-string mappings.
 
 +--------------------+---------------------------+---------------------------+
 | Codec              | Aliases                   | Purpose                   |

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Sun Dec 12 02:33:04 2010
@@ -1352,19 +1352,6 @@
         "They're Bill's Friends."
 
 
-.. method:: str.transform(encoding, errors='strict')
-
-   Return an encoded version of the string.  In contrast to :meth:`encode`, this
-   method works with codecs that provide string-to-string mappings, and not
-   string-to-bytes mappings.  :meth:`transform` therefore returns a string
-   object.
-
-   The codecs that can be used with this method are listed in
-   :ref:`standard-encodings`.
-
-   .. versionadded:: 3.2
-
-
 .. method:: str.translate(map)
 
    Return a copy of the *s* where all characters have been mapped through the
@@ -1382,14 +1369,6 @@
       example).
 
 
-.. method:: str.untransform(encoding, errors='strict')
-
-   Return a decoded version of the string.  This provides the reverse operation
-   of :meth:`transform`.
-
-   .. versionadded:: 3.2
-
-
 .. method:: str.upper()
 
    Return a copy of the string converted to uppercase.
@@ -1821,20 +1800,6 @@
 The maketrans and translate methods differ in semantics from the versions
 available on strings:
 
-.. method:: bytes.transform(encoding, errors='strict')
-            bytearray.transform(encoding, errors='strict')
-
-   Return an encoded version of the bytes object.  In contrast to
-   :meth:`encode`, this method works with codecs that provide bytes-to-bytes
-   mappings, and not string-to-bytes mappings.  :meth:`transform` therefore
-   returns a bytes or bytearray object.
-
-   The codecs that can be used with this method are listed in
-   :ref:`standard-encodings`.
-
-   .. versionadded:: 3.2
-
-
 .. method:: bytes.translate(table[, delete])
             bytearray.translate(table[, delete])
 
@@ -1852,15 +1817,6 @@
       b'rd ths shrt txt'
 
 
-.. method:: bytes.untransform(encoding, errors='strict')
-            bytearray.untransform(encoding, errors='strict')
-
-   Return an decoded version of the bytes object.  This provides the reverse
-   operation of :meth:`transform`.
-
-   .. versionadded:: 3.2
-
-
 .. staticmethod:: bytes.maketrans(from, to)
                   bytearray.maketrans(from, to)
 

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Sun Dec 12 02:33:04 2010
@@ -406,26 +406,6 @@
 
 Some smaller changes made to the core Python language are:
 
-* :class:`bytes` and :class:`str` now have two net methods, *transform* and
-  *untransform*.  These provide analogues to *encode* and *decode* but are used
-  for general purpose str-to-str and bytes-to-bytes transformations rather than
-  Unicode codecs for bytes-to-str and str-to-bytes.
-
-  Along with the new methods, several non-unicode codecs been restored from Python 2.x
-  including *base64*, *bz2*, *hex*, *quopri*, *rot13*, *uu*, and *zlib*.
-
-  >>> t = b'which witch had which witches wrist watch'
-  >>> t.transform('quopri')
-  b'which=20witch=20had=20which=20witches=20wrist=20watch'
-
-  >>> short = t.transform('zlib_codec')
-  >>> len(t), len(short)
-  (41, 38)
-  >>> short.untransform('zlib_codec')
-  b'which witch had which witches wrist watch'
-
-  (From multiple contributors in :issue:`7475`.)
-
 * String formatting for :func:`format` and :meth:`str.format` gained new
   capabilities for the format character **#**.  Previously, for integers in
   binary, octal, or hexadecimal, it caused the output to be prefixed with '0b',

Modified: python/branches/py3k/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bytes.py	(original)
+++ python/branches/py3k/Lib/test/test_bytes.py	Sun Dec 12 02:33:04 2010
@@ -207,11 +207,6 @@
         self.assertEqual(b.decode(errors="ignore", encoding="utf8"),
                          "Hello world\n")
 
-    def test_transform(self):
-        b1 = self.type2test(range(256))
-        b2 = b1.transform("base64").untransform("base64")
-        self.assertEqual(b2, b1)
-
     def test_from_int(self):
         b = self.type2test(0)
         self.assertEqual(b, self.type2test())

Modified: python/branches/py3k/Lib/test/test_codecs.py
==============================================================================
--- python/branches/py3k/Lib/test/test_codecs.py	(original)
+++ python/branches/py3k/Lib/test/test_codecs.py	Sun Dec 12 02:33:04 2010
@@ -1691,9 +1691,9 @@
     bytes_transform_encodings.append("bz2_codec")
 
 class TransformCodecTest(unittest.TestCase):
+
     def test_basics(self):
         binput = bytes(range(256))
-        ainput = bytearray(binput)
         for encoding in bytes_transform_encodings:
             # generic codecs interface
             (o, size) = codecs.getencoder(encoding)(binput)
@@ -1702,22 +1702,9 @@
             self.assertEqual(size, len(o))
             self.assertEqual(i, binput)
 
-            # transform interface
-            boutput = binput.transform(encoding)
-            aoutput = ainput.transform(encoding)
-            self.assertEqual(boutput, aoutput)
-            self.assertIsInstance(boutput, bytes)
-            self.assertIsInstance(aoutput, bytearray)
-            bback = boutput.untransform(encoding)
-            aback = aoutput.untransform(encoding)
-            self.assertEqual(bback, aback)
-            self.assertEqual(bback, binput)
-            self.assertIsInstance(bback, bytes)
-            self.assertIsInstance(aback, bytearray)
-
     def test_read(self):
         for encoding in bytes_transform_encodings:
-            sin = b"\x80".transform(encoding)
+            sin = codecs.encode(b"\x80", encoding)
             reader = codecs.getreader(encoding)(io.BytesIO(sin))
             sout = reader.read()
             self.assertEqual(sout, b"\x80")
@@ -1726,7 +1713,7 @@
         for encoding in bytes_transform_encodings:
             if encoding in ['uu_codec', 'zlib_codec']:
                 continue
-            sin = b"\x80".transform(encoding)
+            sin = codecs.encode(b"\x80", encoding)
             reader = codecs.getreader(encoding)(io.BytesIO(sin))
             sout = reader.readline()
             self.assertEqual(sout, b"\x80")

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sun Dec 12 02:33:04 2010
@@ -42,10 +42,6 @@
 
 - Issue #9915: Speed up sorting with a key.
 
-- Issue #7475: Added transform() and untransform() methods to both bytes and
-  string types.  They can be used to access those codecs providing
-  bytes-to-bytes and string-to-string mappings.
-
 - Issue #8685: Speed up set difference ``a - b`` when source set ``a`` is much
   larger than operand ``b``.  Patch by Andrew Bennetts.
 

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c	(original)
+++ python/branches/py3k/Objects/bytearrayobject.c	Sun Dec 12 02:33:04 2010
@@ -2488,75 +2488,6 @@
     return PyUnicode_FromEncodedObject(self, encoding, errors);
 }
 
-PyDoc_STRVAR(transform__doc__,
-"B.transform(encoding, errors='strict') -> bytearray\n\
-\n\
-Transform B using the codec registered for encoding. errors may be given\n\
-to set a different error handling scheme.");
-
-static PyObject *
-bytearray_transform(PyObject *self, PyObject *args, PyObject *kwargs)
-{
-    const char *encoding = NULL;
-    const char *errors = NULL;
-    static char *kwlist[] = {"encoding", "errors", 0};
-    PyObject *v, *w;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-
-    v = PyCodec_Encode(self, encoding, errors);
-    if (v == NULL)
-        return NULL;
-    if (!PyBytes_Check(v)) {
-        PyErr_Format(PyExc_TypeError,
-                     "encoder did not return a bytes object (type=%.400s)",
-                     Py_TYPE(v)->tp_name);
-        Py_DECREF(v);
-        return NULL;
-    }
-    w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v),
-                                      PyBytes_GET_SIZE(v));
-    Py_DECREF(v);
-    return w;
-}
-
-
-PyDoc_STRVAR(untransform__doc__,
-"B.untransform(encoding, errors='strict') -> bytearray\n\
-\n\
-Reverse-transform B using the codec registered for encoding. errors may\n\
-be given to set a different error handling scheme.");
-
-static PyObject *
-bytearray_untransform(PyObject *self, PyObject *args, PyObject *kwargs)
-{
-    const char *encoding = NULL;
-    const char *errors = NULL;
-    static char *kwlist[] = {"encoding", "errors", 0};
-    PyObject *v, *w;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-
-    v = PyCodec_Decode(self, encoding, errors);
-    if (v == NULL)
-        return NULL;
-    if (!PyBytes_Check(v)) {
-        PyErr_Format(PyExc_TypeError,
-                     "decoder did not return a bytes object (type=%.400s)",
-                     Py_TYPE(v)->tp_name);
-        Py_DECREF(v);
-        return NULL;
-    }
-    w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v),
-                                      PyBytes_GET_SIZE(v));
-    Py_DECREF(v);
-    return w;
-}
-
 PyDoc_STRVAR(alloc_doc,
 "B.__alloc__() -> int\n\
 \n\
@@ -2851,12 +2782,8 @@
     {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
      _Py_swapcase__doc__},
     {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
-    {"transform", (PyCFunction)bytearray_transform, METH_VARARGS | METH_KEYWORDS,
-     transform__doc__},
     {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
      translate__doc__},
-    {"untransform", (PyCFunction)bytearray_untransform, METH_VARARGS | METH_KEYWORDS,
-     untransform__doc__},
     {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
     {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
     {NULL}

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Sun Dec 12 02:33:04 2010
@@ -2312,68 +2312,6 @@
     return PyUnicode_FromEncodedObject(self, encoding, errors);
 }
 
-PyDoc_STRVAR(transform__doc__,
-"B.transform(encoding, errors='strict') -> bytes\n\
-\n\
-Transform B using the codec registered for encoding. errors may be given\n\
-to set a different error handling scheme.");
-
-static PyObject *
-bytes_transform(PyObject *self, PyObject *args, PyObject *kwargs)
-{
-    const char *encoding = NULL;
-    const char *errors = NULL;
-    static char *kwlist[] = {"encoding", "errors", 0};
-    PyObject *v;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-
-    v = PyCodec_Encode(self, encoding, errors);
-    if (v == NULL)
-        return NULL;
-    if (!PyBytes_Check(v)) {
-        PyErr_Format(PyExc_TypeError,
-                     "encoder did not return a bytes object (type=%.400s)",
-                     Py_TYPE(v)->tp_name);
-        Py_DECREF(v);
-        return NULL;
-    }
-    return v;
-}
-
-
-PyDoc_STRVAR(untransform__doc__,
-"B.untransform(encoding, errors='strict') -> bytes\n\
-\n\
-Reverse-transform B using the codec registered for encoding. errors may\n\
-be given to set a different error handling scheme.");
-
-static PyObject *
-bytes_untransform(PyObject *self, PyObject *args, PyObject *kwargs)
-{
-    const char *encoding = NULL;
-    const char *errors = NULL;
-    static char *kwlist[] = {"encoding", "errors", 0};
-    PyObject *v;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-
-    v = PyCodec_Decode(self, encoding, errors);
-    if (v == NULL)
-        return NULL;
-    if (!PyBytes_Check(v)) {
-        PyErr_Format(PyExc_TypeError,
-                     "decoder did not return a bytes object (type=%.400s)",
-                     Py_TYPE(v)->tp_name);
-        Py_DECREF(v);
-        return NULL;
-    }
-    return v;
-}
 
 PyDoc_STRVAR(splitlines__doc__,
 "B.splitlines([keepends]) -> list of lines\n\
@@ -2537,10 +2475,8 @@
     {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
      _Py_swapcase__doc__},
     {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
-    {"transform", (PyCFunction)bytes_transform, METH_VARARGS | METH_KEYWORDS, transform__doc__},
     {"translate", (PyCFunction)bytes_translate, METH_VARARGS,
      translate__doc__},
-    {"untransform", (PyCFunction)bytes_untransform, METH_VARARGS | METH_KEYWORDS, untransform__doc__},
     {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
     {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
     {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS,

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Sun Dec 12 02:33:04 2010
@@ -7455,44 +7455,6 @@
     return PyUnicode_AsEncodedString((PyObject *)self, encoding, errors);
 }
 
-PyDoc_STRVAR(transform__doc__,
-             "S.transform(encoding, errors='strict') -> str\n\
-\n\
-Transform S using the codec registered for encoding. errors may be given\n\
-to set a different error handling scheme.");
-
-static PyObject *
-unicode_transform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
-{
-    static char *kwlist[] = {"encoding", "errors", 0};
-    char *encoding = NULL;
-    char *errors = NULL;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-    return PyUnicode_AsEncodedUnicode((PyObject *)self, encoding, errors);
-}
-
-PyDoc_STRVAR(untransform__doc__,
-             "S.untransform(encoding, errors='strict') -> str\n\
-\n\
-Reverse-transform S using the codec registered for encoding. errors may be\n\
-given to set a different error handling scheme.");
-
-static PyObject *
-unicode_untransform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
-{
-    static char *kwlist[] = {"encoding", "errors", 0};
-    char *encoding = NULL;
-    char *errors = NULL;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform",
-                                     kwlist, &encoding, &errors))
-        return NULL;
-    return PyUnicode_AsDecodedUnicode((PyObject *)self, encoding, errors);
-}
-
 PyDoc_STRVAR(expandtabs__doc__,
              "S.expandtabs([tabsize]) -> str\n\
 \n\
@@ -9144,8 +9106,7 @@
     /* Order is according to common usage: often used methods should
        appear first, since lookup is done sequentially. */
 
-    {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS,
-     encode__doc__},
+    {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
     {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__},
     {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__},
     {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__},
@@ -9190,10 +9151,6 @@
     {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
     {"maketrans", (PyCFunction) unicode_maketrans,
      METH_VARARGS | METH_STATIC, maketrans__doc__},
-    {"transform", (PyCFunction) unicode_transform, METH_VARARGS | METH_KEYWORDS,
-     transform__doc__},
-    {"untransform", (PyCFunction) unicode_untransform, METH_VARARGS | METH_KEYWORDS,
-     untransform__doc__},
     {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
 #if 0
     {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},

From python-checkins at python.org  Sun Dec 12 02:46:43 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Dec 2010 02:46:43 +0100 (CET)
Subject: [Python-checkins] r87177 -
	python/branches/py3k/Lib/test/test_listcomps.py
Message-ID: <20101212014643.849D3EE98A@mail.python.org>

Author: benjamin.peterson
Date: Sun Dec 12 02:46:43 2010
New Revision: 87177

Log:
having three copies of the same test is surely a bit excessive

Modified:
   python/branches/py3k/Lib/test/test_listcomps.py

Modified: python/branches/py3k/Lib/test/test_listcomps.py
==============================================================================
--- python/branches/py3k/Lib/test/test_listcomps.py	(original)
+++ python/branches/py3k/Lib/test/test_listcomps.py	Sun Dec 12 02:46:43 2010
@@ -146,299 +146,3 @@
 
 if __name__ == "__main__":
     test_main(verbose=True)
-doctests = """
-########### Tests borrowed from or inspired by test_genexps.py ############
-
-Test simple loop with conditional
-
-    >>> sum([i*i for i in range(100) if i&1 == 1])
-    166650
-
-Test simple nesting
-
-    >>> [(i,j) for i in range(3) for j in range(4)]
-    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
-
-Test nesting with the inner expression dependent on the outer
-
-    >>> [(i,j) for i in range(4) for j in range(i)]
-    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
-
-Make sure the induction variable is not exposed
-
-    >>> i = 20
-    >>> sum([i*i for i in range(100)])
-    328350
-
-    >>> i
-    20
-
-Verify that syntax error's are raised for listcomps used as lvalues
-
-    >>> [y for y in (1,2)] = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-    >>> [y for y in (1,2)] += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-
-########### Tests borrowed from or inspired by test_generators.py ############
-
-Make a nested list comprehension that acts like range()
-
-    >>> def frange(n):
-    ...     return [i for i in range(n)]
-    >>> frange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Same again, only as a lambda expression instead of a function definition
-
-    >>> lrange = lambda n:  [i for i in range(n)]
-    >>> lrange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Generators can call other generators:
-
-    >>> def grange(n):
-    ...     for x in [i for i in range(n)]:
-    ...         yield x
-    >>> list(grange(5))
-    [0, 1, 2, 3, 4]
-
-
-Make sure that None is a valid return value
-
-    >>> [None for i in range(10)]
-    [None, None, None, None, None, None, None, None, None, None]
-
-########### Tests for various scoping corner cases ############
-
-Return lambdas that use the iteration variable as a default argument
-
-    >>> items = [(lambda i=i: i) for i in range(5)]
-    >>> [x() for x in items]
-    [0, 1, 2, 3, 4]
-
-Same again, only this time as a closure variable
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-Another way to test that the iteration variable is local to the list comp
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> i = 20
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-And confirm that a closure can jump over the list comp scope
-
-    >>> items = [(lambda: y) for i in range(5)]
-    >>> y = 2
-    >>> [x() for x in items]
-    [2, 2, 2, 2, 2]
-
-We also repeat each of the above scoping tests inside a function
-
-    >>> def test_func():
-    ...     items = [(lambda i=i: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [0, 1, 2, 3, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     i = 20
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: y) for i in range(5)]
-    ...     y = 2
-    ...     return [x() for x in items]
-    >>> test_func()
-    [2, 2, 2, 2, 2]
-
-"""
-
-
-__test__ = {'doctests' : doctests}
-
-def test_main(verbose=None):
-    import sys
-    from test import support
-    from test import test_listcomps
-    support.run_doctest(test_listcomps, verbose)
-
-    # verify reference counting
-    if verbose and hasattr(sys, "gettotalrefcount"):
-        import gc
-        counts = [None] * 5
-        for i in range(len(counts)):
-            support.run_doctest(test_genexps, verbose)
-            gc.collect()
-            counts[i] = sys.gettotalrefcount()
-        print(counts)
-
-if __name__ == "__main__":
-    test_main(verbose=True)
-doctests = """
-########### Tests borrowed from or inspired by test_genexps.py ############
-
-Test simple loop with conditional
-
-    >>> sum([i*i for i in range(100) if i&1 == 1])
-    166650
-
-Test simple nesting
-
-    >>> [(i,j) for i in range(3) for j in range(4)]
-    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
-
-Test nesting with the inner expression dependent on the outer
-
-    >>> [(i,j) for i in range(4) for j in range(i)]
-    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
-
-Make sure the induction variable is not exposed
-
-    >>> i = 20
-    >>> sum([i*i for i in range(100)])
-    328350
-
-    >>> i
-    20
-
-Verify that syntax error's are raised for listcomps used as lvalues
-
-    >>> [y for y in (1,2)] = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-    >>> [y for y in (1,2)] += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-
-########### Tests borrowed from or inspired by test_generators.py ############
-
-Make a nested list comprehension that acts like range()
-
-    >>> def frange(n):
-    ...     return [i for i in range(n)]
-    >>> frange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Same again, only as a lambda expression instead of a function definition
-
-    >>> lrange = lambda n:  [i for i in range(n)]
-    >>> lrange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Generators can call other generators:
-
-    >>> def grange(n):
-    ...     for x in [i for i in range(n)]:
-    ...         yield x
-    >>> list(grange(5))
-    [0, 1, 2, 3, 4]
-
-
-Make sure that None is a valid return value
-
-    >>> [None for i in range(10)]
-    [None, None, None, None, None, None, None, None, None, None]
-
-########### Tests for various scoping corner cases ############
-
-Return lambdas that use the iteration variable as a default argument
-
-    >>> items = [(lambda i=i: i) for i in range(5)]
-    >>> [x() for x in items]
-    [0, 1, 2, 3, 4]
-
-Same again, only this time as a closure variable
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-Another way to test that the iteration variable is local to the list comp
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> i = 20
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-And confirm that a closure can jump over the list comp scope
-
-    >>> items = [(lambda: y) for i in range(5)]
-    >>> y = 2
-    >>> [x() for x in items]
-    [2, 2, 2, 2, 2]
-
-We also repeat each of the above scoping tests inside a function
-
-    >>> def test_func():
-    ...     items = [(lambda i=i: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [0, 1, 2, 3, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     i = 20
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: y) for i in range(5)]
-    ...     y = 2
-    ...     return [x() for x in items]
-    >>> test_func()
-    [2, 2, 2, 2, 2]
-
-"""
-
-
-__test__ = {'doctests' : doctests}
-
-def test_main(verbose=None):
-    import sys
-    from test import support
-    from test import test_listcomps
-    support.run_doctest(test_listcomps, verbose)
-
-    # verify reference counting
-    if verbose and hasattr(sys, "gettotalrefcount"):
-        import gc
-        counts = [None] * 5
-        for i in range(len(counts)):
-            support.run_doctest(test_listcomps, verbose)
-            gc.collect()
-            counts[i] = sys.gettotalrefcount()
-        print(counts)
-
-if __name__ == "__main__":
-    test_main(verbose=True)

From python-checkins at python.org  Sun Dec 12 02:49:46 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Dec 2010 02:49:46 +0100 (CET)
Subject: [Python-checkins] r87178 - in python/branches/release31-maint:
	Lib/test/test_listcomps.py
Message-ID: <20101212014946.E53B1EE9AF@mail.python.org>

Author: benjamin.peterson
Date: Sun Dec 12 02:49:46 2010
New Revision: 87178

Log:
Merged revisions 87177 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87177 | benjamin.peterson | 2010-12-11 19:46:43 -0600 (Sat, 11 Dec 2010) | 1 line
  
  having three copies of the same test is surely a bit excessive
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_listcomps.py

Modified: python/branches/release31-maint/Lib/test/test_listcomps.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_listcomps.py	(original)
+++ python/branches/release31-maint/Lib/test/test_listcomps.py	Sun Dec 12 02:49:46 2010
@@ -146,299 +146,3 @@
 
 if __name__ == "__main__":
     test_main(verbose=True)
-doctests = """
-########### Tests borrowed from or inspired by test_genexps.py ############
-
-Test simple loop with conditional
-
-    >>> sum([i*i for i in range(100) if i&1 == 1])
-    166650
-
-Test simple nesting
-
-    >>> [(i,j) for i in range(3) for j in range(4)]
-    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
-
-Test nesting with the inner expression dependent on the outer
-
-    >>> [(i,j) for i in range(4) for j in range(i)]
-    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
-
-Make sure the induction variable is not exposed
-
-    >>> i = 20
-    >>> sum([i*i for i in range(100)])
-    328350
-
-    >>> i
-    20
-
-Verify that syntax error's are raised for listcomps used as lvalues
-
-    >>> [y for y in (1,2)] = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-    >>> [y for y in (1,2)] += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-
-########### Tests borrowed from or inspired by test_generators.py ############
-
-Make a nested list comprehension that acts like range()
-
-    >>> def frange(n):
-    ...     return [i for i in range(n)]
-    >>> frange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Same again, only as a lambda expression instead of a function definition
-
-    >>> lrange = lambda n:  [i for i in range(n)]
-    >>> lrange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Generators can call other generators:
-
-    >>> def grange(n):
-    ...     for x in [i for i in range(n)]:
-    ...         yield x
-    >>> list(grange(5))
-    [0, 1, 2, 3, 4]
-
-
-Make sure that None is a valid return value
-
-    >>> [None for i in range(10)]
-    [None, None, None, None, None, None, None, None, None, None]
-
-########### Tests for various scoping corner cases ############
-
-Return lambdas that use the iteration variable as a default argument
-
-    >>> items = [(lambda i=i: i) for i in range(5)]
-    >>> [x() for x in items]
-    [0, 1, 2, 3, 4]
-
-Same again, only this time as a closure variable
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-Another way to test that the iteration variable is local to the list comp
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> i = 20
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-And confirm that a closure can jump over the list comp scope
-
-    >>> items = [(lambda: y) for i in range(5)]
-    >>> y = 2
-    >>> [x() for x in items]
-    [2, 2, 2, 2, 2]
-
-We also repeat each of the above scoping tests inside a function
-
-    >>> def test_func():
-    ...     items = [(lambda i=i: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [0, 1, 2, 3, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     i = 20
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: y) for i in range(5)]
-    ...     y = 2
-    ...     return [x() for x in items]
-    >>> test_func()
-    [2, 2, 2, 2, 2]
-
-"""
-
-
-__test__ = {'doctests' : doctests}
-
-def test_main(verbose=None):
-    import sys
-    from test import support
-    from test import test_listcomps
-    support.run_doctest(test_listcomps, verbose)
-
-    # verify reference counting
-    if verbose and hasattr(sys, "gettotalrefcount"):
-        import gc
-        counts = [None] * 5
-        for i in range(len(counts)):
-            support.run_doctest(test_genexps, verbose)
-            gc.collect()
-            counts[i] = sys.gettotalrefcount()
-        print(counts)
-
-if __name__ == "__main__":
-    test_main(verbose=True)
-doctests = """
-########### Tests borrowed from or inspired by test_genexps.py ############
-
-Test simple loop with conditional
-
-    >>> sum([i*i for i in range(100) if i&1 == 1])
-    166650
-
-Test simple nesting
-
-    >>> [(i,j) for i in range(3) for j in range(4)]
-    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
-
-Test nesting with the inner expression dependent on the outer
-
-    >>> [(i,j) for i in range(4) for j in range(i)]
-    [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
-
-Make sure the induction variable is not exposed
-
-    >>> i = 20
-    >>> sum([i*i for i in range(100)])
-    328350
-
-    >>> i
-    20
-
-Verify that syntax error's are raised for listcomps used as lvalues
-
-    >>> [y for y in (1,2)] = 10          # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-    >>> [y for y in (1,2)] += 10         # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-       ...
-    SyntaxError: ...
-
-
-########### Tests borrowed from or inspired by test_generators.py ############
-
-Make a nested list comprehension that acts like range()
-
-    >>> def frange(n):
-    ...     return [i for i in range(n)]
-    >>> frange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Same again, only as a lambda expression instead of a function definition
-
-    >>> lrange = lambda n:  [i for i in range(n)]
-    >>> lrange(10)
-    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
-Generators can call other generators:
-
-    >>> def grange(n):
-    ...     for x in [i for i in range(n)]:
-    ...         yield x
-    >>> list(grange(5))
-    [0, 1, 2, 3, 4]
-
-
-Make sure that None is a valid return value
-
-    >>> [None for i in range(10)]
-    [None, None, None, None, None, None, None, None, None, None]
-
-########### Tests for various scoping corner cases ############
-
-Return lambdas that use the iteration variable as a default argument
-
-    >>> items = [(lambda i=i: i) for i in range(5)]
-    >>> [x() for x in items]
-    [0, 1, 2, 3, 4]
-
-Same again, only this time as a closure variable
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-Another way to test that the iteration variable is local to the list comp
-
-    >>> items = [(lambda: i) for i in range(5)]
-    >>> i = 20
-    >>> [x() for x in items]
-    [4, 4, 4, 4, 4]
-
-And confirm that a closure can jump over the list comp scope
-
-    >>> items = [(lambda: y) for i in range(5)]
-    >>> y = 2
-    >>> [x() for x in items]
-    [2, 2, 2, 2, 2]
-
-We also repeat each of the above scoping tests inside a function
-
-    >>> def test_func():
-    ...     items = [(lambda i=i: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [0, 1, 2, 3, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: i) for i in range(5)]
-    ...     i = 20
-    ...     return [x() for x in items]
-    >>> test_func()
-    [4, 4, 4, 4, 4]
-
-    >>> def test_func():
-    ...     items = [(lambda: y) for i in range(5)]
-    ...     y = 2
-    ...     return [x() for x in items]
-    >>> test_func()
-    [2, 2, 2, 2, 2]
-
-"""
-
-
-__test__ = {'doctests' : doctests}
-
-def test_main(verbose=None):
-    import sys
-    from test import support
-    from test import test_listcomps
-    support.run_doctest(test_listcomps, verbose)
-
-    # verify reference counting
-    if verbose and hasattr(sys, "gettotalrefcount"):
-        import gc
-        counts = [None] * 5
-        for i in range(len(counts)):
-            support.run_doctest(test_listcomps, verbose)
-            gc.collect()
-            counts[i] = sys.gettotalrefcount()
-        print(counts)
-
-if __name__ == "__main__":
-    test_main(verbose=True)

From solipsis at pitrou.net  Sun Dec 12 04:49:59 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sun, 12 Dec 2010 04:49:59 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87177): sum=0
Message-ID: 

py3k results for svn r87177 (hg cset a39a0b1975c8)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogXtZ_Gq', '-x']

From python-checkins at python.org  Sun Dec 12 14:20:55 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 14:20:55 +0100 (CET)
Subject: [Python-checkins] r87179 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212132055.D948EEE993@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 14:20:55 2010
New Revision: 87179

Log:
Logging documentation update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 14:20:55 2010
@@ -14,198 +14,343 @@
 This module defines functions and classes which implement a flexible error
 logging system for applications.
 
-Logging is performed by calling methods on instances of the :class:`Logger`
-class (hereafter called :dfn:`loggers`). Each instance has a name, and they are
-conceptually arranged in a namespace hierarchy using dots (periods) as
-separators. For example, a logger named "scan" is the parent of loggers
-"scan.text", "scan.html" and "scan.pdf". Logger names can be anything you want,
-and indicate the area of an application in which a logged message originates.
-
-Logged messages also have levels of importance associated with them. The default
-levels provided are :const:`DEBUG`, :const:`INFO`, :const:`WARNING`,
-:const:`ERROR` and :const:`CRITICAL`. As a convenience, you indicate the
-importance of a logged message by calling an appropriate method of
-:class:`Logger`. The methods are :meth:`debug`, :meth:`info`, :meth:`warning`,
-:meth:`error` and :meth:`critical`, which mirror the default levels. You are not
-constrained to use these levels: you can specify your own and use a more general
-:class:`Logger` method, :meth:`log`, which takes an explicit level argument.
+The key benefit of having the logging API provided by a standard library module
+is that all Python modules can participate in logging, so your application log
+can include your own messages integrated with messages from third-party
+modules.
 
 
 Logging tutorial
 ----------------
 
-The key benefit of having the logging API provided by a standard library module
-is that all Python modules can participate in logging, so your application log
-can include messages from third-party modules.
+Logging is a means of tracking events that happen when some software runs. The
+software's developer adds logging calls to their code to indicate that certain
+events have occurred. An event is described by a descriptive message which can
+optionally contain variable data (i.e. data that is potentially different for
+each occurrence of the event). Events also have an importance which the
+developer ascribes to the event; the importance can also be called the *level*
+or *severity*.
 
-It is, of course, possible to log messages with different verbosity levels or to
-different destinations.  Support for writing log messages to files, HTTP
-GET/POST locations, email via SMTP, generic sockets, or OS-specific logging
-mechanisms is included in the package.  You can also create your own log
-destination class if you have special requirements not met by any of the
-built-in classes.
+When to use logging
+^^^^^^^^^^^^^^^^^^^
 
-Simple examples
-^^^^^^^^^^^^^^^
+Logging provides a set of convenience functions for simple logging usage. These
+are :func:`debug`, :func:`info`, :func:`warning`, :func:`error` and
+:func:`critical`. To determine when to use logging, see the table below, which
+states, for each of a set of common tasks, the best tool to use for it.
+
++-------------------------------------+--------------------------------------+
+| Task you want to perform            | The best tool for the task           |
++=====================================+======================================+
+| Display console output for ordinary | print()                              |
+| usage of a command line script or   |                                      |
+| program                             |                                      |
++-------------------------------------+--------------------------------------+
+| Report events that occur during     | logging.info() (or logging.debug()   |
+| normal operation of a program (e.g. | for very detailed output for         |
+| or status monitoring or fault       | diagnostic purposes)                 |
+| investigation)                      |                                      |
++-------------------------------------+--------------------------------------+
+| Issue a warning regarding a         | warnings.warn() in library code      |
+| particular runtime event            | if the issue is avoidable and the    |
+|                                     | client application should be         |
+|                                     | modified to eliminate the warning    |
+|                                     |                                      |
+|                                     | logging.warn() if there is nothing   |
+|                                     | the client application can do about  |
+|                                     | the situation, but the event should  |
+|                                     | still be noted                       |
++-------------------------------------+--------------------------------------+
+| Report an error regarding a         | Raise an exception                   |
+| particular runtime event            |                                      |
++-------------------------------------+--------------------------------------+
+| Report suppression of an error      | logging.error(), logging.exception(),|
+| without raising an exception (e.g.  | or logging.critical() as appropriate |
+| error handler in a long-running     | for the specific error and           |
+| server process)                     | application domain                   |
++-------------------------------------+--------------------------------------+
+
+The logging functions are named after the level or severity of the events
+they are used to track. The standard levels and their applicability are
+described below (in increasing order of severity):
+
++--------------+---------------------------------------------+
+| Level        | When it's used                              |
++==============+=============================================+
+| ``DEBUG``    | Detailed information, typically of interest |
+|              | only when diagnosing problems.              |
++--------------+---------------------------------------------+
+| ``INFO``     | Confirmation that things are working as     |
+|              | expected.                                   |
++--------------+---------------------------------------------+
+| ``WARNING``  | An indication that something unexpected     |
+|              | happened, or indicative of some problem in  |
+|              | the near future (e.g. "disk space low").    |
+|              | The software is still working as expected.  |
++--------------+---------------------------------------------+
+| ``ERROR``    | Due to a more serious problem, the software |
+|              | has not been able to perform some function. |
++--------------+---------------------------------------------+
+| ``CRITICAL`` | A serious error, indicating that the program|
+|              | itself may be unable to continue running.   |
++--------------+---------------------------------------------+
+
+The default level is ``WARNING``, which means that only events of this level
+and above will be tracked, unless the logging package is configured to do
+otherwise.
+
+Events that are tracked can be handled in different ways. The simplest way of
+handling tracked events is to print them to the console. Another common way
+is to write them to a disk file.
 
-.. sectionauthor:: Doug Hellmann
-.. (see )
 
-Most applications are probably going to want to log to a file, so let's start
-with that case. Using the :func:`basicConfig` function, we can set up the
-default handler so that debug messages are written to a file (in the example,
-we assume that you have the appropriate permissions to create a file called
-*example.log* in the current directory)::
+.. _minimal-example:
+
+A simple example
+^^^^^^^^^^^^^^^^
+
+A very simple example is::
 
    import logging
-   LOG_FILENAME = 'example.log'
-   logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
+   logging.warning('Watch out!') # will print a message to the console
+   logging.info('I told you so') # will not print anything
 
+If you type these lines into a script and run it, you'll see::
+
+   WARNING:root:Watch out!
+
+printed out on the console. The ``INFO`` message doesn't appear because the
+default level is ``WARNING``. The printed message includes the indication of
+the level and the description of the event provided in the logging call, i.e.
+'Watch out!'. Don't worry about the 'root' part for now: it will be explained
+later. The actual output can be formatted quite flexibly if you need that;
+formatting options will also be explained later.
+
+
+Logging to a file
+^^^^^^^^^^^^^^^^^
+
+A very common situation is that of recording logging events in a file, so let's
+look at that next::
+
+   import logging
+   logging.basicConfig(filename='example.log',level=logging.DEBUG)
    logging.debug('This message should go to the log file')
+   logging.info('So should this')
+   logging.warning('And this, too')
 
 And now if we open the file and look at what we have, we should find the log
-message::
+messages::
 
    DEBUG:root:This message should go to the log file
+   INFO:root:So should this
+   WARNING:root:And this, too
 
-If you run the script repeatedly, the additional log messages are appended to
-the file.  To create a new file each time, you can pass a *filemode* argument to
-:func:`basicConfig` with a value of ``'w'``.  Rather than managing the file size
-yourself, though, it is simpler to use a :class:`RotatingFileHandler`::
+This example also shows how you can set the logging level which acts as the
+threshold for tracking. In this case, because we set the threshold to
+``DEBUG``, all of the messages were printed.
 
-   import glob
-   import logging
-   import logging.handlers
+If you run the above script several times, the messages from successive runs
+are appended to the file *example.log*. If you want each run to start afresh,
+not remembering the messages from earlier runs, you can specify the *filemode*
+argument, by changing the call in the above example to::
 
-   LOG_FILENAME = 'logging_rotatingfile_example.out'
+   logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
 
-   # Set up a specific logger with our desired output level
-   my_logger = logging.getLogger('MyLogger')
-   my_logger.setLevel(logging.DEBUG)
+The output will be the same as before, but the log file is no longer appended
+to, so the messages from earlier runs are lost.
 
-   # Add the log message handler to the logger
-   handler = logging.handlers.RotatingFileHandler(
-                 LOG_FILENAME, maxBytes=20, backupCount=5)
 
-   my_logger.addHandler(handler)
+Logging from multiple modules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-   # Log some messages
-   for i in range(20):
-       my_logger.debug('i = %d' % i)
+If your program consists of multiple modules, here's an example of how you
+could organize logging in it::
 
-   # See what files are created
-   logfiles = glob.glob('%s*' % LOG_FILENAME)
+   # myapp.py
+   import logging
+   import mylib
 
-   for filename in logfiles:
-       print(filename)
+   def main():
+       logging.basicConfig(filename='myapp.log', level=logging.INFO)
+       logging.info('Started')
+       mylib.do_something()
+       logging.info('Finished')
 
-The result should be 6 separate files, each with part of the log history for the
-application::
+   if __name__ == '__main__':
+       main()
 
-   logging_rotatingfile_example.out
-   logging_rotatingfile_example.out.1
-   logging_rotatingfile_example.out.2
-   logging_rotatingfile_example.out.3
-   logging_rotatingfile_example.out.4
-   logging_rotatingfile_example.out.5
+::
 
-The most current file is always :file:`logging_rotatingfile_example.out`,
-and each time it reaches the size limit it is renamed with the suffix
-``.1``. Each of the existing backup files is renamed to increment the suffix
-(``.1`` becomes ``.2``, etc.)  and the ``.6`` file is erased.
+   # mylib.py
+   import logging
 
-Obviously this example sets the log length much much too small as an extreme
-example.  You would want to set *maxBytes* to an appropriate value.
+   def do_something():
+       logging.info('Doing something')
 
-Another useful feature of the logging API is the ability to produce different
-messages at different log levels.  This allows you to instrument your code with
-debug messages, for example, but turning the log level down so that those debug
-messages are not written for your production system.  The default levels are
-``NOTSET``, ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` and ``CRITICAL``.
+If you run myapp.py, you should see this in myapp.log::
+
+   INFO:root:Started
+   INFO:root:Doing something
+   INFO:root:Finished
+
+which is hopefully what you were expecting to see. You can generalize this to
+multiple modules, using the pattern in *mylib.py*. Note that for this simple
+usage pattern, you won't know, by looking in the log file, *where* in your
+application your messages came from, apart from looking at the event
+description. If you want to track the location of your messages, you'll need
+to refer to the documentation beyond the tutorial level - see
+:ref:`more-advanced-logging`.
 
-The logger, handler, and log message call each specify a level.  The log message
-is only emitted if the handler and logger are configured to emit messages of
-that level or lower.  For example, if a message is ``CRITICAL``, and the logger
-is set to ``ERROR``, the message is emitted.  If a message is a ``WARNING``, and
-the logger is set to produce only ``ERROR``\s, the message is not emitted::
+
+Logging variable data
+^^^^^^^^^^^^^^^^^^^^^
+
+To log variable data, use a format string for the event description message and
+append the variable data as arguments. For example::
 
    import logging
-   import sys
+   logging.warning('%s before you %s', 'Look', 'leap!')
 
-   LEVELS = {'debug': logging.DEBUG,
-             'info': logging.INFO,
-             'warning': logging.WARNING,
-             'error': logging.ERROR,
-             'critical': logging.CRITICAL}
+will display::
 
-   if len(sys.argv) > 1:
-       level_name = sys.argv[1]
-       level = LEVELS.get(level_name, logging.NOTSET)
-       logging.basicConfig(level=level)
+   WARNING:root:Look before you leap!
 
-   logging.debug('This is a debug message')
-   logging.info('This is an info message')
-   logging.warning('This is a warning message')
-   logging.error('This is an error message')
-   logging.critical('This is a critical error message')
+As you can see, merging of variable data into the event description message
+uses the old, %-style of string formatting. This is for backwards
+compatibility: the logging package pre-dates newer formatting options such as
+:meth:`str.format` and :class:`string.Template`. These formatting options *are*
+supported, but exploring them is outside the scope of this tutorial.
 
-Run the script with an argument like 'debug' or 'warning' to see which messages
-show up at different levels::
 
-   $ python logging_level_example.py debug
-   DEBUG:root:This is a debug message
-   INFO:root:This is an info message
-   WARNING:root:This is a warning message
-   ERROR:root:This is an error message
-   CRITICAL:root:This is a critical error message
+Changing the format of displayed messages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-   $ python logging_level_example.py info
-   INFO:root:This is an info message
-   WARNING:root:This is a warning message
-   ERROR:root:This is an error message
-   CRITICAL:root:This is a critical error message
+To change the format which is used to display messages, you need to
+specify the format you want to use::
 
-You will notice that these log messages all have ``root`` embedded in them.  The
-logging module supports a hierarchy of loggers with different names.  An easy
-way to tell where a specific log message comes from is to use a separate logger
-object for each of your modules.  Each new logger "inherits" the configuration
-of its parent, and log messages sent to a logger include the name of that
-logger.  Optionally, each logger can be configured differently, so that messages
-from different modules are handled in different ways.  Let's look at a simple
-example of how to log from different modules so it is easy to trace the source
-of the message::
+   import logging
+   logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
+   logging.debug('This message should appear on the console')
+   logging.info('So should this')
+   logging.warning('And this, too')
+
+which would print::
+
+   DEBUG:This message should appear on the console
+   INFO:So should this
+   WARNING:And this, too
+
+Notice that the 'root' which appeared in earlier examples has disappeared. For
+a full set of things that can appear in format strings, you can refer to the
+documentation for :ref:`formatter-objects`, but for simple usage, you just need
+the *levelname* (severity), *message* (event description, including variable
+data) and perhaps to display when the event occurred. This is described in the
+next section.
+
+Displaying the date/time in messages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To display the date and time of an event, you would place "%(asctime)s" in
+your format string::
 
    import logging
+   logging.basicConfig(format='%(asctime)s %(message)s')
+   logging.warning('is when this event was logged.')
 
-   logging.basicConfig(level=logging.WARNING)
+which should print something like this::
 
-   logger1 = logging.getLogger('package1.module1')
-   logger2 = logging.getLogger('package2.module2')
+   2010-12-12 11:41:42,612 is when this event was logged.
 
-   logger1.warning('This message comes from one module')
-   logger2.warning('And this message comes from another module')
+The default format for date/time display (shown above) is ISO8601. If you need
+more control over the formatting of the date/time, provide a *datefmt*
+argument to ``basicConfig``, as in this example::
 
-And the output::
+   import logging
+   logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
+   logging.warning('is when this event was logged.')
 
-   $ python logging_modules_example.py
-   WARNING:package1.module1:This message comes from one module
-   WARNING:package2.module2:And this message comes from another module
+which would display something like this::
 
-There are many more options for configuring logging, including different log
-message formatting options, having messages delivered to multiple destinations,
-and changing the configuration of a long-running application on the fly using a
-socket interface.  All of these options are covered in depth in the library
-module documentation.
+   12/12/2010 11:46:36 AM is when this event was logged.
 
-Loggers
-^^^^^^^
+The format of the *datefmt* argument is the same as supported by
+:func:`time.strftime`.
 
-The logging library takes a modular approach and offers the several categories
+
+Er...that's it for the tutorial
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+That concludes the tutorial. It should be enough to get you up and running
+with logging. There's a lot more that the logging package offers, but to get
+the best out of it, you'll need to invest a little more of your time in
+reading the following sections. If you're ready for that, grab some of your
+favourite beverage and carry on.
+
+If your logging needs are simple, then use the above examples to incorporate
+logging into your own scripts, and if you run into problems or don't
+understand something, please post a question on the comp.lang.python Usenet
+group (available at http://groups.google.com/group/comp.lang.python) and you
+should receive help before too long.
+
+Still here? There's no need to read this long page in linear fashion, top to
+bottom. Take a look at the topics in the sidebar to see if there's something
+that interests you, and click on a topic to see more detail. Although some of
+the topics do follow on from each other, there are a few that can just stand
+alone.
+
+
+.. _more-advanced-logging:
+
+More advanced logging
+---------------------
+
+The logging library takes a modular approach and offers several categories
 of components: loggers, handlers, filters, and formatters.  Loggers expose the
-interface that application code directly uses.  Handlers send the log records to
-the appropriate destination. Filters provide a finer grained facility for
-determining which log records to send on to a handler.  Formatters specify the
-layout of the resultant log record.
+interface that application code directly uses.  Handlers send the log records
+(created by loggers) to the appropriate destination. Filters provide a finer
+grained facility for determining which log records to output. Formatters
+specify the layout of the resultant log record in the final output.
+
+Logging is performed by calling methods on instances of the :class:`Logger`
+class (hereafter called :dfn:`loggers`). Each instance has a name, and they are
+conceptually arranged in a namespace hierarchy using dots (periods) as
+separators. For example, a logger named "scan" is the parent of loggers
+"scan.text", "scan.html" and "scan.pdf". Logger names can be anything you want,
+and indicate the area of an application in which a logged message originates.
+
+The root of the hierarchy of loggers is called the root logger. That's the
+logger used by the functions :func:`debug`, :func:`info`, :func:`warning`,
+:func:`error` and :func:`critical`, which just call the same-named method of
+the root logger. The functions and the methods have the same signatures. The
+root logger's name is printed as 'root' in the logged output.
+
+It is, of course, possible to log messages to different destinations. Support
+for writing log messages to files, HTTP GET/POST locations, email via SMTP,
+generic sockets, or OS-specific logging mechanisms is included in the package.
+Destinations are served by :dfn:`handler` classes. You can create your own log
+destination class if you have special requirements not met by any of the
+built-in handler classes.
+
+By default, no destination is set for any logging messages. You can specify
+a destination (such as console or file) by using :func:`basicConfig` as in the
+tutorial examples. If you call the functions  :func:`debug`, :func:`info`,
+:func:`warning`, :func:`error` and :func:`critical`, they will check to see
+if no destination is set; and if one is not set, they will set a destination
+of the console (``sys.stderr``) and a default format for the displayed
+message before delegating to the root logger to do the actual message output.
+
+The default format set by :func:`basicConfig` for messages is::
+
+   severity:logger name:message
+
+You can change this by passing a format string to :func:`basicConfig` with the
+*format* keyword argument. For all options regarding how a format string is
+constructed, see :ref:`formatter-objects`.
+
+
+Loggers
+^^^^^^^
 
 :class:`Logger` objects have a threefold job.  First, they expose several
 methods to application code so that applications can log messages at runtime.
@@ -688,7 +833,7 @@
    The :class:`NullHandler` class.
 
 .. versionadded:: 3.2
-   The :class:`QueueHandler` class.
+   The :class:`~logging.handlers.QueueHandler` class.
 
 The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler`
 classes are defined in the core logging package. The other handlers are
@@ -1250,8 +1395,7 @@
 
    .. versionadded:: 3.2
 
-
-.. _minimal-example:
+.. _basic-example:
 
 Basic example
 -------------
@@ -1373,6 +1517,138 @@
    Wed, 21 Jul 2004 15:35:16 ERROR    Pack my box with 5 dozen liquor jugs
 
 
+Using file rotation
+^^^^^^^^^^^^^^^^^^^
+
+.. sectionauthor:: Doug Hellmann, Vinay Sajip (changes)
+.. (see )
+
+Sometimes you want to let a log file grow to a certain size, then open a new
+file and log to that. You may want to keep a certain number of these files, and
+when that many files have been created, rotate the files so that the number of
+files and the size of the files both remin bounded. For this usage pattern, the
+logging package provides a :class:`RotatingFileHandler`::
+
+   import glob
+   import logging
+   import logging.handlers
+
+   LOG_FILENAME = 'logging_rotatingfile_example.out'
+
+   # Set up a specific logger with our desired output level
+   my_logger = logging.getLogger('MyLogger')
+   my_logger.setLevel(logging.DEBUG)
+
+   # Add the log message handler to the logger
+   handler = logging.handlers.RotatingFileHandler(
+                 LOG_FILENAME, maxBytes=20, backupCount=5)
+
+   my_logger.addHandler(handler)
+
+   # Log some messages
+   for i in range(20):
+       my_logger.debug('i = %d' % i)
+
+   # See what files are created
+   logfiles = glob.glob('%s*' % LOG_FILENAME)
+
+   for filename in logfiles:
+       print(filename)
+
+The result should be 6 separate files, each with part of the log history for the
+application::
+
+   logging_rotatingfile_example.out
+   logging_rotatingfile_example.out.1
+   logging_rotatingfile_example.out.2
+   logging_rotatingfile_example.out.3
+   logging_rotatingfile_example.out.4
+   logging_rotatingfile_example.out.5
+
+The most current file is always :file:`logging_rotatingfile_example.out`,
+and each time it reaches the size limit it is renamed with the suffix
+``.1``. Each of the existing backup files is renamed to increment the suffix
+(``.1`` becomes ``.2``, etc.)  and the ``.6`` file is erased.
+
+Obviously this example sets the log length much much too small as an extreme
+example.  You would want to set *maxBytes* to an appropriate value.
+
+
+The logger, handler, and log message call each specify a level.  The log message
+is only emitted if the handler and logger are configured to emit messages of
+that level or lower.  For example, if a message is ``CRITICAL``, and the logger
+is set to ``ERROR``, the message is emitted.  If a message is a ``WARNING``, and
+the logger is set to produce only ``ERROR``\s, the message is not emitted::
+
+   import logging
+   import sys
+
+   LEVELS = {'debug': logging.DEBUG,
+             'info': logging.INFO,
+             'warning': logging.WARNING,
+             'error': logging.ERROR,
+             'critical': logging.CRITICAL}
+
+   if len(sys.argv) > 1:
+       level_name = sys.argv[1]
+       level = LEVELS.get(level_name, logging.NOTSET)
+       logging.basicConfig(level=level)
+
+   logging.debug('This is a debug message')
+   logging.info('This is an info message')
+   logging.warning('This is a warning message')
+   logging.error('This is an error message')
+   logging.critical('This is a critical error message')
+
+Run the script with an argument like 'debug' or 'warning' to see which messages
+show up at different levels::
+
+   $ python logging_level_example.py debug
+   DEBUG:root:This is a debug message
+   INFO:root:This is an info message
+   WARNING:root:This is a warning message
+   ERROR:root:This is an error message
+   CRITICAL:root:This is a critical error message
+
+   $ python logging_level_example.py info
+   INFO:root:This is an info message
+   WARNING:root:This is a warning message
+   ERROR:root:This is an error message
+   CRITICAL:root:This is a critical error message
+
+You will notice that these log messages all have ``root`` embedded in them.  The
+logging module supports a hierarchy of loggers with different names.  An easy
+way to tell where a specific log message comes from is to use a separate logger
+object for each of your modules.  Each new logger "inherits" the configuration
+of its parent, and log messages sent to a logger include the name of that
+logger.  Optionally, each logger can be configured differently, so that messages
+from different modules are handled in different ways.  Let's look at a simple
+example of how to log from different modules so it is easy to trace the source
+of the message::
+
+   import logging
+
+   logging.basicConfig(level=logging.WARNING)
+
+   logger1 = logging.getLogger('package1.module1')
+   logger2 = logging.getLogger('package2.module2')
+
+   logger1.warning('This message comes from one module')
+   logger2.warning('And this message comes from another module')
+
+And the output::
+
+   $ python logging_modules_example.py
+   WARNING:package1.module1:This message comes from one module
+   WARNING:package2.module2:And this message comes from another module
+
+There are many more options for configuring logging, including different log
+message formatting options, having messages delivered to multiple destinations,
+and changing the configuration of a long-running application on the fly using a
+socket interface.  All of these options are covered in depth in the library
+module documentation.
+
+
 .. _multiple-destinations:
 
 Logging to multiple destinations
@@ -3216,7 +3492,7 @@
 wire).
 
 
-.. class:: LogRecord(name, lvl, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
+.. class:: LogRecord(name, levelno, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
 
    Contains all the information pertinent to the event being logged.
 
@@ -3241,7 +3517,7 @@
 
       Line number in the source file of origin.
 
-   .. attribute:: lvl
+   .. attribute:: levelno
 
       Numeric logging level.
 

From python-checkins at python.org  Sun Dec 12 14:25:29 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 14:25:29 +0100 (CET)
Subject: [Python-checkins] r87180 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212132529.C21CBEE996@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 14:25:29 2010
New Revision: 87180

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 14:25:29 2010
@@ -319,6 +319,14 @@
 "scan.text", "scan.html" and "scan.pdf". Logger names can be anything you want,
 and indicate the area of an application in which a logged message originates.
 
+A good convention to use when naming loggers is to use a module-level logger,
+in each module which uses logging, named as follows::
+
+   logger = logging.getLogger(__name__)
+
+This means that logger names track the package/module hierarchy, and it's
+intuitively obvious where events are logged just from the logger name.
+
 The root of the hierarchy of loggers is called the root logger. That's the
 logger used by the functions :func:`debug`, :func:`info`, :func:`warning`,
 :func:`error` and :func:`critical`, which just call the same-named method of

From python-checkins at python.org  Sun Dec 12 14:49:39 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 14:49:39 +0100 (CET)
Subject: [Python-checkins] r87181 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212134939.671F9EE990@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 14:49:39 2010
New Revision: 87181

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 14:49:39 2010
@@ -146,6 +146,11 @@
    INFO:root:So should this
    WARNING:root:And this, too
 
+The call to :func:`basicConfig` should come *before* any calls to :func:`debug`,
+:func:`info` etc. As it's intended as a one-off simple configuration facility,
+only the first call will actually do anything: subsequent calls are effectively
+no-ops.
+
 This example also shows how you can set the logging level which acts as the
 threshold for tracking. In this case, because we set the threshold to
 ``DEBUG``, all of the messages were printed.

From python-checkins at python.org  Sun Dec 12 16:24:22 2010
From: python-checkins at python.org (nick.coghlan)
Date: Sun, 12 Dec 2010 16:24:22 +0100 (CET)
Subject: [Python-checkins] r87182 - in python/branches/py3k: Lib/tempfile.py
	Lib/test/support.py Lib/test/test_tempfile.py Misc/NEWS
Message-ID: <20101212152422.2252BEE9D7@mail.python.org>

Author: nick.coghlan
Date: Sun Dec 12 16:24:21 2010
New Revision: 87182

Log:
Issue #10888 (partial resolution): tidy up some behaviour in the new tempfile.TemporaryDirectory context manager

Modified:
   python/branches/py3k/Lib/tempfile.py
   python/branches/py3k/Lib/test/support.py
   python/branches/py3k/Lib/test/test_tempfile.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/tempfile.py
==============================================================================
--- python/branches/py3k/Lib/tempfile.py	(original)
+++ python/branches/py3k/Lib/tempfile.py	Sun Dec 12 16:24:21 2010
@@ -29,6 +29,8 @@
 
 # Imports.
 
+import warnings as _warnings
+import sys as _sys
 import io as _io
 import os as _os
 import errno as _errno
@@ -617,24 +619,40 @@
     """
 
     def __init__(self, suffix="", prefix=template, dir=None):
-        # cleanup() needs this and is called even when mkdtemp fails
-        self._closed = True
-        self.name = mkdtemp(suffix, prefix, dir)
         self._closed = False
+        self.name = None # Handle mkdtemp throwing an exception
+        self.name = mkdtemp(suffix, prefix, dir)
+
+    def __repr__(self):
+        return "<{} {!r}>".format(self.__class__.__name__, self.name)
 
     def __enter__(self):
         return self.name
 
-    def cleanup(self):
-        if not self._closed:
-            self._rmtree(self.name)
+    def cleanup(self, _warn=False):
+        if self.name and not self._closed:
+            try:
+                self._rmtree(self.name)
+            except (TypeError, AttributeError) as ex:
+                # Issue #10188: Emit a warning on stderr
+                # if the directory could not be cleaned
+                # up due to missing globals
+                if "None" not in str(ex):
+                    raise
+                print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
+                      file=_sys.stderr)
+                return
             self._closed = True
+            if _warn:
+                self._warn("Implicitly cleaning up {!r}".format(self),
+                           ResourceWarning)
 
     def __exit__(self, exc, value, tb):
         self.cleanup()
 
-    __del__ = cleanup
-
+    def __del__(self):
+        # Issue a ResourceWarning if implicit cleanup needed
+        self.cleanup(_warn=True)
 
     # XXX (ncoghlan): The following code attempts to make
     # this class tolerant of the module nulling out process
@@ -646,6 +664,7 @@
     _remove = staticmethod(_os.remove)
     _rmdir = staticmethod(_os.rmdir)
     _os_error = _os.error
+    _warn = _warnings.warn
 
     def _rmtree(self, path):
         # Essentially a stripped down version of shutil.rmtree.  We can't

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Sun Dec 12 16:24:21 2010
@@ -874,6 +874,9 @@
 def captured_stdout():
     return captured_output("stdout")
 
+def captured_stderr():
+    return captured_output("stderr")
+
 def captured_stdin():
     return captured_output("stdin")
 

Modified: python/branches/py3k/Lib/test/test_tempfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_tempfile.py	(original)
+++ python/branches/py3k/Lib/test/test_tempfile.py	Sun Dec 12 16:24:21 2010
@@ -925,6 +925,13 @@
             f.write(b"Hello world!")
         return tmp
 
+    def test_mkdtemp_failure(self):
+        # Check no additional exception if mkdtemp fails
+        # Previously would raise AttributeError instead
+        # (noted as part of Issue #10888)
+        #with self.assertRaises(os.error):
+        tempfile.TemporaryDirectory(prefix="[]<>?*!:")
+
     def test_explicit_cleanup(self):
         # A TemporaryDirectory is deleted when cleaned up
         dir = tempfile.mkdtemp()
@@ -955,20 +962,50 @@
     def test_del_on_shutdown(self):
         # A TemporaryDirectory may be cleaned up during shutdown
         # Make sure it works with the relevant modules nulled out
-        dir = tempfile.mkdtemp()
-        try:
+        with self.do_create() as dir:
             d = self.do_create(dir=dir)
             # Mimic the nulling out of modules that
             # occurs during system shutdown
             modules = [os, os.path]
             if has_stat:
                 modules.append(stat)
-            with NulledModules(*modules):
-                d.cleanup()
+            # Currently broken, so suppress the warning
+            # that is otherwise emitted on stdout
+            with support.captured_stderr() as err:
+                with NulledModules(*modules):
+                    d.cleanup()
+            # Currently broken, so stop spurious exception by
+            # indicating the object has already been closed
+            d._closed = True
+            # And this assert will fail, as expected by the
+            # unittest decorator...
             self.assertFalse(os.path.exists(d.name),
                         "TemporaryDirectory %s exists after cleanup" % d.name)
-        finally:
-            os.rmdir(dir)
+
+    def test_warnings_on_cleanup(self):
+        # Two kinds of warning on shutdown
+        #   Issue 10888: may write to stderr if modules are nulled out
+        #   ResourceWarning will be triggered by __del__
+        with self.do_create() as dir:
+            d = self.do_create(dir=dir)
+
+            #Check for the Issue 10888 message
+            modules = [os, os.path]
+            if has_stat:
+                modules.append(stat)
+            with support.captured_stderr() as err:
+                with NulledModules(*modules):
+                    d.cleanup()
+            message = err.getvalue()
+            self.assertIn("while cleaning up",  message)
+            self.assertIn(d.name,  message)
+
+            # Check for the resource warning
+            with support.check_warnings(('Implicitly', ResourceWarning), quiet=False):
+                warnings.filterwarnings("always", category=ResourceWarning)
+                d.__del__()
+            self.assertFalse(os.path.exists(d.name),
+                        "TemporaryDirectory %s exists after __del__" % d.name)
 
     def test_multiple_close(self):
         # Can be cleaned-up many times without error

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sun Dec 12 16:24:21 2010
@@ -11,6 +11,12 @@
 Library
 -------
 
+* Issue #10188 (partial resolution): tempfile.TemporaryDirectory emits
+  a warning on sys.stderr rather than throwing a misleading exception
+  if cleanup fails due to nulling out of modules during shutdown.
+  Also avoids an AttributeError when mkdtemp call fails and issues
+  a ResourceWarning on implicit cleanup via __del__.
+
 * Issue #10107: Warn about unsaved files in IDLE on OSX.
 
 

From python-checkins at python.org  Sun Dec 12 18:37:28 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 18:37:28 +0100 (CET)
Subject: [Python-checkins] r87183 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212173728.1B0B6EE9A7@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 18:37:27 2010
New Revision: 87183

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 18:37:27 2010
@@ -48,7 +48,7 @@
 +-------------------------------------+--------------------------------------+
 | Report events that occur during     | logging.info() (or logging.debug()   |
 | normal operation of a program (e.g. | for very detailed output for         |
-| or status monitoring or fault       | diagnostic purposes)                 |
+| for status monitoring or fault      | diagnostic purposes)                 |
 | investigation)                      |                                      |
 +-------------------------------------+--------------------------------------+
 | Issue a warning regarding a         | warnings.warn() in library code      |
@@ -283,12 +283,12 @@
 :func:`time.strftime`.
 
 
-Er...that's it for the tutorial
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Er...that's it for the basics
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-That concludes the tutorial. It should be enough to get you up and running
-with logging. There's a lot more that the logging package offers, but to get
-the best out of it, you'll need to invest a little more of your time in
+That concludes the basic tutorial. It should be enough to get you up and
+running with logging. There's a lot more that the logging package offers, but
+to get the best out of it, you'll need to invest a little more of your time in
 reading the following sections. If you're ready for that, grab some of your
 favourite beverage and carry on.
 
@@ -298,11 +298,14 @@
 group (available at http://groups.google.com/group/comp.lang.python) and you
 should receive help before too long.
 
-Still here? There's no need to read this long page in linear fashion, top to
-bottom. Take a look at the topics in the sidebar to see if there's something
-that interests you, and click on a topic to see more detail. Although some of
-the topics do follow on from each other, there are a few that can just stand
-alone.
+Still here? There's no need to read the whole of the logging documentation in
+linear fashion, top to bottom (there's quite a lot of it still to come). You
+can carry on reading the next few sections, which provide a slightly more
+advanced/in-depth tutorial than the basic one above. After that, you can
+take a look at the topics in the sidebar to see if there's something that
+especially interests you, and click on a topic to see more detail. Although
+some of the topics do follow on from each other, there are a few that can just
+stand alone.
 
 
 .. _more-advanced-logging:
@@ -374,14 +377,24 @@
 The most widely used methods on logger objects fall into two categories:
 configuration and message sending.
 
+These are the most common configuration methods:
+
 * :meth:`Logger.setLevel` specifies the lowest-severity log message a logger
-  will handle, where debug is the lowest built-in severity level and critical is
-  the highest built-in severity.  For example, if the severity level is info,
-  the logger will handle only info, warning, error, and critical messages and
-  will ignore debug messages.
+  will handle, where debug is the lowest built-in severity level and critical
+  is the highest built-in severity.  For example, if the severity level is
+  INFO, the logger will handle only INFO, WARNING, ERROR, and CRITICAL messages
+  and will ignore DEBUG messages.
+
+* :meth:`Logger.addHandler` and :meth:`Logger.removeHandler` add and remove
+  handler objects from the logger object.  Handlers are covered in more detail
+  in :ref:`handler-basic`.
 
 * :meth:`Logger.addFilter` and :meth:`Logger.removeFilter` add and remove filter
-  objects from the logger object.  This tutorial does not address filters.
+  objects from the logger object.  Filters are covered in more detail in
+  :ref:`filter`.
+
+You don't need to always call these methods on every logger you create. See the
+last two paragraphs in this section.
 
 With the logger object configured, the following methods create log messages:
 
@@ -410,11 +423,24 @@
 down in the hierarchical list are children of loggers higher up in the list.
 For example, given a logger with a name of ``foo``, loggers with names of
 ``foo.bar``, ``foo.bar.baz``, and ``foo.bam`` are all descendants of ``foo``.
+
+Loggers have a concept of *effective level*. If a level is not explicitly set
+on a logger, the level of its parent is used instead as its effective level.
+If the parent has no explicit level set, *its* parent is examined, and so on -
+all ancestors are searched until an explicitly set level is found. The root
+logger always has an explicit level set (``WARNING`` by default). When deciding
+whether to process an event, the effective level of the logger is used to
+determine whether the event is passed to the logger's handlers.
+
 Child loggers propagate messages up to the handlers associated with their
-ancestor loggers.  Because of this, it is unnecessary to define and configure
+ancestor loggers. Because of this, it is unnecessary to define and configure
 handlers for all the loggers an application uses. It is sufficient to
 configure handlers for a top-level logger and create child loggers as needed.
+(You can, however, turn off propagation by setting the *propagate*
+attribute of a logger to *False*.)
+
 
+.. _handler-basic:
 
 Handlers
 ^^^^^^^^
@@ -428,8 +454,9 @@
 requires three individual handlers where each handler is responsible for sending
 messages of a specific severity to a specific location.
 
-The standard library includes quite a few handler types; this tutorial uses only
-:class:`StreamHandler` and :class:`FileHandler` in its examples.
+The standard library includes quite a few handler types (see
+:ref:`useful-handlers`); the tutorials use mainly :class:`StreamHandler` and
+:class:`FileHandler` in its examples.
 
 There are very few methods in a handler for application developers to concern
 themselves with.  The only handler methods that seem relevant for application
@@ -656,46 +683,70 @@
 For more information about logging using a dictionary, see
 :ref:`logging-config-api`.
 
-.. _library-config:
+What happens if no configuration is provided
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Configuring Logging for a Library
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+If no logging configuration is provided, it is possible to have a situation
+where a logging event needs to be output, but no handlers can be found to
+output the event. The behaviour of the logging package in these
+circumstances is dependent on the Python version.
+
+For versions of Python prior to 3.2, the behaviour is as follows:
+
+* If *logging.raiseExceptions* is *False* (production mode), the event is
+  silently dropped.
+
+* If *logging.raiseExceptions* is *True* (development mode), a message
+  "No handlers could be found for logger X.Y.Z" is printed once.
+
+In Python 3.2 and later, the behaviour is as follows:
+
+* The event is output using a 'handler of last resort", stored in
+  ``logging.lastResort``. This internal handler is not associated with any
+  logger, and acts like a :class:`StreamHandler` which writes the event
+  description message to the current value of ``sys.stderr`` (therefore
+  respecting any redirections which may be in effect). No formatting is
+  done on the message - just the bare event description message is printed.
+  The handler's level is set to ``WARNING``, so all events at this and
+  greater severities will be output.
 
-When developing a library which uses logging, some consideration needs to be
-given to its configuration. If the using application does not use logging, and
-library code makes logging calls, then a one-off message "No handlers could be
-found for logger X.Y.Z" is printed to the console. This message is intended
-to catch mistakes in logging configuration, but will confuse an application
-developer who is not aware of logging by the library.
-
-In addition to documenting how a library uses logging, a good way to configure
-library logging so that it does not cause a spurious message is to add a
-handler which does nothing. This avoids the message being printed, since a
-handler will be found: it just doesn't produce any output. If the library user
-configures logging for application use, presumably that configuration will add
-some handlers, and if levels are suitably configured then logging calls made
-in library code will send output to those handlers, as normal.
+To obtain the pre-3.2 behaviour, ``logging.lastResort`` can be set to *None*.
 
-A do-nothing handler can be simply defined as follows::
+.. _library-config:
 
-    import logging
+Configuring Logging for a Library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-    class NullHandler(logging.Handler):
-        def emit(self, record):
-            pass
-
-An instance of this handler should be added to the top-level logger of the
-logging namespace used by the library. If all logging by a library *foo* is
-done using loggers with names matching "foo.x.y", then the code::
+When developing a library which uses logging, you should take care to
+document how the library uses logging - for example, the names of loggers
+used. Some consideration also needs to be given to its logging configuration.
+If the using application does not use logging, and library code makes logging
+calls, then (as described in the previous section) events of severity
+``WARNING`` and greater will be printed to ``sys.stderr``. This is regarded as
+the best default behaviour.
+
+If for some reason you *don't* want these messages printed in the absence of
+any logging configuration, you can attach a do-nothing handler to the top-level
+logger for your library. This avoids the message being printed, since a handler
+will be always be found for the library's events: it just doesn't produce any
+output. If the library user configures logging for application use, presumably
+that configuration will add some handlers, and if levels are suitably
+configured then logging calls made in library code will send output to those
+handlers, as normal.
+
+A do-nothing handler is included in the logging package: :class:`NullHandler`
+(since Python 3.1). An instance of this handler could be added to the top-level
+logger of the logging namespace used by the library (*if* you want to prevent
+your library's logged events being output to ``sys.stderr`` in the absence of
+logging configuration). If all logging by a library *foo* is done using loggers
+with names matching 'foo.x', 'foo.x.y', etc. then the code::
 
     import logging
-
-    h = NullHandler()
-    logging.getLogger("foo").addHandler(h)
+    logging.getLogger('foo').addHandler(logging.NullHandler())
 
 should have the desired effect. If an organisation produces a number of
-libraries, then the logger name specified can be "orgname.foo" rather than
-just "foo".
+libraries, then the logger name specified can be 'orgname.foo' rather than
+just 'foo'.
 
 **PLEASE NOTE:** It is strongly advised that you *do not add any handlers other
 than* :class:`NullHandler` *to your library's loggers*. This is because the
@@ -705,9 +756,6 @@
 "under the hood", you might well interfere with their ability to carry out
 unit tests and deliver logs which suit their requirements.
 
-.. versionadded:: 3.1
-   The :class:`NullHandler` class.
-
 
 Logging Levels
 --------------
@@ -781,6 +829,8 @@
 given numeric value might mean different things for different libraries.
 
 
+.. _useful-handlers:
+
 Useful Handlers
 ---------------
 

From python-checkins at python.org  Sun Dec 12 19:09:54 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 19:09:54 +0100 (CET)
Subject: [Python-checkins] r87184 - python/branches/py3k/Doc/library/dis.rst
Message-ID: <20101212180954.0B899EE990@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 19:09:53 2010
New Revision: 87184

Log:
SET_LINENO was removed in 2.3



Modified:
   python/branches/py3k/Doc/library/dis.rst

Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst	(original)
+++ python/branches/py3k/Doc/library/dis.rst	Sun Dec 12 19:09:53 2010
@@ -733,11 +733,6 @@
    Used by the :keyword:`del` statement.
 
 
-.. opcode:: SET_LINENO (lineno)
-
-   This opcode is obsolete.
-
-
 .. opcode:: RAISE_VARARGS (argc)
 
    Raises an exception. *argc* indicates the number of parameters to the raise

From python-checkins at python.org  Sun Dec 12 19:12:41 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 19:12:41 +0100 (CET)
Subject: [Python-checkins] r87185 - python/branches/py3k/Doc/library/imp.rst
Message-ID: <20101212181241.19ECCEE9AB@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 19:12:40 2010
New Revision: 87185

Log:
Remove reference to stuff which is already obsolete in 2.x.



Modified:
   python/branches/py3k/Doc/library/imp.rst

Modified: python/branches/py3k/Doc/library/imp.rst
==============================================================================
--- python/branches/py3k/Doc/library/imp.rst	(original)
+++ python/branches/py3k/Doc/library/imp.rst	Sun Dec 12 19:12:40 2010
@@ -258,88 +258,6 @@
 
    The module was found as a frozen module (see :func:`init_frozen`).
 
-The following constant and functions are obsolete; their functionality is
-available through :func:`find_module` or :func:`load_module`. They are kept
-around for backward compatibility:
-
-
-.. data:: SEARCH_ERROR
-
-   Unused.
-
-
-.. function:: init_builtin(name)
-
-   Initialize the built-in module called *name* and return its module object along
-   with storing it in ``sys.modules``.  If the module was already initialized, it
-   will be initialized *again*.  Re-initialization involves the copying of the
-   built-in module's ``__dict__`` from the cached module over the module's entry in
-   ``sys.modules``.  If there is no built-in module called *name*, ``None`` is
-   returned.
-
-
-.. function:: init_frozen(name)
-
-   Initialize the frozen module called *name* and return its module object.  If
-   the module was already initialized, it will be initialized *again*.  If there
-   is no frozen module called *name*, ``None`` is returned.  (Frozen modules are
-   modules written in Python whose compiled byte-code object is incorporated
-   into a custom-built Python interpreter by Python's :program:`freeze`
-   utility. See :file:`Tools/freeze/` for now.)
-
-
-.. function:: is_builtin(name)
-
-   Return ``1`` if there is a built-in module called *name* which can be
-   initialized again.  Return ``-1`` if there is a built-in module called *name*
-   which cannot be initialized again (see :func:`init_builtin`).  Return ``0`` if
-   there is no built-in module called *name*.
-
-
-.. function:: is_frozen(name)
-
-   Return ``True`` if there is a frozen module (see :func:`init_frozen`) called
-   *name*, or ``False`` if there is no such module.
-
-
-.. function:: load_compiled(name, pathname, [file])
-
-   .. index:: pair: file; byte-code
-
-   Load and initialize a module implemented as a byte-compiled code file and return
-   its module object.  If the module was already initialized, it will be
-   initialized *again*.  The *name* argument is used to create or access a module
-   object.  The *pathname* argument points to the byte-compiled code file.  The
-   *file* argument is the byte-compiled code file, open for reading in binary mode,
-   from the beginning. It must currently be a real file object, not a user-defined
-   class emulating a file.
-
-
-.. function:: load_dynamic(name, pathname[, file])
-
-   Load and initialize a module implemented as a dynamically loadable shared
-   library and return its module object.  If the module was already initialized, it
-   will be initialized *again*. Re-initialization involves copying the ``__dict__``
-   attribute of the cached instance of the module over the value used in the module
-   cached in ``sys.modules``.  The *pathname* argument must point to the shared
-   library.  The *name* argument is used to construct the name of the
-   initialization function: an external C function called ``initname()`` in the
-   shared library is called.  The optional *file* argument is ignored.  (Note:
-   using shared libraries is highly system dependent, and not all systems support
-   it.)
-
-
-.. function:: load_source(name, pathname[, file])
-
-   Load and initialize a module implemented as a Python source file and return its
-   module object.  If the module was already initialized, it will be initialized
-   *again*.  The *name* argument is used to create or access a module object.  The
-   *pathname* argument points to the source file.  The *file* argument is the
-   source file, open for reading as text, from the beginning. It must currently be
-   a real file object, not a user-defined class emulating a file.  Note that if a
-   properly matching byte-compiled file (with suffix :file:`.pyc` or :file:`.pyo`)
-   exists, it will be used instead of parsing the given source file.
-
 
 .. class:: NullImporter(path_string)
 

From python-checkins at python.org  Sun Dec 12 19:14:34 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 19:14:34 +0100 (CET)
Subject: [Python-checkins] r87186 -
	python/branches/py3k/Doc/library/array.rst
Message-ID: <20101212181434.B100AEE99F@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 19:14:34 2010
New Revision: 87186

Log:
Obsolete aliases needn't be documented



Modified:
   python/branches/py3k/Doc/library/array.rst

Modified: python/branches/py3k/Doc/library/array.rst
==============================================================================
--- python/branches/py3k/Doc/library/array.rst	(original)
+++ python/branches/py3k/Doc/library/array.rst	Sun Dec 12 19:14:34 2010
@@ -65,10 +65,6 @@
    passed to the :meth:`extend` method.
 
 
-.. data:: ArrayType
-
-   Obsolete alias for :class:`array`.
-
 .. data:: typecodes
 
    A string with all available type codes.

From python-checkins at python.org  Sun Dec 12 19:17:33 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 19:17:33 +0100 (CET)
Subject: [Python-checkins] r87187 - in python/branches/release31-maint:
	Doc/library/array.rst Doc/library/dis.rst Doc/library/imp.rst
Message-ID: <20101212181733.17654EE9DD@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 19:17:32 2010
New Revision: 87187

Log:
Merged revisions 87184-87186 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87184 | antoine.pitrou | 2010-12-12 19:09:53 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  SET_LINENO was removed in 2.3
........
  r87185 | antoine.pitrou | 2010-12-12 19:12:40 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Remove reference to stuff which is already obsolete in 2.x.
........
  r87186 | antoine.pitrou | 2010-12-12 19:14:34 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Obsolete aliases needn't be documented
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/library/array.rst
   python/branches/release31-maint/Doc/library/dis.rst
   python/branches/release31-maint/Doc/library/imp.rst

Modified: python/branches/release31-maint/Doc/library/array.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/array.rst	(original)
+++ python/branches/release31-maint/Doc/library/array.rst	Sun Dec 12 19:17:32 2010
@@ -65,10 +65,6 @@
    passed to the :meth:`extend` method.
 
 
-.. data:: ArrayType
-
-   Obsolete alias for :class:`array`.
-
 .. data:: typecodes
 
    A string with all available type codes.

Modified: python/branches/release31-maint/Doc/library/dis.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/dis.rst	(original)
+++ python/branches/release31-maint/Doc/library/dis.rst	Sun Dec 12 19:17:32 2010
@@ -695,11 +695,6 @@
    storage.
 
 
-.. opcode:: SET_LINENO (lineno)
-
-   This opcode is obsolete.
-
-
 .. opcode:: RAISE_VARARGS (argc)
 
    Raises an exception. *argc* indicates the number of parameters to the raise

Modified: python/branches/release31-maint/Doc/library/imp.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/imp.rst	(original)
+++ python/branches/release31-maint/Doc/library/imp.rst	Sun Dec 12 19:17:32 2010
@@ -223,88 +223,6 @@
 
    The module was found as a frozen module (see :func:`init_frozen`).
 
-The following constant and functions are obsolete; their functionality is
-available through :func:`find_module` or :func:`load_module`. They are kept
-around for backward compatibility:
-
-
-.. data:: SEARCH_ERROR
-
-   Unused.
-
-
-.. function:: init_builtin(name)
-
-   Initialize the built-in module called *name* and return its module object along
-   with storing it in ``sys.modules``.  If the module was already initialized, it
-   will be initialized *again*.  Re-initialization involves the copying of the
-   built-in module's ``__dict__`` from the cached module over the module's entry in
-   ``sys.modules``.  If there is no built-in module called *name*, ``None`` is
-   returned.
-
-
-.. function:: init_frozen(name)
-
-   Initialize the frozen module called *name* and return its module object.  If
-   the module was already initialized, it will be initialized *again*.  If there
-   is no frozen module called *name*, ``None`` is returned.  (Frozen modules are
-   modules written in Python whose compiled byte-code object is incorporated
-   into a custom-built Python interpreter by Python's :program:`freeze`
-   utility. See :file:`Tools/freeze/` for now.)
-
-
-.. function:: is_builtin(name)
-
-   Return ``1`` if there is a built-in module called *name* which can be
-   initialized again.  Return ``-1`` if there is a built-in module called *name*
-   which cannot be initialized again (see :func:`init_builtin`).  Return ``0`` if
-   there is no built-in module called *name*.
-
-
-.. function:: is_frozen(name)
-
-   Return ``True`` if there is a frozen module (see :func:`init_frozen`) called
-   *name*, or ``False`` if there is no such module.
-
-
-.. function:: load_compiled(name, pathname, [file])
-
-   .. index:: pair: file; byte-code
-
-   Load and initialize a module implemented as a byte-compiled code file and return
-   its module object.  If the module was already initialized, it will be
-   initialized *again*.  The *name* argument is used to create or access a module
-   object.  The *pathname* argument points to the byte-compiled code file.  The
-   *file* argument is the byte-compiled code file, open for reading in binary mode,
-   from the beginning. It must currently be a real file object, not a user-defined
-   class emulating a file.
-
-
-.. function:: load_dynamic(name, pathname[, file])
-
-   Load and initialize a module implemented as a dynamically loadable shared
-   library and return its module object.  If the module was already initialized, it
-   will be initialized *again*. Re-initialization involves copying the ``__dict__``
-   attribute of the cached instance of the module over the value used in the module
-   cached in ``sys.modules``.  The *pathname* argument must point to the shared
-   library.  The *name* argument is used to construct the name of the
-   initialization function: an external C function called ``initname()`` in the
-   shared library is called.  The optional *file* argument is ignored.  (Note:
-   using shared libraries is highly system dependent, and not all systems support
-   it.)
-
-
-.. function:: load_source(name, pathname[, file])
-
-   Load and initialize a module implemented as a Python source file and return its
-   module object.  If the module was already initialized, it will be initialized
-   *again*.  The *name* argument is used to create or access a module object.  The
-   *pathname* argument points to the source file.  The *file* argument is the
-   source file, open for reading as text, from the beginning. It must currently be
-   a real file object, not a user-defined class emulating a file.  Note that if a
-   properly matching byte-compiled file (with suffix :file:`.pyc` or :file:`.pyo`)
-   exists, it will be used instead of parsing the given source file.
-
 
 .. class:: NullImporter(path_string)
 

From python-checkins at python.org  Sun Dec 12 19:25:25 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 19:25:25 +0100 (CET)
Subject: [Python-checkins] r87188 - python/branches/py3k/Doc/library/test.rst
Message-ID: <20101212182525.C5C6DEE9F3@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 19:25:25 2010
New Revision: 87188

Log:
Make this a warning and fix indentation



Modified:
   python/branches/py3k/Doc/library/test.rst

Modified: python/branches/py3k/Doc/library/test.rst
==============================================================================
--- python/branches/py3k/Doc/library/test.rst	(original)
+++ python/branches/py3k/Doc/library/test.rst	Sun Dec 12 19:25:25 2010
@@ -5,12 +5,12 @@
    :synopsis: Regression tests package containing the testing suite for Python.
 .. sectionauthor:: Brett Cannon 
 
-.. note::
-    The :mod:`test` package is meant for internal use by Python only. It is
-    documented for the benefit of the core developers of Python. Any use of
-    this package outside of Python's standard library is discouraged as code
-    mentioned here can change or be removed without notice between releases of
-    Python.
+.. warning::
+   The :mod:`test` package is meant for internal use by Python only. It is
+   documented for the benefit of the core developers of Python. Any use of
+   this package outside of Python's standard library is discouraged as code
+   mentioned here can change or be removed without notice between releases of
+   Python.
 
 
 The :mod:`test` package contains all regression tests for Python as well as the

From python-checkins at python.org  Sun Dec 12 20:59:48 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 20:59:48 +0100 (CET)
Subject: [Python-checkins] r87189 - in python/branches/py3k/Doc/c-api:
	buffer.rst typeobj.rst
Message-ID: <20101212195948.353C3EE9F4@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 20:59:47 2010
New Revision: 87189

Log:
Better explain the buffer interface (hopefully)



Modified:
   python/branches/py3k/Doc/c-api/buffer.rst
   python/branches/py3k/Doc/c-api/typeobj.rst

Modified: python/branches/py3k/Doc/c-api/buffer.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/buffer.rst	(original)
+++ python/branches/py3k/Doc/c-api/buffer.rst	Sun Dec 12 20:59:47 2010
@@ -12,16 +12,32 @@
 .. index::
    single: buffer interface
 
-Python objects implemented in C can export a "buffer interface."  These
-functions can be used by an object to expose its data in a raw, byte-oriented
-format. Clients of the object can use the buffer interface to access the
-object data directly, without needing to copy it first.
-
-Examples of objects that support the buffer interface are :class:`bytes`,
-:class:`bytearray` and :class:`array.array`. The bytes and bytearray objects
-exposes their bytes contents in the buffer interface's byte-oriented form.
-An :class:`array.array` can also expose its contents, but it should be noted
-that array elements may be multi-byte values.
+Certain objects available in Python wrap access to an underlying memory
+array or *buffer*.  Such objects include the built-in :class:`bytes` and
+:class:`bytearray`, and some extension types like :class:`array.array`.
+Third-party libraries may define their own types for special purposes, such
+as image processing or numeric analysis.
+
+While each of these types have their own semantics, they share the common
+characteristic of being backed by a possibly large memory buffer.  It is
+then desireable, in some situations, to access that buffer directly and
+without intermediate copying.
+
+Python provides such a facility at the C level in the form of the *buffer
+protocol*.  This protocol has two sides:
+
+.. index:: single: PyBufferProcs
+
+- on the producer side, a type can export a "buffer interface" which allows
+  objects of that type to expose information about their underlying buffer.
+  This interface is described in the section :ref:`buffer-structs`;
+
+- on the consumer side, several means are available to obtain a pointer to
+  the raw underlying data of an object (for example a method parameter).
+
+Simple objects such as :class:`bytes` and :class:`bytearray` expose their
+underlying buffer in byte-oriented form.  Other forms are possible; for example,
+the elements exposed by a :class:`array.array` can be multi-byte values.
 
 An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write`
 method of file objects: any object that can export a series of bytes through
@@ -44,12 +60,6 @@
 resource leaks.
 
 
-.. index:: single: PyBufferProcs
-
-How the buffer interface is exposed by a type object is described in the
-section :ref:`buffer-structs`, under the description for :c:type:`PyBufferProcs`.
-
-
 The buffer structure
 ====================
 

Modified: python/branches/py3k/Doc/c-api/typeobj.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/typeobj.rst	(original)
+++ python/branches/py3k/Doc/c-api/typeobj.rst	Sun Dec 12 20:59:47 2010
@@ -1195,7 +1195,7 @@
 .. sectionauthor:: Benjamin Peterson
 
 
-The buffer interface exports a model where an object can expose its internal
+The :ref:`buffer interface ` exports a model where an object can expose its internal
 data.
 
 If an object does not export the buffer interface, then its :attr:`tp_as_buffer`

From python-checkins at python.org  Sun Dec 12 21:01:43 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:01:43 +0100 (CET)
Subject: [Python-checkins] r87190 -
	python/branches/py3k/Doc/library/stdtypes.rst
Message-ID: <20101212200143.4C1D8EE9FE@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:01:43 2010
New Revision: 87190

Log:
Add link to the buffer protocol description from the memory description.



Modified:
   python/branches/py3k/Doc/library/stdtypes.rst

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Sun Dec 12 21:01:43 2010
@@ -2279,8 +2279,8 @@
 ===============
 
 :class:`memoryview` objects allow Python code to access the internal data
-of an object that supports the buffer protocol without copying.  Memory
-is generally interpreted as simple bytes.
+of an object that supports the :ref:`buffer protocol ` without
+copying.  Memory is generally interpreted as simple bytes.
 
 .. class:: memoryview(obj)
 

From python-checkins at python.org  Sun Dec 12 21:06:19 2010
From: python-checkins at python.org (r.david.murray)
Date: Sun, 12 Dec 2010 21:06:19 +0100 (CET)
Subject: [Python-checkins] r87191 -
	python/branches/py3k/Lib/email/generator.py
Message-ID: <20101212200619.DA356EE995@mail.python.org>

Author: r.david.murray
Date: Sun Dec 12 21:06:19 2010
New Revision: 87191

Log:
#243654: only create a new MIME boundary if we don't already have one.

The rearranged code should do exactly what the old code did, but
the new code avoids a potentially costly re computation in the case
where a boundary already exists.


Modified:
   python/branches/py3k/Lib/email/generator.py

Modified: python/branches/py3k/Lib/email/generator.py
==============================================================================
--- python/branches/py3k/Lib/email/generator.py	(original)
+++ python/branches/py3k/Lib/email/generator.py	Sun Dec 12 21:06:19 2010
@@ -220,19 +220,13 @@
             g = self.clone(s)
             g.flatten(part, unixfrom=False, linesep=self._NL)
             msgtexts.append(s.getvalue())
-        # Now make sure the boundary we've selected doesn't appear in any of
-        # the message texts.
-        alltext = self._encoded_NL.join(msgtexts)
         # BAW: What about boundaries that are wrapped in double-quotes?
-        boundary = msg.get_boundary(failobj=self._make_boundary(alltext))
-        # If we had to calculate a new boundary because the body text
-        # contained that string, set the new boundary.  We don't do it
-        # unconditionally because, while set_boundary() preserves order, it
-        # doesn't preserve newlines/continuations in headers.  This is no big
-        # deal in practice, but turns out to be inconvenient for the unittest
-        # suite.
-        if msg.get_boundary() != boundary:
-            msg.set_boundary(boundary)
+        boundary = msg.get_boundary()
+        if not boundary:
+            # Create a boundary that doesn't appear in any of the
+            # message texts.
+            alltext = self._encoded_NL.join(msgtexts)
+            msg.set_boundary(self._make_boundary(alltext))
         # If there's a preamble, write it out, with a trailing CRLF
         if msg.preamble is not None:
             self.write(msg.preamble + self._NL)

From python-checkins at python.org  Sun Dec 12 21:09:18 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:09:18 +0100 (CET)
Subject: [Python-checkins] r87192 -
	python/branches/py3k/Doc/library/stdtypes.rst
Message-ID: <20101212200918.2C937EE9A1@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:09:18 2010
New Revision: 87192

Log:
Remove redundant sentence, and fix markup



Modified:
   python/branches/py3k/Doc/library/stdtypes.rst

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Sun Dec 12 21:09:18 2010
@@ -2433,12 +2433,9 @@
    single: protocol; context management
 
 Python's :keyword:`with` statement supports the concept of a runtime context
-defined by a context manager.  This is implemented using two separate methods
+defined by a context manager.  This is implemented using a pair of methods
 that allow user-defined classes to define a runtime context that is entered
-before the statement body is executed and exited when the statement ends.
-
-The :dfn:`context management protocol` consists of a pair of methods that need
-to be provided for a context manager object to define a runtime context:
+before the statement body is executed and exited when the statement ends:
 
 
 .. method:: contextmanager.__enter__()
@@ -2486,9 +2483,9 @@
 their implementation of the context management protocol. See the
 :mod:`contextlib` module for some examples.
 
-Python's :term:`generator`\s and the ``contextlib.contextmanager`` :term:`decorator`
+Python's :term:`generator`\s and the :class:`contextlib.contextmanager` decorator
 provide a convenient way to implement these protocols.  If a generator function is
-decorated with the ``contextlib.contextmanager`` decorator, it will return a
+decorated with the :class:`contextlib.contextmanager` decorator, it will return a
 context manager implementing the necessary :meth:`__enter__` and
 :meth:`__exit__` methods, rather than the iterator produced by an undecorated
 generator function.

From python-checkins at python.org  Sun Dec 12 21:13:32 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:13:32 +0100 (CET)
Subject: [Python-checkins] r87193 -
	python/branches/py3k/Doc/library/random.rst
Message-ID: <20101212201332.04D60EA5E@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:13:31 2010
New Revision: 87193

Log:
Fix heading level



Modified:
   python/branches/py3k/Doc/library/random.rst

Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst	(original)
+++ python/branches/py3k/Doc/library/random.rst	Sun Dec 12 21:13:31 2010
@@ -259,7 +259,7 @@
 
 
 Notes on Reproducibility
-========================
+------------------------
 
 Sometimes it is useful to be able to reproduce the sequences given by a pseudo
 random number generator.  By re-using a seed value, the same sequence should be
@@ -277,7 +277,7 @@
 .. _random-examples:
 
 Examples and Recipes
-====================
+--------------------
 
 Basic usage::
 

From python-checkins at python.org  Sun Dec 12 21:17:29 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:17:29 +0100 (CET)
Subject: [Python-checkins] r87194 -
	python/branches/py3k/Doc/library/os.path.rst
Message-ID: <20101212201729.73C3CEE989@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:17:29 2010
New Revision: 87194

Log:
Consistent ordering of availability statements



Modified:
   python/branches/py3k/Doc/library/os.path.rst

Modified: python/branches/py3k/Doc/library/os.path.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.path.rst	(original)
+++ python/branches/py3k/Doc/library/os.path.rst	Sun Dec 12 21:17:29 2010
@@ -228,7 +228,7 @@
 
    *start* defaults to :attr:`os.curdir`.
 
-   Availability:  Windows, Unix.
+   Availability: Unix, Windows.
 
 
 .. function:: samefile(path1, path2)
@@ -241,7 +241,7 @@
    name using the Windows API call GetFinalPathNameByHandle. This function
    raises an exception if handles cannot be obtained to either file.
 
-   Availability: Windows, Unix.
+   Availability: Unix, Windows.
 
    .. versionchanged:: 3.2
       Added Windows support.

From python-checkins at python.org  Sun Dec 12 21:28:13 2010
From: python-checkins at python.org (r.david.murray)
Date: Sun, 12 Dec 2010 21:28:13 +0100 (CET)
Subject: [Python-checkins] r87195 - in python/branches/release31-maint:
	Lib/email/generator.py
Message-ID: <20101212202813.2EB88EE9A1@mail.python.org>

Author: r.david.murray
Date: Sun Dec 12 21:28:13 2010
New Revision: 87195

Log:
Merged revisions 87191 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87191 | r.david.murray | 2010-12-12 15:06:19 -0500 (Sun, 12 Dec 2010) | 6 lines
  
  #243654: only create a new MIME boundary if we don't already have one.
  
  The rearranged code should do exactly what the old code did, but
  the new code avoids a potentially costly re computation in the case
  where a boundary already exists.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/email/generator.py

Modified: python/branches/release31-maint/Lib/email/generator.py
==============================================================================
--- python/branches/release31-maint/Lib/email/generator.py	(original)
+++ python/branches/release31-maint/Lib/email/generator.py	Sun Dec 12 21:28:13 2010
@@ -180,19 +180,13 @@
             g = self.clone(s)
             g.flatten(part, unixfrom=False)
             msgtexts.append(s.getvalue())
-        # Now make sure the boundary we've selected doesn't appear in any of
-        # the message texts.
-        alltext = NL.join(msgtexts)
         # BAW: What about boundaries that are wrapped in double-quotes?
-        boundary = msg.get_boundary(failobj=_make_boundary(alltext))
-        # If we had to calculate a new boundary because the body text
-        # contained that string, set the new boundary.  We don't do it
-        # unconditionally because, while set_boundary() preserves order, it
-        # doesn't preserve newlines/continuations in headers.  This is no big
-        # deal in practice, but turns out to be inconvenient for the unittest
-        # suite.
-        if msg.get_boundary() != boundary:
-            msg.set_boundary(boundary)
+        boundary = msg.get_boundary()
+        if not boundary:
+            # Create a boundary that doesn't appear in any of the
+            # message texts.
+            alltext = NL.join(msgtexts)
+            msg.set_boundary(self._make_boundary(alltext))
         # If there's a preamble, write it out, with a trailing CRLF
         if msg.preamble is not None:
             print(msg.preamble, file=self._fp)

From python-checkins at python.org  Sun Dec 12 21:32:19 2010
From: python-checkins at python.org (r.david.murray)
Date: Sun, 12 Dec 2010 21:32:19 +0100 (CET)
Subject: [Python-checkins] r87196 - in python/branches/release27-maint:
	Lib/email/generator.py
Message-ID: <20101212203219.E6701EE9A1@mail.python.org>

Author: r.david.murray
Date: Sun Dec 12 21:32:19 2010
New Revision: 87196

Log:
Merged revisions 87191 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87191 | r.david.murray | 2010-12-12 15:06:19 -0500 (Sun, 12 Dec 2010) | 6 lines
  
  #243654: only create a new MIME boundary if we don't already have one.
  
  The rearranged code should do exactly what the old code did, but
  the new code avoids a potentially costly re computation in the case
  where a boundary already exists.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/email/generator.py

Modified: python/branches/release27-maint/Lib/email/generator.py
==============================================================================
--- python/branches/release27-maint/Lib/email/generator.py	(original)
+++ python/branches/release27-maint/Lib/email/generator.py	Sun Dec 12 21:32:19 2010
@@ -202,19 +202,13 @@
             g = self.clone(s)
             g.flatten(part, unixfrom=False)
             msgtexts.append(s.getvalue())
-        # Now make sure the boundary we've selected doesn't appear in any of
-        # the message texts.
-        alltext = NL.join(msgtexts)
         # BAW: What about boundaries that are wrapped in double-quotes?
-        boundary = msg.get_boundary(failobj=_make_boundary(alltext))
-        # If we had to calculate a new boundary because the body text
-        # contained that string, set the new boundary.  We don't do it
-        # unconditionally because, while set_boundary() preserves order, it
-        # doesn't preserve newlines/continuations in headers.  This is no big
-        # deal in practice, but turns out to be inconvenient for the unittest
-        # suite.
-        if msg.get_boundary() != boundary:
-            msg.set_boundary(boundary)
+        boundary = msg.get_boundary()
+        if not boundary:
+            # Create a boundary that doesn't appear in any of the
+            # message texts.
+            alltext = NL.join(msgtexts)
+            msg.set_boundary(self._make_boundary(alltext))
         # If there's a preamble, write it out, with a trailing CRLF
         if msg.preamble is not None:
             print >> self._fp, msg.preamble

From python-checkins at python.org  Sun Dec 12 21:34:49 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:34:49 +0100 (CET)
Subject: [Python-checkins] r87197 - in python/branches/py3k/Doc/library:
	concurrent.futures.rst multiprocessing.rst someos.rst threading.rst
Message-ID: <20101212203449.5190EEE9A1@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:34:49 2010
New Revision: 87197

Log:
Homogenize the "optional OS services" menu



Modified:
   python/branches/py3k/Doc/library/concurrent.futures.rst
   python/branches/py3k/Doc/library/multiprocessing.rst
   python/branches/py3k/Doc/library/someos.rst
   python/branches/py3k/Doc/library/threading.rst

Modified: python/branches/py3k/Doc/library/concurrent.futures.rst
==============================================================================
--- python/branches/py3k/Doc/library/concurrent.futures.rst	(original)
+++ python/branches/py3k/Doc/library/concurrent.futures.rst	Sun Dec 12 21:34:49 2010
@@ -1,5 +1,5 @@
-:mod:`concurrent.futures` --- Concurrent computation
-====================================================
+:mod:`concurrent.futures` --- Launching parallel tasks
+======================================================
 
 .. module:: concurrent.futures
    :synopsis: Execute computations concurrently using threads or processes.

Modified: python/branches/py3k/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/py3k/Doc/library/multiprocessing.rst	(original)
+++ python/branches/py3k/Doc/library/multiprocessing.rst	Sun Dec 12 21:34:49 2010
@@ -1,8 +1,8 @@
-:mod:`multiprocessing` --- Process-based "threading" interface
-==============================================================
+:mod:`multiprocessing` --- Process-based parallelism
+====================================================
 
 .. module:: multiprocessing
-   :synopsis: Process-based "threading" interface.
+   :synopsis: Process-based parallelism.
 
 
 Introduction

Modified: python/branches/py3k/Doc/library/someos.rst
==============================================================================
--- python/branches/py3k/Doc/library/someos.rst	(original)
+++ python/branches/py3k/Doc/library/someos.rst	Sun Dec 12 21:34:49 2010
@@ -14,11 +14,11 @@
 
    select.rst
    threading.rst
-   dummy_threading.rst
-   _thread.rst
-   _dummy_thread.rst
-   concurrent.futures.rst
    multiprocessing.rst
+   concurrent.futures.rst
    mmap.rst
    readline.rst
    rlcompleter.rst
+   dummy_threading.rst
+   _thread.rst
+   _dummy_thread.rst

Modified: python/branches/py3k/Doc/library/threading.rst
==============================================================================
--- python/branches/py3k/Doc/library/threading.rst	(original)
+++ python/branches/py3k/Doc/library/threading.rst	Sun Dec 12 21:34:49 2010
@@ -1,8 +1,8 @@
-:mod:`threading` --- Higher-level threading interface
-=====================================================
+:mod:`threading` --- Thread-based parallelism
+=============================================
 
 .. module:: threading
-   :synopsis: Higher-level threading interface.
+   :synopsis: Thread-based parallelism.
 
 
 This module constructs higher-level threading interfaces on top of the lower

From python-checkins at python.org  Sun Dec 12 21:57:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 21:57:12 +0100 (CET)
Subject: [Python-checkins] r87198 -
	python/branches/py3k/Doc/library/socket.rst
Message-ID: <20101212205712.89C60EE9A1@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 21:57:12 2010
New Revision: 87198

Log:
Improve readability of the socket docs



Modified:
   python/branches/py3k/Doc/library/socket.rst

Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst	(original)
+++ python/branches/py3k/Doc/library/socket.rst	Sun Dec 12 21:57:12 2010
@@ -14,16 +14,6 @@
    Some behavior may be platform dependent, since calls are made to the operating
    system socket APIs.
 
-For an introduction to socket programming (in C), see the following papers: An
-Introductory 4.3BSD Interprocess Communication Tutorial, by Stuart Sechrest and
-An Advanced 4.3BSD Interprocess Communication Tutorial, by Samuel J.  Leffler et
-al, both in the UNIX Programmer's Manual, Supplementary Documents 1 (sections
-PS1:7 and PS1:8).  The platform-specific reference material for the various
-socket-related system calls are also a valuable source of information on the
-details of socket semantics.  For Unix, refer to the manual pages; for Windows,
-see the WinSock (or Winsock 2) specification. For IPv6-ready APIs, readers may
-want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6.
-
 .. index:: object: socket
 
 The Python interface is a straightforward transliteration of the Unix system
@@ -34,26 +24,63 @@
 files, buffer allocation on receive operations is automatic, and buffer length
 is implicit on send operations.
 
-Socket addresses are represented as follows: A single string is used for the
-:const:`AF_UNIX` address family. A pair ``(host, port)`` is used for the
-:const:`AF_INET` address family, where *host* is a string representing either a
-hostname in Internet domain notation like ``'daring.cwi.nl'`` or an IPv4 address
-like ``'100.50.200.5'``, and *port* is an integral port number. For
-:const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo,
-scopeid)`` is used, where *flowinfo* and *scopeid* represents ``sin6_flowinfo``
-and ``sin6_scope_id`` member in :const:`struct sockaddr_in6` in C. For
-:mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for
-backward compatibility. Note, however, omission of *scopeid* can cause problems
-in manipulating scoped IPv6 addresses. Other address families are currently not
-supported. The address format required by a particular socket object is
-automatically selected based on the address family specified when the socket
-object was created.
+
+Socket families
+---------------
+
+Depending on the system and the build options, various socket families
+are supported by this module.
+
+Socket addresses are represented as follows:
+
+- A single string is used for the :const:`AF_UNIX` address family.
+
+- A pair ``(host, port)`` is used for the :const:`AF_INET` address family,
+  where *host* is a string representing either a hostname in Internet domain
+  notation like ``'daring.cwi.nl'`` or an IPv4 address like ``'100.50.200.5'``,
+  and *port* is an integral port number.
+
+- For :const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo,
+  scopeid)`` is used, where *flowinfo* and *scopeid* represent the ``sin6_flowinfo``
+  and ``sin6_scope_id`` members in :const:`struct sockaddr_in6` in C.  For
+  :mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for
+  backward compatibility.  Note, however, omission of *scopeid* can cause problems
+  in manipulating scoped IPv6 addresses.
+
+- :const:`AF_NETLINK` sockets are represented as pairs ``(pid, groups)``.
+
+- Linux-only support for TIPC is available using the :const:`AF_TIPC`
+  address family.  TIPC is an open, non-IP based networked protocol designed
+  for use in clustered computer environments.  Addresses are represented by a
+  tuple, and the fields depend on the address type. The general tuple form is
+  ``(addr_type, v1, v2, v3 [, scope])``, where:
+
+  - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
+    TIPC_ADDR_ID.
+  - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
+    TIPC_NODE_SCOPE.
+  - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
+    the port identifier, and *v3* should be 0.
+
+    If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
+    is the lower port number, and *v3* is the upper port number.
+
+    If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+    reference, and *v3* should be set to 0.
+
+    If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+    reference, and *v3* should be set to 0.
+
+- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`)
+  support specific representations.
+
+  .. XXX document them!
 
 For IPv4 addresses, two special forms are accepted instead of a host address:
 the empty string represents :const:`INADDR_ANY`, and the string
-``''`` represents :const:`INADDR_BROADCAST`. The behavior is not
-available for IPv6 for backward compatibility, therefore, you may want to avoid
-these if you intend to support IPv6 with your Python programs.
+``''`` represents :const:`INADDR_BROADCAST`.  This behavior is not
+compatible with IPv6, therefore, you may want to avoid these if you intend
+to support IPv6 with your Python programs.
 
 If you use a hostname in the *host* portion of IPv4/v6 socket address, the
 program may show a nondeterministic behavior, as Python uses the first address
@@ -62,40 +89,18 @@
 resolution and/or the host configuration.  For deterministic behavior use a
 numeric address in *host* portion.
 
-AF_NETLINK sockets are represented as  pairs ``pid, groups``.
-
-
-Linux-only support for TIPC is also available using the :const:`AF_TIPC`
-address family. TIPC is an open, non-IP based networked protocol designed
-for use in clustered computer environments.  Addresses are represented by a
-tuple, and the fields depend on the address type. The general tuple form is
-``(addr_type, v1, v2, v3 [, scope])``, where:
-
-- *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
-  TIPC_ADDR_ID.
-- *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
-  TIPC_NODE_SCOPE.
-- If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
-  the port identifier, and *v3* should be 0.
-
-  If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
-  is the lower port number, and *v3* is the upper port number.
-
-  If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
-  reference, and *v3* should be set to 0.
-
-  If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
-  reference, and *v3* should be set to 0.
-
-
 All errors raise exceptions.  The normal exceptions for invalid argument types
 and out-of-memory conditions can be raised; errors related to socket or address
-semantics raise the error :exc:`socket.error`.
+semantics raise :exc:`socket.error` or one of its subclasses.
 
 Non-blocking mode is supported through :meth:`~socket.setblocking`.  A
 generalization of this based on timeouts is supported through
 :meth:`~socket.settimeout`.
 
+
+Module contents
+---------------
+
 The module :mod:`socket` exports the following constants and functions:
 
 
@@ -144,7 +149,8 @@
 
    These constants represent the address (and protocol) families, used for the
    first argument to :func:`socket`.  If the :const:`AF_UNIX` constant is not
-   defined then this protocol is unsupported.
+   defined then this protocol is unsupported.  More constants may be available
+   depending on the system.
 
 
 .. data:: SOCK_STREAM
@@ -154,8 +160,9 @@
           SOCK_SEQPACKET
 
    These constants represent the socket types, used for the second argument to
-   :func:`socket`. (Only :const:`SOCK_STREAM` and :const:`SOCK_DGRAM` appear to be
-   generally useful.)
+   :func:`socket`.  More constants may be available depending on the system.
+   (Only :const:`SOCK_STREAM` and :const:`SOCK_DGRAM` appear to be generally
+   useful.)
 
 .. data:: SOCK_CLOEXEC
           SOCK_NONBLOCK
@@ -950,3 +957,21 @@
 
    # disabled promiscuous mode
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
+
+
+.. seealso::
+
+   For an introduction to socket programming (in C), see the following papers:
+
+   - *An Introductory 4.3BSD Interprocess Communication Tutorial*, by Stuart Sechrest
+
+   - *An Advanced 4.3BSD Interprocess Communication Tutorial*, by Samuel J.  Leffler et
+     al,
+
+   both in the UNIX Programmer's Manual, Supplementary Documents 1 (sections
+   PS1:7 and PS1:8).  The platform-specific reference material for the various
+   socket-related system calls are also a valuable source of information on the
+   details of socket semantics.  For Unix, refer to the manual pages; for Windows,
+   see the WinSock (or Winsock 2) specification.  For IPv6-ready APIs, readers may
+   want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6.
+

From python-checkins at python.org  Sun Dec 12 22:07:49 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 22:07:49 +0100 (CET)
Subject: [Python-checkins] r87199 - in python/branches/release31-maint:
	Doc/c-api/buffer.rst Doc/c-api/typeobj.rst
	Doc/library/os.path.rst Doc/library/stdtypes.rst
	Doc/library/test.rst
Message-ID: <20101212210749.D3055EE9FB@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 22:07:49 2010
New Revision: 87199

Log:
Merged revisions 87188-87190,87192-87194 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87188 | antoine.pitrou | 2010-12-12 19:25:25 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Make this a warning and fix indentation
........
  r87189 | antoine.pitrou | 2010-12-12 20:59:47 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Better explain the buffer interface (hopefully)
........
  r87190 | antoine.pitrou | 2010-12-12 21:01:43 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Add link to the buffer protocol description from the memory description.
........
  r87192 | antoine.pitrou | 2010-12-12 21:09:18 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Remove redundant sentence, and fix markup
........
  r87193 | antoine.pitrou | 2010-12-12 21:13:31 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Fix heading level
........
  r87194 | antoine.pitrou | 2010-12-12 21:17:29 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Consistent ordering of availability statements
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/c-api/buffer.rst
   python/branches/release31-maint/Doc/c-api/typeobj.rst
   python/branches/release31-maint/Doc/library/os.path.rst
   python/branches/release31-maint/Doc/library/stdtypes.rst
   python/branches/release31-maint/Doc/library/test.rst

Modified: python/branches/release31-maint/Doc/c-api/buffer.rst
==============================================================================
--- python/branches/release31-maint/Doc/c-api/buffer.rst	(original)
+++ python/branches/release31-maint/Doc/c-api/buffer.rst	Sun Dec 12 22:07:49 2010
@@ -12,16 +12,32 @@
 .. index::
    single: buffer interface
 
-Python objects implemented in C can export a "buffer interface."  These
-functions can be used by an object to expose its data in a raw, byte-oriented
-format. Clients of the object can use the buffer interface to access the
-object data directly, without needing to copy it first.
-
-Examples of objects that support the buffer interface are :class:`bytes`,
-:class:`bytearray` and :class:`array.array`. The bytes and bytearray objects
-exposes their bytes contents in the buffer interface's byte-oriented form.
-An :class:`array.array` can also expose its contents, but it should be noted
-that array elements may be multi-byte values.
+Certain objects available in Python wrap access to an underlying memory
+array or *buffer*.  Such objects include the built-in :class:`bytes` and
+:class:`bytearray`, and some extension types like :class:`array.array`.
+Third-party libraries may define their own types for special purposes, such
+as image processing or numeric analysis.
+
+While each of these types have their own semantics, they share the common
+characteristic of being backed by a possibly large memory buffer.  It is
+then desireable, in some situations, to access that buffer directly and
+without intermediate copying.
+
+Python provides such a facility at the C level in the form of the *buffer
+protocol*.  This protocol has two sides:
+
+.. index:: single: PyBufferProcs
+
+- on the producer side, a type can export a "buffer interface" which allows
+  objects of that type to expose information about their underlying buffer.
+  This interface is described in the section :ref:`buffer-structs`;
+
+- on the consumer side, several means are available to obtain a pointer to
+  the raw underlying data of an object (for example a method parameter).
+
+Simple objects such as :class:`bytes` and :class:`bytearray` expose their
+underlying buffer in byte-oriented form.  Other forms are possible; for example,
+the elements exposed by a :class:`array.array` can be multi-byte values.
 
 An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write`
 method of file objects: any object that can export a series of bytes through
@@ -44,12 +60,6 @@
 resource leaks.
 
 
-.. index:: single: PyBufferProcs
-
-How the buffer interface is exposed by a type object is described in the
-section :ref:`buffer-structs`, under the description for :ctype:`PyBufferProcs`.
-
-
 The buffer structure
 ====================
 

Modified: python/branches/release31-maint/Doc/c-api/typeobj.rst
==============================================================================
--- python/branches/release31-maint/Doc/c-api/typeobj.rst	(original)
+++ python/branches/release31-maint/Doc/c-api/typeobj.rst	Sun Dec 12 22:07:49 2010
@@ -1193,7 +1193,7 @@
 .. sectionauthor:: Benjamin Peterson
 
 
-The buffer interface exports a model where an object can expose its internal
+The :ref:`buffer interface ` exports a model where an object can expose its internal
 data.
 
 If an object does not export the buffer interface, then its :attr:`tp_as_buffer`

Modified: python/branches/release31-maint/Doc/library/os.path.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/os.path.rst	(original)
+++ python/branches/release31-maint/Doc/library/os.path.rst	Sun Dec 12 22:07:49 2010
@@ -227,7 +227,7 @@
 
    *start* defaults to :attr:`os.curdir`.
 
-   Availability:  Windows, Unix.
+   Availability: Unix, Windows.
 
 
 .. function:: samefile(path1, path2)

Modified: python/branches/release31-maint/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/stdtypes.rst	(original)
+++ python/branches/release31-maint/Doc/library/stdtypes.rst	Sun Dec 12 22:07:49 2010
@@ -2081,9 +2081,9 @@
 memoryview Types
 ================
 
-:class:`memoryview`\s allow Python code to access the internal data of an object
-that supports the buffer protocol without copying.  Memory can be interpreted as
-simple bytes or complex data structures.
+:class:`memoryview` objects allow Python code to access the internal data
+of an object that supports the :ref:`buffer protocol ` without
+copying.  Memory is generally interpreted as simple bytes.
 
 .. class:: memoryview(obj)
 
@@ -2203,12 +2203,9 @@
    single: protocol; context management
 
 Python's :keyword:`with` statement supports the concept of a runtime context
-defined by a context manager.  This is implemented using two separate methods
+defined by a context manager.  This is implemented using a pair of methods
 that allow user-defined classes to define a runtime context that is entered
-before the statement body is executed and exited when the statement ends.
-
-The :dfn:`context management protocol` consists of a pair of methods that need
-to be provided for a context manager object to define a runtime context:
+before the statement body is executed and exited when the statement ends:
 
 
 .. method:: contextmanager.__enter__()
@@ -2256,9 +2253,9 @@
 their implementation of the context management protocol. See the
 :mod:`contextlib` module for some examples.
 
-Python's :term:`generator`\s and the ``contextlib.contextmanager`` :term:`decorator`
+Python's :term:`generator`\s and the :class:`contextlib.contextmanager` decorator
 provide a convenient way to implement these protocols.  If a generator function is
-decorated with the ``contextlib.contextmanager`` decorator, it will return a
+decorated with the :class:`contextlib.contextmanager` decorator, it will return a
 context manager implementing the necessary :meth:`__enter__` and
 :meth:`__exit__` methods, rather than the iterator produced by an undecorated
 generator function.

Modified: python/branches/release31-maint/Doc/library/test.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/test.rst	(original)
+++ python/branches/release31-maint/Doc/library/test.rst	Sun Dec 12 22:07:49 2010
@@ -5,12 +5,12 @@
    :synopsis: Regression tests package containing the testing suite for Python.
 .. sectionauthor:: Brett Cannon 
 
-.. note::
-    The :mod:`test` package is meant for internal use by Python only. It is
-    documented for the benefit of the core developers of Python. Any use of
-    this package outside of Python's standard library is discouraged as code
-    mentioned here can change or be removed without notice between releases of
-    Python.
+.. warning::
+   The :mod:`test` package is meant for internal use by Python only. It is
+   documented for the benefit of the core developers of Python. Any use of
+   this package outside of Python's standard library is discouraged as code
+   mentioned here can change or be removed without notice between releases of
+   Python.
 
 
 The :mod:`test` package contains all regression tests for Python as well as the

From python-checkins at python.org  Sun Dec 12 22:08:54 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Dec 2010 22:08:54 +0100 (CET)
Subject: [Python-checkins] r87200 - in python/branches/release31-maint:
	Doc/library/multiprocessing.rst Doc/library/socket.rst
	Doc/library/someos.rst Doc/library/threading.rst
Message-ID: <20101212210854.E758AEE9C8@mail.python.org>

Author: antoine.pitrou
Date: Sun Dec 12 22:08:54 2010
New Revision: 87200

Log:
Merged revisions 87197-87198 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87197 | antoine.pitrou | 2010-12-12 21:34:49 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Homogenize the "optional OS services" menu
........
  r87198 | antoine.pitrou | 2010-12-12 21:57:12 +0100 (dim., 12 d?c. 2010) | 3 lines
  
  Improve readability of the socket docs
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/library/multiprocessing.rst
   python/branches/release31-maint/Doc/library/socket.rst
   python/branches/release31-maint/Doc/library/someos.rst
   python/branches/release31-maint/Doc/library/threading.rst

Modified: python/branches/release31-maint/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/multiprocessing.rst	(original)
+++ python/branches/release31-maint/Doc/library/multiprocessing.rst	Sun Dec 12 22:08:54 2010
@@ -1,8 +1,8 @@
-:mod:`multiprocessing` --- Process-based "threading" interface
-==============================================================
+:mod:`multiprocessing` --- Process-based parallelism
+====================================================
 
 .. module:: multiprocessing
-   :synopsis: Process-based "threading" interface.
+   :synopsis: Process-based parallelism.
 
 
 Introduction

Modified: python/branches/release31-maint/Doc/library/socket.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/socket.rst	(original)
+++ python/branches/release31-maint/Doc/library/socket.rst	Sun Dec 12 22:08:54 2010
@@ -15,16 +15,6 @@
    Some behavior may be platform dependent, since calls are made to the operating
    system socket APIs.
 
-For an introduction to socket programming (in C), see the following papers: An
-Introductory 4.3BSD Interprocess Communication Tutorial, by Stuart Sechrest and
-An Advanced 4.3BSD Interprocess Communication Tutorial, by Samuel J.  Leffler et
-al, both in the UNIX Programmer's Manual, Supplementary Documents 1 (sections
-PS1:7 and PS1:8).  The platform-specific reference material for the various
-socket-related system calls are also a valuable source of information on the
-details of socket semantics.  For Unix, refer to the manual pages; for Windows,
-see the WinSock (or Winsock 2) specification. For IPv6-ready APIs, readers may
-want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6.
-
 .. index:: object: socket
 
 The Python interface is a straightforward transliteration of the Unix system
@@ -35,26 +25,63 @@
 files, buffer allocation on receive operations is automatic, and buffer length
 is implicit on send operations.
 
-Socket addresses are represented as follows: A single string is used for the
-:const:`AF_UNIX` address family. A pair ``(host, port)`` is used for the
-:const:`AF_INET` address family, where *host* is a string representing either a
-hostname in Internet domain notation like ``'daring.cwi.nl'`` or an IPv4 address
-like ``'100.50.200.5'``, and *port* is an integral port number. For
-:const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo,
-scopeid)`` is used, where *flowinfo* and *scopeid* represents ``sin6_flowinfo``
-and ``sin6_scope_id`` member in :const:`struct sockaddr_in6` in C. For
-:mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for
-backward compatibility. Note, however, omission of *scopeid* can cause problems
-in manipulating scoped IPv6 addresses. Other address families are currently not
-supported. The address format required by a particular socket object is
-automatically selected based on the address family specified when the socket
-object was created.
+
+Socket families
+---------------
+
+Depending on the system and the build options, various socket families
+are supported by this module.
+
+Socket addresses are represented as follows:
+
+- A single string is used for the :const:`AF_UNIX` address family.
+
+- A pair ``(host, port)`` is used for the :const:`AF_INET` address family,
+  where *host* is a string representing either a hostname in Internet domain
+  notation like ``'daring.cwi.nl'`` or an IPv4 address like ``'100.50.200.5'``,
+  and *port* is an integral port number.
+
+- For :const:`AF_INET6` address family, a four-tuple ``(host, port, flowinfo,
+  scopeid)`` is used, where *flowinfo* and *scopeid* represent the ``sin6_flowinfo``
+  and ``sin6_scope_id`` members in :const:`struct sockaddr_in6` in C.  For
+  :mod:`socket` module methods, *flowinfo* and *scopeid* can be omitted just for
+  backward compatibility.  Note, however, omission of *scopeid* can cause problems
+  in manipulating scoped IPv6 addresses.
+
+- :const:`AF_NETLINK` sockets are represented as pairs ``(pid, groups)``.
+
+- Linux-only support for TIPC is available using the :const:`AF_TIPC`
+  address family.  TIPC is an open, non-IP based networked protocol designed
+  for use in clustered computer environments.  Addresses are represented by a
+  tuple, and the fields depend on the address type. The general tuple form is
+  ``(addr_type, v1, v2, v3 [, scope])``, where:
+
+  - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
+    TIPC_ADDR_ID.
+  - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
+    TIPC_NODE_SCOPE.
+  - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
+    the port identifier, and *v3* should be 0.
+
+    If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
+    is the lower port number, and *v3* is the upper port number.
+
+    If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+    reference, and *v3* should be set to 0.
+
+    If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+    reference, and *v3* should be set to 0.
+
+- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`)
+  support specific representations.
+
+  .. XXX document them!
 
 For IPv4 addresses, two special forms are accepted instead of a host address:
 the empty string represents :const:`INADDR_ANY`, and the string
-``''`` represents :const:`INADDR_BROADCAST`. The behavior is not
-available for IPv6 for backward compatibility, therefore, you may want to avoid
-these if you intend to support IPv6 with your Python programs.
+``''`` represents :const:`INADDR_BROADCAST`.  This behavior is not
+compatible with IPv6, therefore, you may want to avoid these if you intend
+to support IPv6 with your Python programs.
 
 If you use a hostname in the *host* portion of IPv4/v6 socket address, the
 program may show a nondeterministic behavior, as Python uses the first address
@@ -63,40 +90,18 @@
 resolution and/or the host configuration.  For deterministic behavior use a
 numeric address in *host* portion.
 
-AF_NETLINK sockets are represented as  pairs ``pid, groups``.
-
-
-Linux-only support for TIPC is also available using the :const:`AF_TIPC`
-address family. TIPC is an open, non-IP based networked protocol designed
-for use in clustered computer environments.  Addresses are represented by a
-tuple, and the fields depend on the address type. The general tuple form is
-``(addr_type, v1, v2, v3 [, scope])``, where:
-
-- *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
-  TIPC_ADDR_ID.
-- *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
-  TIPC_NODE_SCOPE.
-- If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
-  the port identifier, and *v3* should be 0.
-
-  If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
-  is the lower port number, and *v3* is the upper port number.
-
-  If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
-  reference, and *v3* should be set to 0.
-
-  If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
-  reference, and *v3* should be set to 0.
-
-
 All errors raise exceptions.  The normal exceptions for invalid argument types
 and out-of-memory conditions can be raised; errors related to socket or address
-semantics raise the error :exc:`socket.error`.
+semantics raise :exc:`socket.error` or one of its subclasses.
 
 Non-blocking mode is supported through :meth:`~socket.setblocking`.  A
 generalization of this based on timeouts is supported through
 :meth:`~socket.settimeout`.
 
+
+Module contents
+---------------
+
 The module :mod:`socket` exports the following constants and functions:
 
 
@@ -145,7 +150,8 @@
 
    These constants represent the address (and protocol) families, used for the
    first argument to :func:`socket`.  If the :const:`AF_UNIX` constant is not
-   defined then this protocol is unsupported.
+   defined then this protocol is unsupported.  More constants may be available
+   depending on the system.
 
 
 .. data:: SOCK_STREAM
@@ -155,8 +161,9 @@
           SOCK_SEQPACKET
 
    These constants represent the socket types, used for the second argument to
-   :func:`socket`. (Only :const:`SOCK_STREAM` and :const:`SOCK_DGRAM` appear to be
-   generally useful.)
+   :func:`socket`.  More constants may be available depending on the system.
+   (Only :const:`SOCK_STREAM` and :const:`SOCK_DGRAM` appear to be generally
+   useful.)
 
 
 .. data:: SO_*
@@ -911,3 +918,21 @@
 
    # disabled promiscuous mode
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
+
+
+.. seealso::
+
+   For an introduction to socket programming (in C), see the following papers:
+
+   - *An Introductory 4.3BSD Interprocess Communication Tutorial*, by Stuart Sechrest
+
+   - *An Advanced 4.3BSD Interprocess Communication Tutorial*, by Samuel J.  Leffler et
+     al,
+
+   both in the UNIX Programmer's Manual, Supplementary Documents 1 (sections
+   PS1:7 and PS1:8).  The platform-specific reference material for the various
+   socket-related system calls are also a valuable source of information on the
+   details of socket semantics.  For Unix, refer to the manual pages; for Windows,
+   see the WinSock (or Winsock 2) specification.  For IPv6-ready APIs, readers may
+   want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6.
+

Modified: python/branches/release31-maint/Doc/library/someos.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/someos.rst	(original)
+++ python/branches/release31-maint/Doc/library/someos.rst	Sun Dec 12 22:08:54 2010
@@ -14,10 +14,10 @@
 
    select.rst
    threading.rst
-   dummy_threading.rst
-   _thread.rst
-   _dummy_thread.rst
    multiprocessing.rst
    mmap.rst
    readline.rst
    rlcompleter.rst
+   dummy_threading.rst
+   _thread.rst
+   _dummy_thread.rst

Modified: python/branches/release31-maint/Doc/library/threading.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/threading.rst	(original)
+++ python/branches/release31-maint/Doc/library/threading.rst	Sun Dec 12 22:08:54 2010
@@ -1,8 +1,8 @@
-:mod:`threading` --- Higher-level threading interface
-=====================================================
+:mod:`threading` --- Thread-based parallelism
+=============================================
 
 .. module:: threading
-   :synopsis: Higher-level threading interface.
+   :synopsis: Thread-based parallelism.
 
 
 This module constructs higher-level threading interfaces on top of the lower

From python-checkins at python.org  Sun Dec 12 23:30:17 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 23:30:17 +0100 (CET)
Subject: [Python-checkins] r87201 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212223017.9ACDCEE9CA@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 23:30:17 2010
New Revision: 87201

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 23:30:17 2010
@@ -12,7 +12,7 @@
 .. index:: pair: Errors; logging
 
 This module defines functions and classes which implement a flexible error
-logging system for applications.
+logging system for applications and libraries.
 
 The key benefit of having the logging API provided by a standard library module
 is that all Python modules can participate in logging, so your application log
@@ -224,8 +224,9 @@
 As you can see, merging of variable data into the event description message
 uses the old, %-style of string formatting. This is for backwards
 compatibility: the logging package pre-dates newer formatting options such as
-:meth:`str.format` and :class:`string.Template`. These formatting options *are*
-supported, but exploring them is outside the scope of this tutorial.
+:meth:`str.format` and :class:`string.Template`. These newer formatting
+options *are* supported, but exploring them is outside the scope of this
+tutorial.
 
 
 Changing the format of displayed messages

From python-checkins at python.org  Sun Dec 12 23:45:35 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 23:45:35 +0100 (CET)
Subject: [Python-checkins] r87202 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212224535.C828DEE995@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 23:45:35 2010
New Revision: 87202

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 23:45:35 2010
@@ -146,15 +146,35 @@
    INFO:root:So should this
    WARNING:root:And this, too
 
+This example also shows how you can set the logging level which acts as the
+threshold for tracking. In this case, because we set the threshold to
+``DEBUG``, all of the messages were printed.
+
+If you want to set the logging level from a command-line option such as::
+
+   --log=INFO
+
+and you have the value of the parameter passed for ``--log`` in some variable
+*loglevel*, you can use::
+
+   getattr(logging, loglevel.upper())
+
+to get the value which you'll pass to :func:`basicConfig` via the *level*
+argument. You may want to error check any user input value, perhaps as in the
+following example::
+
+   # assuming loglevel is bound to the string value obtained from the
+   # command line argument. Convert to upper case to allow the user to
+   # specify --log=DEBUG or --log=debug
+   numeric_level = getattr(logging, loglevel.upper(), None)
+   assert numeric_level is not None, 'Invalid log level: %s' % loglevel
+   logging.basicConfig(level=numeric_level, ...)
+
 The call to :func:`basicConfig` should come *before* any calls to :func:`debug`,
 :func:`info` etc. As it's intended as a one-off simple configuration facility,
 only the first call will actually do anything: subsequent calls are effectively
 no-ops.
 
-This example also shows how you can set the logging level which acts as the
-threshold for tracking. In this case, because we set the threshold to
-``DEBUG``, all of the messages were printed.
-
 If you run the above script several times, the messages from successive runs
 are appended to the file *example.log*. If you want each run to start afresh,
 not remembering the messages from earlier runs, you can specify the *filemode*

From python-checkins at python.org  Sun Dec 12 23:47:13 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Dec 2010 23:47:13 +0100 (CET)
Subject: [Python-checkins] r87203 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101212224713.CB625EEA24@mail.python.org>

Author: vinay.sajip
Date: Sun Dec 12 23:47:13 2010
New Revision: 87203

Log:
Logging documentation - further update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Sun Dec 12 23:47:13 2010
@@ -2,7 +2,7 @@
 ==============================================
 
 .. module:: logging
-   :synopsis: Flexible error logging system for applications.
+   :synopsis: Flexible event logging system for applications.
 
 
 .. moduleauthor:: Vinay Sajip 
@@ -11,7 +11,7 @@
 
 .. index:: pair: Errors; logging
 
-This module defines functions and classes which implement a flexible error
+This module defines functions and classes which implement a flexible event
 logging system for applications and libraries.
 
 The key benefit of having the logging API provided by a standard library module

From python-checkins at python.org  Mon Dec 13 04:02:43 2010
From: python-checkins at python.org (nick.coghlan)
Date: Mon, 13 Dec 2010 04:02:43 +0100 (CET)
Subject: [Python-checkins] r87204 -
	python/branches/py3k/Lib/test/test_tempfile.py
Message-ID: <20101213030243.AC96BEE9A5@mail.python.org>

Author: nick.coghlan
Date: Mon Dec 13 04:02:43 2010
New Revision: 87204

Log:
Actually finish the tests for r87182

Modified:
   python/branches/py3k/Lib/test/test_tempfile.py

Modified: python/branches/py3k/Lib/test/test_tempfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_tempfile.py	(original)
+++ python/branches/py3k/Lib/test/test_tempfile.py	Mon Dec 13 04:02:43 2010
@@ -928,9 +928,11 @@
     def test_mkdtemp_failure(self):
         # Check no additional exception if mkdtemp fails
         # Previously would raise AttributeError instead
-        # (noted as part of Issue #10888)
-        #with self.assertRaises(os.error):
-        tempfile.TemporaryDirectory(prefix="[]<>?*!:")
+        # (noted as part of Issue #10188)
+        with tempfile.TemporaryDirectory() as nonexistent:
+            pass
+        with self.assertRaises(os.error):
+            tempfile.TemporaryDirectory(dir=nonexistent)
 
     def test_explicit_cleanup(self):
         # A TemporaryDirectory is deleted when cleaned up

From python-checkins at python.org  Mon Dec 13 04:06:08 2010
From: python-checkins at python.org (nick.coghlan)
Date: Mon, 13 Dec 2010 04:06:08 +0100 (CET)
Subject: [Python-checkins] r87182 - svn:log
Message-ID: <20101213030608.070EDEE9B5@mail.python.org>

Author: nick.coghlan
Revision: 87182
Property Name: svn:log
Action: modified

Property diff:
--- old property value
+++ new property value
@@ -1 +1 @@
-Issue #10888 (partial resolution): tidy up some behaviour in the new tempfile.TemporaryDirectory context manager
\ No newline at end of file
+Issue #10188 (partial resolution): tidy up some behaviour in the new tempfile.TemporaryDirectory context manager

From python-checkins at python.org  Mon Dec 13 04:32:10 2010
From: python-checkins at python.org (kristjan.jonsson)
Date: Mon, 13 Dec 2010 04:32:10 +0100 (CET)
Subject: [Python-checkins] r87205 -
	python/branches/py3k/PCbuild/make_buildinfo.c
Message-ID: <20101213033210.C4C3CEEA0F@mail.python.org>

Author: kristjan.jonsson
Date: Mon Dec 13 04:32:10 2010
New Revision: 87205

Log:
issue 10683
When the solution is converted to Visual Studio 2010, the command line to invoke make_buildinfo changes from:
$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\"
to
$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)"
If the final backslash is omitted, the backslash in IntDir will escape the quote, thus passing the quote in as part of the path name.

This solution is a hack-fix to that problem by skipping any trailing quote from the path name.  It works as long as we don't need any additional arguments to make_buildinfo.exe.  This will help all those sould that are going to run this project through the visual studio autoconverter and get the same error.

Modified:
   python/branches/py3k/PCbuild/make_buildinfo.c

Modified: python/branches/py3k/PCbuild/make_buildinfo.c
==============================================================================
--- python/branches/py3k/PCbuild/make_buildinfo.c	(original)
+++ python/branches/py3k/PCbuild/make_buildinfo.c	Mon Dec 13 04:32:10 2010
@@ -91,6 +91,17 @@
     if (argc > 2) {
         tmpdir = argv[2];
         strcat_s(tmppath, _countof(tmppath), tmpdir);
+        /* Hack fix for bad command line:  If the command is issued like this:
+         * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)"
+         * we will get a trailing quote because IntDir ends with a backslash that then
+         * escapes the final ".  To simplify the life for developers, catch that problem
+         * here by cutting it off.
+         * The proper command line, btw is:
+         * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\"
+         * Hooray for command line parsing on windows.
+         */
+        if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"')
+            tmppath[strlen(tmppath)-1] = '\0';
         strcat_s(tmppath, _countof(tmppath), "\\");
     }
 

From ncoghlan at gmail.com  Mon Dec 13 04:45:50 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Mon, 13 Dec 2010 13:45:50 +1000
Subject: [Python-checkins] r87202 -
	python/branches/py3k/Doc/library/logging.rst
In-Reply-To: <20101212224535.C828DEE995@mail.python.org>
References: <20101212224535.C828DEE995@mail.python.org>
Message-ID: 

On Mon, Dec 13, 2010 at 8:45 AM, vinay.sajip  wrote:
> +to get the value which you'll pass to :func:`basicConfig` via the *level*
> +argument. You may want to error check any user input value, perhaps as in the
> +following example::
> +
> + ? # assuming loglevel is bound to the string value obtained from the
> + ? # command line argument. Convert to upper case to allow the user to
> + ? # specify --log=DEBUG or --log=debug
> + ? numeric_level = getattr(logging, loglevel.upper(), None)
> + ? assert numeric_level is not None, 'Invalid log level: %s' % loglevel
> + ? logging.basicConfig(level=numeric_level, ...)

Minor nit - using asserts to check user input is generally a bad idea.
A more explicit check might be a better example:

if not isinstance(numeric_level, int):
   raise ValueError('Invalid log level: %s' % loglevel)

This also covers the case where someone does something weird like pass
in "basic_format" as a logging level.

Cheers,
Nick.

-- 
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia

From solipsis at pitrou.net  Mon Dec 13 04:48:30 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Mon, 13 Dec 2010 04:48:30 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87203): sum=0
Message-ID: 

py3k results for svn r87203 (hg cset e6acf9e4fa7e)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog_iAUSz', '-x']

From python-checkins at python.org  Mon Dec 13 07:45:02 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Mon, 13 Dec 2010 07:45:02 +0100 (CET)
Subject: [Python-checkins] r87206 - in python/branches/py3k:
	Doc/library/subprocess.rst Lib/subprocess.py
	Lib/test/test_subprocess.py
Message-ID: <20101213064502.F40A3EE985@mail.python.org>

Author: gregory.p.smith
Date: Mon Dec 13 07:45:02 2010
New Revision: 87206

Log:
Get rid of the close_fds DeprecationWarning.  Changes the default on a per
platform basis.  It remains False on Windows and changes to True on all
other platforms (POSIX).  Based on python-dev discussion and
http://bugs.python.org/issue7213.


Modified:
   python/branches/py3k/Doc/library/subprocess.rst
   python/branches/py3k/Lib/subprocess.py
   python/branches/py3k/Lib/test/test_subprocess.py

Modified: python/branches/py3k/Doc/library/subprocess.rst
==============================================================================
--- python/branches/py3k/Doc/library/subprocess.rst	(original)
+++ python/branches/py3k/Doc/library/subprocess.rst	Mon Dec 13 07:45:02 2010
@@ -28,7 +28,7 @@
 This module defines one class called :class:`Popen`:
 
 
-.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
+.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
 
    Arguments are:
 
@@ -153,17 +153,14 @@
 
    If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
    :const:`2` will be closed before the child process is executed. (Unix only).
-   The recommended value for this argument is True.
+   The default varies by platform: :const:`False` on Windows and :const:`True`
+   on POSIX and other platforms.
    On Windows, if *close_fds* is true then no handles will be inherited by the
    child process.  Note that on Windows, you cannot set *close_fds* to true and
    also redirect the standard handles by setting *stdin*, *stdout* or *stderr*.
 
 .. versionchanged:: 3.2
-   Callers should always specify a *close_fds* to avoid a DeprecationWarning.
-   The default behavior of this argument will be changing in Python 3.3.
-
-   If *shell* is :const:`True`, the specified command will be executed through the
-   shell.
+   The default was changed to True on non Windows platforms.
 
    If *cwd* is not ``None``, the child's current directory will be changed to *cwd*
    before it is executed.  Note that this directory is not considered when
@@ -654,4 +651,5 @@
 * ``stdin=PIPE`` and ``stdout=PIPE`` must be specified.
 
 * popen2 closes all file descriptors by default, but you have to specify
-  ``close_fds=True`` with :class:`Popen`.
+  ``close_fds=True`` with :class:`Popen` to guarantee this behavior on
+  all platforms or past Python versions.

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Mon Dec 13 07:45:02 2010
@@ -27,7 +27,7 @@
 
 class Popen(args, bufsize=0, executable=None,
             stdin=None, stdout=None, stderr=None,
-            preexec_fn=None, close_fds=False, shell=False,
+            preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
             cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False):
@@ -39,12 +39,12 @@
 program to execute is normally the first item in the args sequence or
 string, but can be explicitly set by using the executable argument.
 
-On UNIX, with shell=False (default): In this case, the Popen class
+On POSIX, with shell=False (default): In this case, the Popen class
 uses os.execvp() to execute the child program.  args should normally
 be a sequence.  A string will be treated as a sequence with the string
 as the only item (the program to execute).
 
-On UNIX, with shell=True: If args is a string, it specifies the
+On POSIX, with shell=True: If args is a string, it specifies the
 command string to execute through the shell.  If args is a sequence,
 the first item specifies the command string, and any additional items
 will be treated as additional shell arguments.
@@ -73,14 +73,16 @@
 stderr data from the applications should be captured into the same
 file handle as for stdout.
 
-On UNIX, if preexec_fn is set to a callable object, this object will be
+On POSIX, if preexec_fn is set to a callable object, this object will be
 called in the child process just before the child is executed.  The use
 of preexec_fn is not thread safe, using it in the presence of threads
 could lead to a deadlock in the child process before the new executable
 is executed.
 
 If close_fds is true, all file descriptors except 0, 1 and 2 will be
-closed before the child process is executed.
+closed before the child process is executed.  The default for close_fds
+varies by platform: False on Windows and True on all other platforms
+such as POSIX.
 
 if shell is true, the specified command will be executed through the
 shell.
@@ -88,12 +90,12 @@
 If cwd is not None, the current directory will be changed to cwd
 before the child is executed.
 
-On UNIX, if restore_signals is True all signals that Python sets to
+On POSIX, if restore_signals is True all signals that Python sets to
 SIG_IGN are restored to SIG_DFL in the child process before the exec.
 Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.  This
 parameter does nothing on Windows.
 
-On UNIX, if start_new_session is True, the setsid() system call will be made
+On POSIX, if start_new_session is True, the setsid() system call will be made
 in the child process prior to executing the command.
 
 If env is not None, it defines the environment variables for the new
@@ -101,7 +103,7 @@
 
 If universal_newlines is true, the file objects stdout and stderr are
 opened as a text files, but lines may be terminated by any of '\n',
-the Unix end-of-line convention, '\r', the Macintosh convention or
+the Unix end-of-line convention, '\r', the old Macintosh convention or
 '\r\n', the Windows convention.  All of these external representations
 are seen as '\n' by the Python program.  Note: This feature is only
 available if Python is built with universal newline support (the
@@ -242,7 +244,7 @@
 returncode
     The child return code.  A None value indicates that the process
     hasn't terminated yet.  A negative value -N indicates that the
-    child was terminated by signal N (UNIX only).
+    child was terminated by signal N (POSIX only).
 
 
 Replacing older functions with the subprocess module
@@ -562,7 +564,7 @@
 
 # Various tools for executing commands and looking at their output and status.
 #
-# NB This only works (and is only relevant) for UNIX.
+# NB This only works (and is only relevant) for POSIX.
 
 def getstatusoutput(cmd):
     """Return (status, output) of executing cmd in a shell.
@@ -602,10 +604,16 @@
     return getstatusoutput(cmd)[1]
 
 
+if mswindows:
+    _PLATFORM_DEFAULT = False
+else:
+    _PLATFORM_DEFAULT = True
+
+
 class Popen(object):
     def __init__(self, args, bufsize=0, executable=None,
                  stdin=None, stdout=None, stderr=None,
-                 preexec_fn=None, close_fds=None, shell=False,
+                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
                  cwd=None, env=None, universal_newlines=False,
                  startupinfo=None, creationflags=0,
                  restore_signals=True, start_new_session=False,
@@ -619,15 +627,6 @@
         if not isinstance(bufsize, int):
             raise TypeError("bufsize must be an integer")
 
-        if close_fds is None:
-            # Notification for http://bugs.python.org/issue7213 & issue2320
-            warnings.warn(
-                    'The close_fds parameter was not specified.  Its default'
-                    ' behavior will change in a future Python version. '
-                    ' Most users should set it to True.  Please'
-                    ' update your code explicitly set close_fds.',
-                    DeprecationWarning)
-
         if mswindows:
             if preexec_fn is not None:
                 raise ValueError("preexec_fn is not supported on Windows "

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Mon Dec 13 07:45:02 2010
@@ -58,22 +58,6 @@
         self.assertEqual(actual, expected, msg)
 
 
-class DeprecationWarningTests(BaseTestCase):
-    def testCloseFdsWarning(self):
-        quick_process = [sys.executable, "-c", "import sys; sys.exit(0)"]
-        with warnings.catch_warnings(record=True) as warnlist:
-            warnings.simplefilter("always")
-            subprocess.call(quick_process, close_fds=True)
-            self.assertEqual([], warnlist)
-            subprocess.call(quick_process, close_fds=False)
-            self.assertEqual([], warnlist)
-            with self.assertWarns(DeprecationWarning) as wm:
-                subprocess.Popen(quick_process).wait()
-                self.assertEqual(1, len(wm.warnings))
-                self.assertIn('close_fds parameter was not specified',
-                              str(wm.warnings[0]))
-
-
 class ProcessTestCase(BaseTestCase):
 
     def test_call_seq(self):
@@ -1250,8 +1234,7 @@
                   ProcessTestCaseNoPoll,
                   HelperFunctionTests,
                   CommandsWithSpaces,
-                  ContextManagerTests,
-                  DeprecationWarningTests)
+                  ContextManagerTests)
 
     support.run_unittest(*unit_tests)
     support.reap_children()

From python-checkins at python.org  Mon Dec 13 08:59:41 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Mon, 13 Dec 2010 08:59:41 +0100 (CET)
Subject: [Python-checkins] r87207 - in python/branches/py3k:
	Lib/subprocess.py Lib/test/subprocessdata
	Lib/test/subprocessdata/fd_status.py
	Lib/test/subprocessdata/input_reader.py
	Lib/test/subprocessdata/qcat.py
	Lib/test/subprocessdata/qgrep.py Lib/test/test_subprocess.py
	Makefile.pre.in Modules/_posixsubprocess.c Tools/msi/msi.py
	configure.in
Message-ID: <20101213075941.79B53EE981@mail.python.org>

Author: gregory.p.smith
Date: Mon Dec 13 08:59:39 2010
New Revision: 87207

Log:
issue7213: Open the pipes used by subprocesses with the FD_CLOEXEC flag from
the C code, using pipe2() when available.  Adds unittests for close_fds and
cloexec behaviors.


Added:
   python/branches/py3k/Lib/test/subprocessdata/
   python/branches/py3k/Lib/test/subprocessdata/fd_status.py
   python/branches/py3k/Lib/test/subprocessdata/input_reader.py
   python/branches/py3k/Lib/test/subprocessdata/qcat.py
   python/branches/py3k/Lib/test/subprocessdata/qgrep.py
Modified:
   python/branches/py3k/Lib/subprocess.py
   python/branches/py3k/Lib/test/test_subprocess.py
   python/branches/py3k/Makefile.pre.in
   python/branches/py3k/Modules/_posixsubprocess.c
   python/branches/py3k/Tools/msi/msi.py
   python/branches/py3k/configure.in

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Mon Dec 13 08:59:39 2010
@@ -390,6 +390,23 @@
     # POSIX defines PIPE_BUF as >= 512.
     _PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
 
+    if _posixsubprocess:
+        _create_pipe = _posixsubprocess.cloexec_pipe
+    else:
+        def _create_pipe():
+            try:
+                cloexec_flag = fcntl.FD_CLOEXEC
+            except AttributeError:
+                cloexec_flag = 1
+
+            fds = os.pipe()
+
+            old = fcntl.fcntl(fds[0], fcntl.F_GETFD)
+            fcntl.fcntl(fds[0], fcntl.F_SETFD, old | cloexec_flag)
+            old = fcntl.fcntl(fds[1], fcntl.F_GETFD)
+            fcntl.fcntl(fds[1], fcntl.F_SETFD, old | cloexec_flag)
+
+            return fds
 
 __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput",
            "getoutput", "check_output", "CalledProcessError"]
@@ -1031,7 +1048,7 @@
             if stdin is None:
                 pass
             elif stdin == PIPE:
-                p2cread, p2cwrite = os.pipe()
+                p2cread, p2cwrite = _create_pipe()
             elif isinstance(stdin, int):
                 p2cread = stdin
             else:
@@ -1041,7 +1058,7 @@
             if stdout is None:
                 pass
             elif stdout == PIPE:
-                c2pread, c2pwrite = os.pipe()
+                c2pread, c2pwrite = _create_pipe()
             elif isinstance(stdout, int):
                 c2pwrite = stdout
             else:
@@ -1051,7 +1068,7 @@
             if stderr is None:
                 pass
             elif stderr == PIPE:
-                errread, errwrite = os.pipe()
+                errread, errwrite = _create_pipe()
             elif stderr == STDOUT:
                 errwrite = c2pwrite
             elif isinstance(stderr, int):
@@ -1065,16 +1082,6 @@
                     errread, errwrite)
 
 
-        def _set_cloexec_flag(self, fd):
-            try:
-                cloexec_flag = fcntl.FD_CLOEXEC
-            except AttributeError:
-                cloexec_flag = 1
-
-            old = fcntl.fcntl(fd, fcntl.F_GETFD)
-            fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
-
-
         def _close_fds(self, but):
             os.closerange(3, but)
             os.closerange(but + 1, MAXFD)
@@ -1116,10 +1123,9 @@
             # For transferring possible exec failure from child to parent.
             # Data format: "exception name:hex errno:description"
             # Pickle is not used; it is complex and involves memory allocation.
-            errpipe_read, errpipe_write = os.pipe()
+            errpipe_read, errpipe_write = _create_pipe()
             try:
                 try:
-                    self._set_cloexec_flag(errpipe_write)
 
                     if _posixsubprocess:
                         # We must avoid complex work that could involve

Added: python/branches/py3k/Lib/test/subprocessdata/fd_status.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/subprocessdata/fd_status.py	Mon Dec 13 08:59:39 2010
@@ -0,0 +1,24 @@
+"""When called as a script, print a comma-separated list of the open
+file descriptors on stdout."""
+
+import errno
+import os
+import fcntl
+
+try:
+    _MAXFD = os.sysconf("SC_OPEN_MAX")
+except:
+    _MAXFD = 256
+
+def isopen(fd):
+    """Return True if the fd is open, and False otherwise"""
+    try:
+        fcntl.fcntl(fd, fcntl.F_GETFD, 0)
+    except IOError as e:
+        if e.errno == errno.EBADF:
+            return False
+        raise
+    return True
+
+if __name__ == "__main__":
+    print(','.join(str(fd) for fd in range(0, _MAXFD) if isopen(fd)))

Added: python/branches/py3k/Lib/test/subprocessdata/input_reader.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/subprocessdata/input_reader.py	Mon Dec 13 08:59:39 2010
@@ -0,0 +1,7 @@
+"""When called as a script, consumes the input"""
+
+import sys
+
+if __name__ = "__main__":
+    for line in sys.stdin:
+        pass

Added: python/branches/py3k/Lib/test/subprocessdata/qcat.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/subprocessdata/qcat.py	Mon Dec 13 08:59:39 2010
@@ -0,0 +1,7 @@
+"""When ran as a script, simulates cat with no arguments."""
+
+import sys
+
+if __name__ == "__main__":
+    for line in sys.stdin:
+        sys.stdout.write(line)

Added: python/branches/py3k/Lib/test/subprocessdata/qgrep.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/subprocessdata/qgrep.py	Mon Dec 13 08:59:39 2010
@@ -0,0 +1,10 @@
+"""When called with a single argument, simulated fgrep with a single
+argument and no options."""
+
+import sys
+
+if __name__ == "__main__":
+    pattern = sys.argv[1]
+    for line in sys.stdin:
+        if pattern in line:
+            sys.stdout.write(line)

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Mon Dec 13 08:59:39 2010
@@ -10,6 +10,7 @@
 import re
 import sysconfig
 import warnings
+import select
 try:
     import gc
 except ImportError:
@@ -964,6 +965,83 @@
         exitcode = subprocess.call([program, "-c", "pass"], env=envb)
         self.assertEqual(exitcode, 0)
 
+    def test_pipe_cloexec(self):
+        sleeper = support.findfile("input_reader.py", subdir="subprocessdata")
+        fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
+
+        p1 = subprocess.Popen([sys.executable, sleeper],
+                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE, close_fds=False)
+
+        self.addCleanup(p1.communicate, b'')
+
+        p2 = subprocess.Popen([sys.executable, fd_status],
+                              stdout=subprocess.PIPE, close_fds=False)
+
+        output, error = p2.communicate()
+        result_fds = set(map(int, output.split(b',')))
+        unwanted_fds = set([p1.stdin.fileno(), p1.stdout.fileno(),
+                            p1.stderr.fileno()])
+
+        self.assertFalse(result_fds & unwanted_fds,
+                         "Expected no fds from %r to be open in child, "
+                         "found %r" %
+                              (unwanted_fds, result_fds & unwanted_fds))
+
+    def test_pipe_cloexec_real_tools(self):
+        qcat = support.findfile("qcat.py", subdir="subprocessdata")
+        qgrep = support.findfile("qgrep.py", subdir="subprocessdata")
+
+        subdata = b'zxcvbn'
+        data = subdata * 4 + b'\n'
+
+        p1 = subprocess.Popen([sys.executable, qcat],
+                              stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                              close_fds=False)
+
+        p2 = subprocess.Popen([sys.executable, qgrep, subdata],
+                              stdin=p1.stdout, stdout=subprocess.PIPE,
+                              close_fds=False)
+
+        self.addCleanup(p1.wait)
+        self.addCleanup(p2.wait)
+        self.addCleanup(p1.terminate)
+        self.addCleanup(p2.terminate)
+
+        p1.stdin.write(data)
+        p1.stdin.close()
+
+        readfiles, ignored1, ignored2 = select.select([p2.stdout], [], [], 10)
+
+        self.assertTrue(readfiles, "The child hung")
+        self.assertEqual(p2.stdout.read(), data)
+
+    def test_close_fds(self):
+        fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
+
+        fds = os.pipe()
+        self.addCleanup(os.close, fds[0])
+        self.addCleanup(os.close, fds[1])
+
+        open_fds = set(fds)
+
+        p = subprocess.Popen([sys.executable, fd_status],
+                             stdout=subprocess.PIPE, close_fds=False)
+        output, ignored = p.communicate()
+        remaining_fds = set(map(int, output.split(b',')))
+
+        self.assertEqual(remaining_fds & open_fds, open_fds,
+                         "Some fds were closed")
+
+        p = subprocess.Popen([sys.executable, fd_status],
+                             stdout=subprocess.PIPE, close_fds=True)
+        output, ignored = p.communicate()
+        remaining_fds = set(map(int, output.split(b',')))
+
+        self.assertFalse(remaining_fds & open_fds,
+                         "Some fds were left open")
+        self.assertIn(1, remaining_fds, "Subprocess failed")
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Mon Dec 13 08:59:39 2010
@@ -888,7 +888,7 @@
 XMLLIBSUBDIRS=  xml xml/dom xml/etree xml/parsers xml/sax
 LIBSUBDIRS=	tkinter tkinter/test tkinter/test/test_tkinter \
                 tkinter/test/test_ttk site-packages test \
-		test/decimaltestdata test/xmltestdata \
+		test/decimaltestdata test/xmltestdata test/subprocessdata \
 		test/tracedmodules test/encoded_modules \
 		concurrent concurrent/futures encodings \
 		email email/mime email/test email/test/data \

Modified: python/branches/py3k/Modules/_posixsubprocess.c
==============================================================================
--- python/branches/py3k/Modules/_posixsubprocess.c	(original)
+++ python/branches/py3k/Modules/_posixsubprocess.c	Mon Dec 13 08:59:39 2010
@@ -1,6 +1,10 @@
 /* Authors: Gregory P. Smith & Jeffrey Yasskin */
 #include "Python.h"
+#ifdef HAVE_PIPE2
+#define _GNU_SOURCE
+#endif
 #include 
+#include 
 
 
 #define POSIX_CALL(call)   if ((call) == -1) goto error
@@ -398,6 +402,45 @@
 Raises: Only on an error in the parent process.\n\
 ");
 
+PyDoc_STRVAR(subprocess_cloexec_pipe_doc,
+"cloexec_pipe() -> (read_end, write_end)\n\n\
+Create a pipe whose ends have the cloexec flag set.");
+
+static PyObject *
+subprocess_cloexec_pipe(PyObject *self, PyObject *noargs)
+{
+    int fds[2];
+    int res;
+#ifdef HAVE_PIPE2
+    Py_BEGIN_ALLOW_THREADS
+    res = pipe2(fds, O_CLOEXEC);
+    Py_END_ALLOW_THREADS
+#else
+    /* We hold the GIL which offers some protection from other code calling
+     * fork() before the CLOEXEC flags have been set but we can't guarantee
+     * anything without pipe2(). */
+    long oldflags;
+
+    res = pipe(fds);
+
+    if (res == 0) {
+        oldflags = fcntl(fds[0], F_GETFD, 0);
+        if (oldflags < 0) res = oldflags;
+    }
+    if (res == 0)
+        res = fcntl(fds[0], F_SETFD, oldflags | FD_CLOEXEC);
+
+    if (res == 0) {
+        oldflags = fcntl(fds[1], F_GETFD, 0);
+        if (oldflags < 0) res = oldflags;
+    }
+    if (res == 0)
+        res = fcntl(fds[1], F_SETFD, oldflags | FD_CLOEXEC);
+#endif
+    if (res != 0)
+        return PyErr_SetFromErrno(PyExc_OSError);
+    return Py_BuildValue("(ii)", fds[0], fds[1]);
+}
 
 /* module level code ********************************************************/
 
@@ -407,6 +450,7 @@
 
 static PyMethodDef module_methods[] = {
     {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
+    {"cloexec_pipe", subprocess_cloexec_pipe, METH_NOARGS, subprocess_cloexec_pipe_doc},
     {NULL, NULL}  /* sentinel */
 };
 

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Mon Dec 13 08:59:39 2010
@@ -1035,6 +1035,8 @@
         if dir=='xmltestdata':
             lib.glob("*.xml")
             lib.add_file("test.xml.out")
+        if dir=='subprocessdata':
+            lib.glob("*.py")
         if dir=='output':
             lib.glob("test_*")
         if dir=='sndhdrdata':

Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in	(original)
+++ python/branches/py3k/configure.in	Mon Dec 13 08:59:39 2010
@@ -4235,7 +4235,7 @@
   OSF*) AC_MSG_ERROR(OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606) ;;
 esac
 
-
+AC_CHECK_FUNC(pipe2, AC_DEFINE(HAVE_PIPE2, 1, [Define if the OS supports pipe2()]), )
 
 AC_SUBST(THREADHEADERS)
 

From python-checkins at python.org  Mon Dec 13 09:00:52 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Mon, 13 Dec 2010 09:00:52 +0100 (CET)
Subject: [Python-checkins] r87208 - python/branches/py3k/configure
Message-ID: <20101213080052.9C8F8EE981@mail.python.org>

Author: gregory.p.smith
Date: Mon Dec 13 09:00:52 2010
New Revision: 87208

Log:
regenerate configure based on r87207.


Modified:
   python/branches/py3k/configure

Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure	(original)
+++ python/branches/py3k/configure	Mon Dec 13 09:00:52 2010
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision.
+# From configure.in Revision: 87207 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.67 for python 3.2.
 #
@@ -13735,6 +13735,12 @@
   OSF*) as_fn_error $? "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5  ;;
 esac
 
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = x""yes; then :
+
+$as_echo "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
 
 
 

From python-checkins at python.org  Mon Dec 13 09:07:14 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Mon, 13 Dec 2010 09:07:14 +0100 (CET)
Subject: [Python-checkins] r87209 - python/branches/py3k/Misc/NEWS
Message-ID: <20101213080714.4486BEE981@mail.python.org>

Author: gregory.p.smith
Date: Mon Dec 13 09:07:14 2010
New Revision: 87209

Log:
Mention the subprocess.Popen close_fds default change.  Fixup *s to -s.


Modified:
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Dec 13 09:07:14 2010
@@ -11,13 +11,17 @@
 Library
 -------
 
-* Issue #10188 (partial resolution): tempfile.TemporaryDirectory emits
+- Issue #10188 (partial resolution): tempfile.TemporaryDirectory emits
   a warning on sys.stderr rather than throwing a misleading exception
   if cleanup fails due to nulling out of modules during shutdown.
   Also avoids an AttributeError when mkdtemp call fails and issues
   a ResourceWarning on implicit cleanup via __del__.
 
-* Issue #10107: Warn about unsaved files in IDLE on OSX.
+- Issue #10107: Warn about unsaved files in IDLE on OSX.
+
+- Issue #7213: subprocess.Popen's default for close_fds has been changed.
+  It is now platform specific, keeping its default of False on Windows and
+  changing the default to True on POSIX and other platforms.
 
 
 What's New in Python 3.2 Beta 1?

From python-checkins at python.org  Mon Dec 13 09:54:02 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Dec 2010 09:54:02 +0100 (CET)
Subject: [Python-checkins] r87210 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101213085402.B6348EE9B1@mail.python.org>

Author: vinay.sajip
Date: Mon Dec 13 09:54:02 2010
New Revision: 87210

Log:
Logging documentatio update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Mon Dec 13 09:54:02 2010
@@ -167,7 +167,8 @@
    # command line argument. Convert to upper case to allow the user to
    # specify --log=DEBUG or --log=debug
    numeric_level = getattr(logging, loglevel.upper(), None)
-   assert numeric_level is not None, 'Invalid log level: %s' % loglevel
+   if not isinstance(numeric_level, int):
+       raise ValueError('Invalid log level: %s' % loglevel)
    logging.basicConfig(level=numeric_level, ...)
 
 The call to :func:`basicConfig` should come *before* any calls to :func:`debug`,

From vinay_sajip at yahoo.co.uk  Mon Dec 13 09:25:09 2010
From: vinay_sajip at yahoo.co.uk (Vinay Sajip)
Date: Mon, 13 Dec 2010 08:25:09 +0000 (UTC)
Subject: [Python-checkins]
	=?utf-8?q?r87202_-=09python/branches/py3k/Doc/l?=
	=?utf-8?q?ibrary/logging=2Erst?=
References: <20101212224535.C828DEE995@mail.python.org>
	
Message-ID: 

Nick Coghlan  gmail.com> writes:

> Minor nit - using asserts to check user input is generally a bad idea.
> A more explicit check might be a better example:
> 
> if not isinstance(numeric_level, int):
>    raise ValueError('Invalid log level: %s' % loglevel)
> 

You're right, of course - I was being a bit lazy, after a long day :-)

Regards,

Vinay


From python-checkins at python.org  Mon Dec 13 14:07:34 2010
From: python-checkins at python.org (lukasz.langa)
Date: Mon, 13 Dec 2010 14:07:34 +0100 (CET)
Subject: [Python-checkins] r87211 - peps/trunk/pep-0392.txt
Message-ID: <20101213130734.59FD3EE989@mail.python.org>

Author: lukasz.langa
Date: Mon Dec 13 14:07:34 2010
New Revision: 87211

Log:
RC1 is obviously in 2011



Modified:
   peps/trunk/pep-0392.txt

Modified: peps/trunk/pep-0392.txt
==============================================================================
--- peps/trunk/pep-0392.txt	(original)
+++ peps/trunk/pep-0392.txt	Mon Dec 13 14:07:34 2010
@@ -43,7 +43,7 @@
 (No new features beyond this point.)
 
 - 3.2 beta 2: December 18, 2010
-- 3.2 candidate 1: January 8, 2010
+- 3.2 candidate 1: January 8, 2011
 - 3.2 candidate 2: January 22, 2011
 - 3.2 final: February 5, 2011
 

From python-checkins at python.org  Mon Dec 13 17:33:00 2010
From: python-checkins at python.org (nick.coghlan)
Date: Mon, 13 Dec 2010 17:33:00 +0100 (CET)
Subject: [Python-checkins] r87212 -
	python/branches/py3k/Lib/test/test_tempfile.py
Message-ID: <20101213163300.44CBAEE981@mail.python.org>

Author: nick.coghlan
Date: Mon Dec 13 17:32:51 2010
New Revision: 87212

Log:
Captured IO streams with embedded backslashes are always such a fun combination...

Modified:
   python/branches/py3k/Lib/test/test_tempfile.py

Modified: python/branches/py3k/Lib/test/test_tempfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_tempfile.py	(original)
+++ python/branches/py3k/Lib/test/test_tempfile.py	Mon Dec 13 17:32:51 2010
@@ -989,7 +989,13 @@
         #   Issue 10888: may write to stderr if modules are nulled out
         #   ResourceWarning will be triggered by __del__
         with self.do_create() as dir:
-            d = self.do_create(dir=dir)
+            if os.sep != '\\':
+                # Embed a backslash in order to make sure string escaping
+                # in the displayed error message is dealt with correctly
+                suffix = '\\check_backslash_handling'
+            else:
+                suffix = ''
+            d = self.do_create(dir=dir, suf=suffix)
 
             #Check for the Issue 10888 message
             modules = [os, os.path]
@@ -998,7 +1004,7 @@
             with support.captured_stderr() as err:
                 with NulledModules(*modules):
                     d.cleanup()
-            message = err.getvalue()
+            message = err.getvalue().replace('\\\\', '\\')
             self.assertIn("while cleaning up",  message)
             self.assertIn(d.name,  message)
 

From python-checkins at python.org  Mon Dec 13 19:04:23 2010
From: python-checkins at python.org (barry.warsaw)
Date: Mon, 13 Dec 2010 19:04:23 +0100 (CET)
Subject: [Python-checkins] r87213 - in python/branches/py3k:
	Lib/test/subprocessdata/input_reader.py Makefile.pre.in
Message-ID: <20101213180424.0EA7DEE981@mail.python.org>

Author: barry.warsaw
Date: Mon Dec 13 19:04:23 2010
New Revision: 87213

Log:
Issue 10687.  When --without-pymalloc is given, $VERSION is the same as
$LDVERSION, which screws up the sym/hard-links.  This avoids those games when
$VERSION == $LDVERSION.

Also, include a drive-by fix for an obvious syntax error.


Modified:
   python/branches/py3k/Lib/test/subprocessdata/input_reader.py
   python/branches/py3k/Makefile.pre.in

Modified: python/branches/py3k/Lib/test/subprocessdata/input_reader.py
==============================================================================
--- python/branches/py3k/Lib/test/subprocessdata/input_reader.py	(original)
+++ python/branches/py3k/Lib/test/subprocessdata/input_reader.py	Mon Dec 13 19:04:23 2010
@@ -2,6 +2,6 @@
 
 import sys
 
-if __name__ = "__main__":
+if __name__ == "__main__":
     for line in sys.stdin:
         pass

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Mon Dec 13 19:04:23 2010
@@ -836,11 +836,12 @@
 		fi; \
 	done
 	$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE)
-	-if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE); \
-	then rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \
-	else true; \
+	-if test "$(VERSION)" != "$(LDVERSION)"; then \
+		if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)$(VERSION)$(EXE); \
+		then rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \
+		fi; \
+		(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE)); \
 	fi
-	(cd $(DESTDIR)$(BINDIR); $(LN) python$(LDVERSION)$(EXE) python$(VERSION)$(EXE))
 	if test -f $(LDLIBRARY); then \
 		if test -n "$(DLLLIBRARY)" ; then \
 			$(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \
@@ -859,14 +860,16 @@
 	else true; \
 	fi
 	(cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3$(EXE))
+	-if test "$(VERSION)" != "$(LDVERSION)"; then \
+		rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-config; \
+		(cd $(DESTDIR)$(BINDIR); $(LN) -s python$(LDVERSION)-config python$(VERSION)-config); \
+		rm -f $(DESTDIR)$(LIBPC)/python-$(LDVERSION).pc; \
+		(cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python-$(LDVERSION).pc); \
+	fi
 	-rm -f $(DESTDIR)$(BINDIR)/python3-config
-	-rm -f $(DESTDIR)$(BINDIR)/python$(VERSION)-config
-	(cd $(DESTDIR)$(BINDIR); $(LN) -s python$(LDVERSION)-config python$(VERSION)-config)
 	(cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python3-config)
 	-rm -f $(DESTDIR)$(LIBPC)/python3.pc
-	-rm -f $(DESTDIR)$(LIBPC)/python-$(LDVERSION).pc
 	(cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python3.pc)
-	(cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python-$(LDVERSION).pc)
 
 # Install the manual page
 maninstall:
@@ -1307,3 +1310,6 @@
 .PHONY: gdbhooks
 
 # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+# Local Variables:
+# mode: makefile
+# End:

From python-checkins at python.org  Mon Dec 13 19:43:58 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Dec 2010 19:43:58 +0100 (CET)
Subject: [Python-checkins] r87214 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101213184358.A67EAEE9FE@mail.python.org>

Author: vinay.sajip
Date: Mon Dec 13 19:43:57 2010
New Revision: 87214

Log:
Logging documentation update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Mon Dec 13 19:43:57 2010
@@ -270,10 +270,11 @@
 
 Notice that the 'root' which appeared in earlier examples has disappeared. For
 a full set of things that can appear in format strings, you can refer to the
-documentation for :ref:`formatter-objects`, but for simple usage, you just need
-the *levelname* (severity), *message* (event description, including variable
-data) and perhaps to display when the event occurred. This is described in the
-next section.
+documentation for :ref:`logrecord-attributes`, but for simple usage, you just
+need the *levelname* (severity), *message* (event description, including
+variable data) and perhaps to display when the event occurred. This is
+described in the next section.
+
 
 Displaying the date/time in messages
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -524,10 +525,10 @@
 
 If the ``style`` is '%', the message format string uses
 ``%()s`` styled string substitution; the possible keys are
-documented in :ref:`formatter-objects`. If the style is '{', the message format
-string is assumed to be compatible with :meth:`str.format` (using keyword
-arguments), while if the style is '$' then the message format string should
-conform to what is expected by :meth:`string.Template.substitute`.
+documented in :ref:`logrecord-attributes`. If the style is '{', the message
+format string is assumed to be compatible with :meth:`str.format` (using
+keyword arguments), while if the style is '$' then the message format string
+should conform to what is expected by :meth:`string.Template.substitute`.
 
 .. versionchanged:: 3.2
    Added the ``style`` parameter.
@@ -3260,7 +3261,9 @@
 module, supports receiving logging messages from a queue, such as those
 implemented in the :mod:`queue` or :mod:`multiprocessing` modules. The
 messages are received from a queue in an internal thread and passed, on
-the same thread, to one or more handlers for processing.
+the same thread, to one or more handlers for processing. While
+:class:`QueueListener` is not itself a handler, it is documented here
+because it works hand-in-hand with :class:`QueueHandler`.
 
 Along with the :class:`QueueHandler` class, :class:`QueueListener` can be used
 to let handlers do their work on a separate thread from the one which does the
@@ -3384,7 +3387,7 @@
 
 .. currentmodule:: logging
 
-:class:`Formatter`\ s have the following attributes and methods. They are
+:class:`Formatter` objects have the following attributes and methods. They are
 responsible for converting a :class:`LogRecord` to (usually) a string which can
 be interpreted by either a human or an external system. The base
 :class:`Formatter` allows a formatting string to be specified. If none is
@@ -3397,61 +3400,8 @@
 standard Python %-style mapping keys. See section :ref:`old-string-formatting`
 for more information on string formatting.
 
-Currently, the useful mapping keys in a :class:`LogRecord` are:
-
-+-------------------------+-----------------------------------------------+
-| Format                  | Description                                   |
-+=========================+===============================================+
-| ``%(name)s``            | Name of the logger (logging channel).         |
-+-------------------------+-----------------------------------------------+
-| ``%(levelno)s``         | Numeric logging level for the message         |
-|                         | (:const:`DEBUG`, :const:`INFO`,               |
-|                         | :const:`WARNING`, :const:`ERROR`,             |
-|                         | :const:`CRITICAL`).                           |
-+-------------------------+-----------------------------------------------+
-| ``%(levelname)s``       | Text logging level for the message            |
-|                         | (``'DEBUG'``, ``'INFO'``, ``'WARNING'``,      |
-|                         | ``'ERROR'``, ``'CRITICAL'``).                 |
-+-------------------------+-----------------------------------------------+
-| ``%(pathname)s``        | Full pathname of the source file where the    |
-|                         | logging call was issued (if available).       |
-+-------------------------+-----------------------------------------------+
-| ``%(filename)s``        | Filename portion of pathname.                 |
-+-------------------------+-----------------------------------------------+
-| ``%(module)s``          | Module (name portion of filename).            |
-+-------------------------+-----------------------------------------------+
-| ``%(funcName)s``        | Name of function containing the logging call. |
-+-------------------------+-----------------------------------------------+
-| ``%(lineno)d``          | Source line number where the logging call was |
-|                         | issued (if available).                        |
-+-------------------------+-----------------------------------------------+
-| ``%(created)f``         | Time when the :class:`LogRecord` was created  |
-|                         | (as returned by :func:`time.time`).           |
-+-------------------------+-----------------------------------------------+
-| ``%(relativeCreated)d`` | Time in milliseconds when the LogRecord was   |
-|                         | created, relative to the time the logging     |
-|                         | module was loaded.                            |
-+-------------------------+-----------------------------------------------+
-| ``%(asctime)s``         | Human-readable time when the                  |
-|                         | :class:`LogRecord` was created.  By default   |
-|                         | this is of the form "2003-07-08 16:49:45,896" |
-|                         | (the numbers after the comma are millisecond  |
-|                         | portion of the time).                         |
-+-------------------------+-----------------------------------------------+
-| ``%(msecs)d``           | Millisecond portion of the time when the      |
-|                         | :class:`LogRecord` was created.               |
-+-------------------------+-----------------------------------------------+
-| ``%(thread)d``          | Thread ID (if available).                     |
-+-------------------------+-----------------------------------------------+
-| ``%(threadName)s``      | Thread name (if available).                   |
-+-------------------------+-----------------------------------------------+
-| ``%(process)d``         | Process ID (if available).                    |
-+-------------------------+-----------------------------------------------+
-| ``%(processName)s``     | Process name (if available).                  |
-+-------------------------+-----------------------------------------------+
-| ``%(message)s``         | The logged message, computed as ``msg %       |
-|                         | args``.                                       |
-+-------------------------+-----------------------------------------------+
+The useful mapping keys in a :class:`LogRecord` are given in the section on
+:ref:`logrecord-attributes`.
 
 
 .. class:: Formatter(fmt=None, datefmt=None)
@@ -3577,7 +3527,7 @@
 wire).
 
 
-.. class:: LogRecord(name, levelno, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
+.. class:: LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)
 
    Contains all the information pertinent to the event being logged.
 
@@ -3585,50 +3535,23 @@
    are combined using ``msg % args`` to create the :attr:`message` field of the
    record.
 
-   .. attribute:: args
-
-      Tuple of arguments to be used in formatting :attr:`msg`.
-
-   .. attribute:: exc_info
-
-      Exception tuple (? la :func:`sys.exc_info`) or ``None`` if no exception
-      information is available.
-
-   .. attribute:: func
-
-      Name of the function of origin (i.e. in which the logging call was made).
-
-   .. attribute:: lineno
-
-      Line number in the source file of origin.
-
-   .. attribute:: levelno
-
-      Numeric logging level.
-
-   .. attribute:: message
-
-      Bound to the result of :meth:`getMessage` when
-      :meth:`Formatter.format(record)` is invoked.
-
-   .. attribute:: msg
-
-      User-supplied :ref:`format string` or arbitrary object
-      (see :ref:`arbitrary-object-messages`) used in :meth:`getMessage`.
-
-   .. attribute:: name
-
-      Name of the logger that emitted the record.
-
-   .. attribute:: pathname
-
-      Absolute pathname of the source file of origin.
-
-   .. attribute:: stack_info
-
-      Stack frame information (where available) from the bottom of the stack
-      in the current thread, up to and including the stack frame of the
-      logging call which resulted in the creation of this record.
+   :param name:  The name of the logger used to log the event represented by
+                 this LogRecord.
+   :param level: The numeric level of the logging event (one of DEBUG, INFO etc.)
+   :param pathname: The full pathname of the source file where the logging call
+                    was made.
+   :param lineno: The line number in the source file where the logging call was
+                  made.
+   :param msg: The event description message, possibly a format string with
+               placeholders for variable data.
+   :param args: Variable data to merge into the *msg* argument to obtain the
+                event description.
+   :param exc_info: An exception tuple with the current exception information,
+                    or *None* if no exception information is available.
+   :param func: The name of the function or method from which the logging call
+                was invoked.
+   :param sinfo: A text string representing stack information from the base of
+                 the stack in the current thread, up to the logging call.
 
    .. method:: getMessage()
 
@@ -3663,6 +3586,101 @@
    surprises.
 
 
+.. _logrecord-attributes:
+
+``LogRecord`` attributes
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The LogRecord has a number of attributes, most of which are derived from the
+parameters to the constructor. (Note that the names do not always correspond
+exactly between the LogRecord constructor parameters and the LogRecord
+attributes.) These attributes can be used to merge data from the record into
+the format string. The following table lists (in alphabetical order) the
+attribute names, their meanings and the corresponding placeholder in a %-style
+format string.
+
+If you are using {}-formatting (:func:`str.format`), you can use
+``{{attrname}}`` as the placeholder in the format string. If you are using
+$-formatting (:class:`string.Template`), use the form ``${attrname}``. In
+both cases, of course, replace ``attrname`` with the actual attribute name
+you want to use.
+
+In the case of {}-formatting, you can specify formatting flags by placing them
+after the attribute name, separated from it with a colon.
+
++----------------+-------------------------+-----------------------------------------------+
+| Attribute name | Format                  | Description                                   |
++================+=========================+===============================================+
+| args           | You shouldn't need to   | The tuple of arguments merged into ``msg`` to |
+|                | format this yourself.   | produce ``message``.                          |
++----------------+-------------------------+-----------------------------------------------+
+| asctime        | ``%(asctime)s``         | Human-readable time when the                  |
+|                |                         | :class:`LogRecord` was created.  By default   |
+|                |                         | this is of the form "2003-07-08 16:49:45,896" |
+|                |                         | (the numbers after the comma are millisecond  |
+|                |                         | portion of the time).                         |
++----------------+-------------------------+-----------------------------------------------+
+| created        | ``%(created)f``         | Time when the :class:`LogRecord` was created  |
+|                |                         | (as returned by :func:`time.time`).           |
++----------------+-------------------------+-----------------------------------------------+
+| exc_info       | You shouldn't need to   | Exception tuple (? la ``sys.exc_info``) or,   |
+|                | format this yourself.   | if no exception has occurred, *None*.         |
++----------------+-------------------------+-----------------------------------------------+
+| filename       | ``%(filename)s``        | Filename portion of ``pathname``.             |
++----------------+-------------------------+-----------------------------------------------+
+| funcName       | ``%(funcName)s``        | Name of function containing the logging call. |
++----------------+-------------------------+-----------------------------------------------+
+| levelname      | ``%(levelname)s``       | Text logging level for the message            |
+|                |                         | (``'DEBUG'``, ``'INFO'``, ``'WARNING'``,      |
+|                |                         | ``'ERROR'``, ``'CRITICAL'``).                 |
++----------------+-------------------------+-----------------------------------------------+
+| levelno        | ``%(levelno)s``         | Numeric logging level for the message         |
+|                |                         | (:const:`DEBUG`, :const:`INFO`,               |
+|                |                         | :const:`WARNING`, :const:`ERROR`,             |
+|                |                         | :const:`CRITICAL`).                           |
++----------------+-------------------------+-----------------------------------------------+
+| lineno         | ``%(lineno)d``          | Source line number where the logging call was |
+|                |                         | issued (if available).                        |
++----------------+-------------------------+-----------------------------------------------+
+| module         | ``%(module)s``          | Module (name portion of ``filename``).        |
++----------------+-------------------------+-----------------------------------------------+
+| msecs          | ``%(msecs)d``           | Millisecond portion of the time when the      |
+|                |                         | :class:`LogRecord` was created.               |
++----------------+-------------------------+-----------------------------------------------+
+| message        | ``%(message)s``         | The logged message, computed as ``msg %       |
+|                |                         | args``. This is set when                      |
+|                |                         | :meth:`Formatter.format` is invoked.          |
++----------------+-------------------------+-----------------------------------------------+
+| msg            | You shouldn't need to   | The format string passed in the original      |
+|                | format this yourself.   | logging call. Merged with ``args`` to         |
+|                |                         | produce ``message``, or an arbitrary object   |
+|                |                         | (see :ref:`arbitrary-object-messages`).       |
++----------------+-------------------------+-----------------------------------------------+
+| name           | ``%(name)s``            | Name of the logger used to log the call.      |
++----------------+-------------------------+-----------------------------------------------+
+| pathname       | ``%(pathname)s``        | Full pathname of the source file where the    |
+|                |                         | logging call was issued (if available).       |
++----------------+-------------------------+-----------------------------------------------+
+| process        | ``%(process)d``         | Process ID (if available).                    |
++----------------+-------------------------+-----------------------------------------------+
+| processName    | ``%(processName)s``     | Process name (if available).                  |
++----------------+-------------------------+-----------------------------------------------+
+| relativeCreated| ``%(relativeCreated)d`` | Time in milliseconds when the LogRecord was   |
+|                |                         | created, relative to the time the logging     |
+|                |                         | module was loaded.                            |
++----------------+-------------------------+-----------------------------------------------+
+| stack_info     | You shouldn't need to   | Stack frame information (where available)     |
+|                | format this yourself.   | from the bottom of the stack in the current   |
+|                |                         | thread, up to and including the stack frame   |
+|                |                         | of the logging call which resulted in the     |
+|                |                         | creation of this record.                      |
++----------------+-------------------------+-----------------------------------------------+
+| thread         | ``%(thread)d``          | Thread ID (if available).                     |
++----------------+-------------------------+-----------------------------------------------+
+| threadName     | ``%(threadName)s``      | Thread name (if available).                   |
++----------------+-------------------------+-----------------------------------------------+
+
+
 .. _logger-adapter:
 
 LoggerAdapter Objects

From python-checkins at python.org  Mon Dec 13 19:49:08 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Dec 2010 19:49:08 +0100 (CET)
Subject: [Python-checkins] r87215 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101213184908.EFED6EE9C3@mail.python.org>

Author: vinay.sajip
Date: Mon Dec 13 19:49:08 2010
New Revision: 87215

Log:
Logging documentation update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Mon Dec 13 19:49:08 2010
@@ -3600,13 +3600,16 @@
 format string.
 
 If you are using {}-formatting (:func:`str.format`), you can use
-``{{attrname}}`` as the placeholder in the format string. If you are using
+``{attrname}`` as the placeholder in the format string. If you are using
 $-formatting (:class:`string.Template`), use the form ``${attrname}``. In
 both cases, of course, replace ``attrname`` with the actual attribute name
 you want to use.
 
 In the case of {}-formatting, you can specify formatting flags by placing them
-after the attribute name, separated from it with a colon.
+after the attribute name, separated from it with a colon. For example: a
+placeholder of ``{msecs:03d}`` would format a millisecond value of ``4`` as
+``004``. Refer to the :meth:`str.format` documentation for full details on
+the options available to you.
 
 +----------------+-------------------------+-----------------------------------------------+
 | Attribute name | Format                  | Description                                   |

From python-checkins at python.org  Mon Dec 13 23:50:30 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon, 13 Dec 2010 23:50:30 +0100 (CET)
Subject: [Python-checkins] r87216 -
	python/branches/py3k/Doc/library/doctest.rst
Message-ID: <20101213225030.86205EE993@mail.python.org>

Author: r.david.murray
Date: Mon Dec 13 23:50:30 2010
New Revision: 87216

Log:
#10698: fix typo in example.


Modified:
   python/branches/py3k/Doc/library/doctest.rst

Modified: python/branches/py3k/Doc/library/doctest.rst
==============================================================================
--- python/branches/py3k/Doc/library/doctest.rst	(original)
+++ python/branches/py3k/Doc/library/doctest.rst	Mon Dec 13 23:50:30 2010
@@ -922,7 +922,7 @@
 
    def load_tests(loader, tests, ignore):
        tests.addTests(doctest.DocTestSuite(my_module_with_doctests))
-       return test
+       return tests
 
 There are two main functions for creating :class:`unittest.TestSuite` instances
 from text files and modules with doctests:

From python-checkins at python.org  Tue Dec 14 00:51:20 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 00:51:20 +0100 (CET)
Subject: [Python-checkins] r87217 - in python/branches/py3k:
	Doc/library/email.message.rst Lib/email/message.py
	Lib/email/test/test_email.py Misc/NEWS
Message-ID: <20101213235120.59C58EE993@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 00:51:19 2010
New Revision: 87217

Log:
#1078919: make add_header automatically do RFC2231 encoding when needed.

Also document the use of three-tuples if control of the charset
and language is desired.


Modified:
   python/branches/py3k/Doc/library/email.message.rst
   python/branches/py3k/Lib/email/message.py
   python/branches/py3k/Lib/email/test/test_email.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/email.message.rst
==============================================================================
--- python/branches/py3k/Doc/library/email.message.rst	(original)
+++ python/branches/py3k/Doc/library/email.message.rst	Tue Dec 14 00:51:19 2010
@@ -270,7 +270,15 @@
       taken as the parameter name, with underscores converted to dashes (since
       dashes are illegal in Python identifiers).  Normally, the parameter will
       be added as ``key="value"`` unless the value is ``None``, in which case
-      only the key will be added.
+      only the key will be added.  If the value contains non-ASCII characters,
+      it can be specified as a three tuple in the format
+      ``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string naming the
+      charset to be used to encode the value, ``LANGUAGE`` can usually be set
+      to ``None`` or the empty string (see :RFC:`2231` for other possibilities),
+      and ``VALUE`` is the string value containing non-ASCII code points.  If
+      a three tuple is not passed and the value contains non-ASCII characters,
+      it is automatically encoded in :RFC`2231` format using a ``CHARSET``
+      of ``utf-8`` and a ``LANGUAGE`` of ``None``.
 
       Here's an example::
 
@@ -280,6 +288,15 @@
 
          Content-Disposition: attachment; filename="bud.gif"
 
+      An example with with non-ASCII characters::
+
+         msg.add_header('Content-Disposition', 'attachment',
+                        filename=('iso-8859-1', '', 'Fu?baller.ppt'))
+
+      Which produces ::
+
+         Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
+
 
    .. method:: replace_header(_name, _value)
 
@@ -369,7 +386,7 @@
       :rfc:`2231`, you can collapse the parameter value by calling
       :func:`email.utils.collapse_rfc2231_value`, passing in the return value
       from :meth:`get_param`.  This will return a suitably decoded Unicode
-      string whn the value is a tuple, or the original string unquoted if it
+      string when the value is a tuple, or the original string unquoted if it
       isn't.  For example::
 
          rawparam = msg.get_param('foo')

Modified: python/branches/py3k/Lib/email/message.py
==============================================================================
--- python/branches/py3k/Lib/email/message.py	(original)
+++ python/branches/py3k/Lib/email/message.py	Tue Dec 14 00:51:19 2010
@@ -57,7 +57,11 @@
 def _formatparam(param, value=None, quote=True):
     """Convenience function to format and return a key=value pair.
 
-    This will quote the value if needed or if quote is true.
+    This will quote the value if needed or if quote is true.  If value is a
+    three tuple (charset, language, value), it will be encoded according
+    to RFC2231 rules.  If it contains non-ascii characters it will likewise
+    be encoded according to RFC2231 rules, using the utf-8 charset and
+    a null language.
     """
     if value is not None and len(value) > 0:
         # A tuple is used for RFC 2231 encoded parameter values where items
@@ -67,6 +71,12 @@
             # Encode as per RFC 2231
             param += '*'
             value = utils.encode_rfc2231(value[2], value[0], value[1])
+        else:
+            try:
+                value.encode('ascii')
+            except UnicodeEncodeError:
+                param += '*'
+                value = utils.encode_rfc2231(value, 'utf-8', '')
         # BAW: Please check this.  I think that if quote is set it should
         # force quoting even if not necessary.
         if quote or tspecials.search(value):
@@ -438,11 +448,19 @@
         name is the header field to add.  keyword arguments can be used to set
         additional parameters for the header field, with underscores converted
         to dashes.  Normally the parameter will be added as key="value" unless
-        value is None, in which case only the key will be added.
+        value is None, in which case only the key will be added.  If a
+        parameter value contains non-ASCII characters it can be specified as a
+        three-tuple of (charset, language, value), in which case it will be
+        encoded according to RFC2231 rules.  Otherwise it will be encoded using
+        the utf-8 charset and a language of ''.
 
-        Example:
+        Examples:
 
         msg.add_header('content-disposition', 'attachment', filename='bud.gif')
+        msg.add_header('content-disposition', 'attachment',
+                       filename=('utf-8', '', Fu?baller.ppt'))
+        msg.add_header('content-disposition', 'attachment',
+                       filename='Fu?baller.ppt'))
         """
         parts = []
         for k, v in _params.items():

Modified: python/branches/py3k/Lib/email/test/test_email.py
==============================================================================
--- python/branches/py3k/Lib/email/test/test_email.py	(original)
+++ python/branches/py3k/Lib/email/test/test_email.py	Tue Dec 14 00:51:19 2010
@@ -510,6 +510,29 @@
         self.assertEqual(msg.get_payload(decode=True),
                          bytes(x, 'raw-unicode-escape'))
 
+    # Issue 1078919
+    def test_ascii_add_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+                       filename='bud.gif')
+        self.assertEqual('attachment; filename="bud.gif"',
+            msg['Content-Disposition'])
+
+    def test_noascii_add_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+            filename="Fu?baller.ppt")
+        self.assertEqual(
+            'attachment; filename*="utf-8\'\'Fu%C3%9Fballer.ppt"',
+            msg['Content-Disposition'])
+
+    def test_nonascii_add_header_via_triple(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+            filename=('iso-8859-1', '', 'Fu?baller.ppt'))
+        self.assertEqual(
+            'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"',
+            msg['Content-Disposition'])
 
 
 # Test the email.encoders module

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec 14 00:51:19 2010
@@ -11,6 +11,9 @@
 Library
 -------
 
+- Issue #1078919: add_header now automatically RFC2231 encodes parameters
+  that contain non-ascii values.
+
 - Issue #10188 (partial resolution): tempfile.TemporaryDirectory emits
   a warning on sys.stderr rather than throwing a misleading exception
   if cleanup fails due to nulling out of modules during shutdown.

From python-checkins at python.org  Tue Dec 14 00:57:01 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 00:57:01 +0100 (CET)
Subject: [Python-checkins] r87218 - in python/branches/release31-maint:
	Doc/library/email.message.rst Lib/email/message.py
	Lib/email/test/test_email.py Misc/NEWS
Message-ID: <20101213235701.9C263EE993@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 00:57:01 2010
New Revision: 87218

Log:
Merged revisions 87217 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87217 | r.david.murray | 2010-12-13 18:51:19 -0500 (Mon, 13 Dec 2010) | 5 lines
  
  #1078919: make add_header automatically do RFC2231 encoding when needed.
  
  Also document the use of three-tuples if control of the charset
  and language is desired.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/library/email.message.rst
   python/branches/release31-maint/Lib/email/message.py
   python/branches/release31-maint/Lib/email/test/test_email.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Doc/library/email.message.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/email.message.rst	(original)
+++ python/branches/release31-maint/Doc/library/email.message.rst	Tue Dec 14 00:57:01 2010
@@ -257,7 +257,15 @@
       taken as the parameter name, with underscores converted to dashes (since
       dashes are illegal in Python identifiers).  Normally, the parameter will
       be added as ``key="value"`` unless the value is ``None``, in which case
-      only the key will be added.
+      only the key will be added.  If the value contains non-ASCII characters,
+      it can be specified as a three tuple in the format
+      ``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string naming the
+      charset to be used to encode the value, ``LANGUAGE`` can usually be set
+      to ``None`` or the empty string (see :RFC:`2231` for other possibilities),
+      and ``VALUE`` is the string value containing non-ASCII code points.  If
+      a three tuple is not passed and the value contains non-ASCII characters,
+      it is automatically encoded in :RFC`2231` format using a ``CHARSET``
+      of ``utf-8`` and a ``LANGUAGE`` of ``None``.
 
       Here's an example::
 
@@ -267,6 +275,15 @@
 
          Content-Disposition: attachment; filename="bud.gif"
 
+      An example with with non-ASCII characters::
+
+         msg.add_header('Content-Disposition', 'attachment',
+                        filename=('iso-8859-1', '', 'Fu?baller.ppt'))
+
+      Which produces ::
+
+         Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
+
 
    .. method:: replace_header(_name, _value)
 
@@ -356,7 +373,7 @@
       :rfc:`2231`, you can collapse the parameter value by calling
       :func:`email.utils.collapse_rfc2231_value`, passing in the return value
       from :meth:`get_param`.  This will return a suitably decoded Unicode
-      string whn the value is a tuple, or the original string unquoted if it
+      string when the value is a tuple, or the original string unquoted if it
       isn't.  For example::
 
          rawparam = msg.get_param('foo')

Modified: python/branches/release31-maint/Lib/email/message.py
==============================================================================
--- python/branches/release31-maint/Lib/email/message.py	(original)
+++ python/branches/release31-maint/Lib/email/message.py	Tue Dec 14 00:57:01 2010
@@ -39,7 +39,11 @@
 def _formatparam(param, value=None, quote=True):
     """Convenience function to format and return a key=value pair.
 
-    This will quote the value if needed or if quote is true.
+    This will quote the value if needed or if quote is true.  If value is a
+    three tuple (charset, language, value), it will be encoded according
+    to RFC2231 rules.  If it contains non-ascii characters it will likewise
+    be encoded according to RFC2231 rules, using the utf-8 charset and
+    a null language.
     """
     if value is not None and len(value) > 0:
         # A tuple is used for RFC 2231 encoded parameter values where items
@@ -49,6 +53,12 @@
             # Encode as per RFC 2231
             param += '*'
             value = utils.encode_rfc2231(value[2], value[0], value[1])
+        else:
+            try:
+                value.encode('ascii')
+            except UnicodeEncodeError:
+                param += '*'
+                value = utils.encode_rfc2231(value, 'utf-8', '')
         # BAW: Please check this.  I think that if quote is set it should
         # force quoting even if not necessary.
         if quote or tspecials.search(value):
@@ -391,11 +401,19 @@
         name is the header field to add.  keyword arguments can be used to set
         additional parameters for the header field, with underscores converted
         to dashes.  Normally the parameter will be added as key="value" unless
-        value is None, in which case only the key will be added.
+        value is None, in which case only the key will be added.  If a
+        parameter value contains non-ASCII characters it can be specified as a
+        three-tuple of (charset, language, value), in which case it will be
+        encoded according to RFC2231 rules.  Otherwise it will be encoded using
+        the utf-8 charset and a language of ''.
 
-        Example:
+        Examples:
 
         msg.add_header('content-disposition', 'attachment', filename='bud.gif')
+        msg.add_header('content-disposition', 'attachment',
+                       filename=('utf-8', '', Fu?baller.ppt'))
+        msg.add_header('content-disposition', 'attachment',
+                       filename='Fu?baller.ppt'))
         """
         parts = []
         for k, v in _params.items():

Modified: python/branches/release31-maint/Lib/email/test/test_email.py
==============================================================================
--- python/branches/release31-maint/Lib/email/test/test_email.py	(original)
+++ python/branches/release31-maint/Lib/email/test/test_email.py	Tue Dec 14 00:57:01 2010
@@ -504,6 +504,29 @@
         self.assertEqual(msg.get_payload(decode=True),
                          bytes(x, 'raw-unicode-escape'))
 
+    # Issue 1078919
+    def test_ascii_add_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+                       filename='bud.gif')
+        self.assertEqual('attachment; filename="bud.gif"',
+            msg['Content-Disposition'])
+
+    def test_noascii_add_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+            filename="Fu?baller.ppt")
+        self.assertEqual(
+            'attachment; filename*="utf-8\'\'Fu%C3%9Fballer.ppt"',
+            msg['Content-Disposition'])
+
+    def test_nonascii_add_header_via_triple(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+            filename=('iso-8859-1', '', 'Fu?baller.ppt'))
+        self.assertEqual(
+            'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"',
+            msg['Content-Disposition'])
 
 
 # Test the email.encoders module

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Tue Dec 14 00:57:01 2010
@@ -17,6 +17,9 @@
 Library
 -------
 
+- Issue #1078919: add_header now automatically RFC2231 encodes parameters
+  that contain non-ascii values.
+
 - Issue #10107: Warn about unsaved files in IDLE on OSX.
 
 - Issue #7904: Changes to urllib.parse.urlsplit to handle schemes as defined by

From python-checkins at python.org  Tue Dec 14 01:29:27 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 01:29:27 +0100 (CET)
Subject: [Python-checkins] r87219 - in python/branches/release27-maint:
	Doc/library/email.message.rst Lib/email/message.py
	Lib/email/test/test_email.py
Message-ID: <20101214002927.936C8EEA0D@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 01:29:27 2010
New Revision: 87219

Log:
#1078919: document requirement to use triples for non-ascii add_header parms.


Modified:
   python/branches/release27-maint/Doc/library/email.message.rst
   python/branches/release27-maint/Lib/email/message.py
   python/branches/release27-maint/Lib/email/test/test_email.py

Modified: python/branches/release27-maint/Doc/library/email.message.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/email.message.rst	(original)
+++ python/branches/release27-maint/Doc/library/email.message.rst	Tue Dec 14 01:29:27 2010
@@ -266,7 +266,12 @@
       taken as the parameter name, with underscores converted to dashes (since
       dashes are illegal in Python identifiers).  Normally, the parameter will
       be added as ``key="value"`` unless the value is ``None``, in which case
-      only the key will be added.
+      only the key will be added.  If the value contains non-ASCII characters,
+      it must be specified as a three tuple in the format
+      ``(CHARSET, LANGUAGE, VALUE)``, where ``CHARSET`` is a string naming the
+      charset to be used to encode the value, ``LANGUAGE`` can usually be set
+      to ``None`` or the empty string (see :RFC:`2231` for other possibilities),
+      and ``VALUE`` is the string value containing non-ASCII code points.
 
       Here's an example::
 
@@ -276,6 +281,15 @@
 
          Content-Disposition: attachment; filename="bud.gif"
 
+      An example with with non-ASCII characters::
+
+         msg.add_header('Content-Disposition', 'attachment',
+                        filename=('iso-8859-1', '', 'Fu?baller.ppt'))
+
+      Which produces ::
+
+         Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
+
 
    .. method:: replace_header(_name, _value)
 
@@ -380,7 +394,7 @@
       :rfc:`2231`, you can collapse the parameter value by calling
       :func:`email.utils.collapse_rfc2231_value`, passing in the return value
       from :meth:`get_param`.  This will return a suitably decoded Unicode
-      string whn the value is a tuple, or the original string unquoted if it
+      string when the value is a tuple, or the original string unquoted if it
       isn't.  For example::
 
          rawparam = msg.get_param('foo')

Modified: python/branches/release27-maint/Lib/email/message.py
==============================================================================
--- python/branches/release27-maint/Lib/email/message.py	(original)
+++ python/branches/release27-maint/Lib/email/message.py	Tue Dec 14 01:29:27 2010
@@ -38,7 +38,9 @@
 def _formatparam(param, value=None, quote=True):
     """Convenience function to format and return a key=value pair.
 
-    This will quote the value if needed or if quote is true.
+    This will quote the value if needed or if quote is true.  If value is a
+    three tuple (charset, language, value), it will be encoded according
+    to RFC2231 rules.
     """
     if value is not None and len(value) > 0:
         # A tuple is used for RFC 2231 encoded parameter values where items
@@ -389,7 +391,10 @@
         name is the header field to add.  keyword arguments can be used to set
         additional parameters for the header field, with underscores converted
         to dashes.  Normally the parameter will be added as key="value" unless
-        value is None, in which case only the key will be added.
+        value is None, in which case only the key will be added.  If a
+        parameter value contains non-ASCII characters it must be specified as a
+        three-tuple of (charset, language, value), in which case it will be
+        encoded according to RFC2231 rules.
 
         Example:
 

Modified: python/branches/release27-maint/Lib/email/test/test_email.py
==============================================================================
--- python/branches/release27-maint/Lib/email/test/test_email.py	(original)
+++ python/branches/release27-maint/Lib/email/test/test_email.py	Tue Dec 14 01:29:27 2010
@@ -3113,6 +3113,21 @@
         s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3I ?='
         raises(Errors.HeaderParseError, decode_header, s)
 
+    # Issue 1078919
+    def test_ascii_add_header(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+                       filename='bud.gif')
+        self.assertEqual('attachment; filename="bud.gif"',
+            msg['Content-Disposition'])
+
+    def test_nonascii_add_header_via_triple(self):
+        msg = Message()
+        msg.add_header('Content-Disposition', 'attachment',
+            filename=('iso-8859-1', '', 'Fu\xdfballer.ppt'))
+        self.assertEqual(
+            'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"',
+            msg['Content-Disposition'])
 
 
 # Test RFC 2231 header parameters (en/de)coding

From python-checkins at python.org  Tue Dec 14 01:36:31 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 01:36:31 +0100 (CET)
Subject: [Python-checkins] r87220 - python/branches/release27-maint
Message-ID: <20101214003631.EF2A1EEA2F@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 01:36:31 2010
New Revision: 87220

Log:
Blocked revisions 87217 via svnmerge

........
  r87217 | r.david.murray | 2010-12-13 18:51:19 -0500 (Mon, 13 Dec 2010) | 5 lines
  
  #1078919: make add_header automatically do RFC2231 encoding when needed.
  
  Also document the use of three-tuples if control of the charset
  and language is desired.
........


Modified:
   python/branches/release27-maint/   (props changed)

From python-checkins at python.org  Tue Dec 14 01:55:46 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 01:55:46 +0100 (CET)
Subject: [Python-checkins] r87221 - python/branches/py3k/Modules/timemodule.c
Message-ID: <20101214005546.ABB95EEA31@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 01:55:46 2010
New Revision: 87221

Log:
#10699: fix docstring for tzset: it does not take a parameter

Thanks to Garrett Cooper for the fix.


Modified:
   python/branches/py3k/Modules/timemodule.c

Modified: python/branches/py3k/Modules/timemodule.c
==============================================================================
--- python/branches/py3k/Modules/timemodule.c	(original)
+++ python/branches/py3k/Modules/timemodule.c	Tue Dec 14 01:55:46 2010
@@ -715,7 +715,7 @@
 }
 
 PyDoc_STRVAR(tzset_doc,
-"tzset(zone)\n\
+"tzset()\n\
 \n\
 Initialize, or reinitialize, the local timezone to the value stored in\n\
 os.environ['TZ']. The TZ environment variable should be specified in\n\

From python-checkins at python.org  Tue Dec 14 02:22:50 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:22:50 +0100 (CET)
Subject: [Python-checkins] r87222 -
	python/branches/py3k/Lib/test/test_time.py
Message-ID: <20101214012250.CFF1AEE993@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:22:50 2010
New Revision: 87222

Log:
Use skipIf instead of a return when attribute doesn't exist.


Modified:
   python/branches/py3k/Lib/test/test_time.py

Modified: python/branches/py3k/Lib/test/test_time.py
==============================================================================
--- python/branches/py3k/Lib/test/test_time.py	(original)
+++ python/branches/py3k/Lib/test/test_time.py	Tue Dec 14 02:22:50 2010
@@ -126,9 +126,9 @@
     def test_asctime_bounding_check(self):
         self._bounds_checking(time.asctime)
 
+    @unittest.skipIf(not hasattr(time, "tzset"),
+        "time module has no attribute tzset")
     def test_tzset(self):
-        if not hasattr(time, "tzset"):
-            return # Can't test this; don't want the test suite to fail
 
         from os import environ
 

From python-checkins at python.org  Tue Dec 14 02:25:30 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:25:30 +0100 (CET)
Subject: [Python-checkins] r87223 - in python/branches/release31-maint:
	Lib/test/test_time.py
Message-ID: <20101214012530.9DEE6EE9B6@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:25:30 2010
New Revision: 87223

Log:
Merged revisions 87222 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87222 | r.david.murray | 2010-12-13 20:22:50 -0500 (Mon, 13 Dec 2010) | 2 lines
  
  Use skipIf instead of a return when attribute doesn't exist.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_time.py

Modified: python/branches/release31-maint/Lib/test/test_time.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_time.py	(original)
+++ python/branches/release31-maint/Lib/test/test_time.py	Tue Dec 14 02:25:30 2010
@@ -125,9 +125,9 @@
         time.asctime(time.gmtime(self.t))
         self.assertRaises(TypeError, time.asctime, 0)
 
+    @unittest.skipIf(not hasattr(time, "tzset"),
+        "time module has no attribute tzset")
     def test_tzset(self):
-        if not hasattr(time, "tzset"):
-            return # Can't test this; don't want the test suite to fail
 
         from os import environ
 

From python-checkins at python.org  Tue Dec 14 02:28:59 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:28:59 +0100 (CET)
Subject: [Python-checkins] r87224 - in python/branches/release27-maint:
	Lib/test/test_time.py
Message-ID: <20101214012859.DAF42EE993@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:28:59 2010
New Revision: 87224

Log:
Merged revisions 87222 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87222 | r.david.murray | 2010-12-13 20:22:50 -0500 (Mon, 13 Dec 2010) | 2 lines
  
  Use skipIf instead of a return when attribute doesn't exist.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/test/test_time.py

Modified: python/branches/release27-maint/Lib/test/test_time.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_time.py	(original)
+++ python/branches/release27-maint/Lib/test/test_time.py	Tue Dec 14 02:28:59 2010
@@ -115,9 +115,9 @@
         time.asctime(time.gmtime(self.t))
         self.assertRaises(TypeError, time.asctime, 0)
 
+    @unittest.skipIf(not hasattr(time, "tzset"),
+        "time module has no attribute tzset")
     def test_tzset(self):
-        if not hasattr(time, "tzset"):
-            return # Can't test this; don't want the test suite to fail
 
         from os import environ
 

From python-checkins at python.org  Tue Dec 14 02:38:16 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:38:16 +0100 (CET)
Subject: [Python-checkins] r87225 - in
	python/branches/py3k/Lib/multiprocessing: __init__.py
	connection.py dummy/__init__.py dummy/connection.py
	forking.py heap.py managers.py pool.py process.py queues.py
	reduction.py sharedctypes.py synchronize.py util.py
Message-ID: <20101214013816.6271DEE993@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:38:16 2010
New Revision: 87225

Log:
9162: fix license in multiprocessing files


Modified:
   python/branches/py3k/Lib/multiprocessing/__init__.py
   python/branches/py3k/Lib/multiprocessing/connection.py
   python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
   python/branches/py3k/Lib/multiprocessing/dummy/connection.py
   python/branches/py3k/Lib/multiprocessing/forking.py
   python/branches/py3k/Lib/multiprocessing/heap.py
   python/branches/py3k/Lib/multiprocessing/managers.py
   python/branches/py3k/Lib/multiprocessing/pool.py
   python/branches/py3k/Lib/multiprocessing/process.py
   python/branches/py3k/Lib/multiprocessing/queues.py
   python/branches/py3k/Lib/multiprocessing/reduction.py
   python/branches/py3k/Lib/multiprocessing/sharedctypes.py
   python/branches/py3k/Lib/multiprocessing/synchronize.py
   python/branches/py3k/Lib/multiprocessing/util.py

Modified: python/branches/py3k/Lib/multiprocessing/__init__.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/__init__.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/__init__.py	Tue Dec 14 02:38:16 2010
@@ -38,6 +38,7 @@
 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __version__ = '0.70a1'

Modified: python/branches/py3k/Lib/multiprocessing/connection.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/connection.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/connection.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/dummy/__init__.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/dummy/__init__.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/__init__.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/py3k/Lib/multiprocessing/dummy/connection.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/dummy/connection.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/dummy/connection.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/py3k/Lib/multiprocessing/forking.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/forking.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/forking.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/forking.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import os

Modified: python/branches/py3k/Lib/multiprocessing/heap.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/heap.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/heap.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/heap.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import bisect

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Tue Dec 14 02:38:16 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/managers.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]

Modified: python/branches/py3k/Lib/multiprocessing/pool.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/pool.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/pool.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/pool.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Pool']

Modified: python/branches/py3k/Lib/multiprocessing/process.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/process.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/process.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/process.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Process', 'current_process', 'active_children']

Modified: python/branches/py3k/Lib/multiprocessing/queues.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/queues.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/queues.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/queues.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Queue', 'SimpleQueue', 'JoinableQueue']

Modified: python/branches/py3k/Lib/multiprocessing/reduction.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/reduction.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/reduction.py	Tue Dec 14 02:38:16 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/reduction.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = []

Modified: python/branches/py3k/Lib/multiprocessing/sharedctypes.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/sharedctypes.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/sharedctypes.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/sharedctypes.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import sys

Modified: python/branches/py3k/Lib/multiprocessing/synchronize.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/synchronize.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/synchronize.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/py3k/Lib/multiprocessing/util.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/util.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/util.py	Tue Dec 14 02:38:16 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/util.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import itertools

From python-checkins at python.org  Tue Dec 14 02:41:07 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:41:07 +0100 (CET)
Subject: [Python-checkins] r87226 - in python/branches/release31-maint:
	Lib/multiprocessing/__init__.py Lib/multiprocessing/connection.py
	Lib/multiprocessing/dummy/__init__.py
	Lib/multiprocessing/dummy/connection.py
	Lib/multiprocessing/forking.py Lib/multiprocessing/heap.py
	Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py
	Lib/multiprocessing/process.py Lib/multiprocessing/queues.py
	Lib/multiprocessing/reduction.py Lib/multiprocessing/sharedctypes.py
	Lib/multiprocessing/synchronize.py Lib/multiprocessing/util.py
Message-ID: <20101214014107.B6385EE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:41:07 2010
New Revision: 87226

Log:
Merged revisions 87225 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87225 | r.david.murray | 2010-12-13 20:38:16 -0500 (Mon, 13 Dec 2010) | 2 lines
  
  9162: fix license in multiprocessing files
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/multiprocessing/__init__.py
   python/branches/release31-maint/Lib/multiprocessing/connection.py
   python/branches/release31-maint/Lib/multiprocessing/dummy/__init__.py
   python/branches/release31-maint/Lib/multiprocessing/dummy/connection.py
   python/branches/release31-maint/Lib/multiprocessing/forking.py
   python/branches/release31-maint/Lib/multiprocessing/heap.py
   python/branches/release31-maint/Lib/multiprocessing/managers.py
   python/branches/release31-maint/Lib/multiprocessing/pool.py
   python/branches/release31-maint/Lib/multiprocessing/process.py
   python/branches/release31-maint/Lib/multiprocessing/queues.py
   python/branches/release31-maint/Lib/multiprocessing/reduction.py
   python/branches/release31-maint/Lib/multiprocessing/sharedctypes.py
   python/branches/release31-maint/Lib/multiprocessing/synchronize.py
   python/branches/release31-maint/Lib/multiprocessing/util.py

Modified: python/branches/release31-maint/Lib/multiprocessing/__init__.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/__init__.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/__init__.py	Tue Dec 14 02:41:07 2010
@@ -38,6 +38,7 @@
 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __version__ = '0.70a1'

Modified: python/branches/release31-maint/Lib/multiprocessing/connection.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/connection.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/connection.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/release31-maint/Lib/multiprocessing/dummy/__init__.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/dummy/__init__.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/dummy/__init__.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/__init__.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/release31-maint/Lib/multiprocessing/dummy/connection.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/dummy/connection.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/dummy/connection.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/release31-maint/Lib/multiprocessing/forking.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/forking.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/forking.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/forking.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import os

Modified: python/branches/release31-maint/Lib/multiprocessing/heap.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/heap.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/heap.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/heap.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import bisect

Modified: python/branches/release31-maint/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/managers.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/managers.py	Tue Dec 14 02:41:07 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/managers.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]

Modified: python/branches/release31-maint/Lib/multiprocessing/pool.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/pool.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/pool.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/pool.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Pool']

Modified: python/branches/release31-maint/Lib/multiprocessing/process.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/process.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/process.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/process.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Process', 'current_process', 'active_children']

Modified: python/branches/release31-maint/Lib/multiprocessing/queues.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/queues.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/queues.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/queues.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Queue', 'SimpleQueue', 'JoinableQueue']

Modified: python/branches/release31-maint/Lib/multiprocessing/reduction.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/reduction.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/reduction.py	Tue Dec 14 02:41:07 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/reduction.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = []

Modified: python/branches/release31-maint/Lib/multiprocessing/sharedctypes.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/sharedctypes.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/sharedctypes.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/sharedctypes.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import sys

Modified: python/branches/release31-maint/Lib/multiprocessing/synchronize.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/synchronize.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/synchronize.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/release31-maint/Lib/multiprocessing/util.py
==============================================================================
--- python/branches/release31-maint/Lib/multiprocessing/util.py	(original)
+++ python/branches/release31-maint/Lib/multiprocessing/util.py	Tue Dec 14 02:41:07 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/util.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import itertools

From python-checkins at python.org  Tue Dec 14 02:42:41 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 02:42:41 +0100 (CET)
Subject: [Python-checkins] r87227 - in python/branches/release27-maint:
	Lib/multiprocessing/__init__.py Lib/multiprocessing/connection.py
	Lib/multiprocessing/dummy/__init__.py
	Lib/multiprocessing/dummy/connection.py
	Lib/multiprocessing/forking.py Lib/multiprocessing/heap.py
	Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py
	Lib/multiprocessing/process.py Lib/multiprocessing/queues.py
	Lib/multiprocessing/reduction.py Lib/multiprocessing/sharedctypes.py
	Lib/multiprocessing/synchronize.py Lib/multiprocessing/util.py
Message-ID: <20101214014241.197CFEE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 02:42:40 2010
New Revision: 87227

Log:
Merged revisions 87225 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87225 | r.david.murray | 2010-12-13 20:38:16 -0500 (Mon, 13 Dec 2010) | 2 lines
  
  9162: fix license in multiprocessing files
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/multiprocessing/__init__.py
   python/branches/release27-maint/Lib/multiprocessing/connection.py
   python/branches/release27-maint/Lib/multiprocessing/dummy/__init__.py
   python/branches/release27-maint/Lib/multiprocessing/dummy/connection.py
   python/branches/release27-maint/Lib/multiprocessing/forking.py
   python/branches/release27-maint/Lib/multiprocessing/heap.py
   python/branches/release27-maint/Lib/multiprocessing/managers.py
   python/branches/release27-maint/Lib/multiprocessing/pool.py
   python/branches/release27-maint/Lib/multiprocessing/process.py
   python/branches/release27-maint/Lib/multiprocessing/queues.py
   python/branches/release27-maint/Lib/multiprocessing/reduction.py
   python/branches/release27-maint/Lib/multiprocessing/sharedctypes.py
   python/branches/release27-maint/Lib/multiprocessing/synchronize.py
   python/branches/release27-maint/Lib/multiprocessing/util.py

Modified: python/branches/release27-maint/Lib/multiprocessing/__init__.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/__init__.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/__init__.py	Tue Dec 14 02:42:40 2010
@@ -38,6 +38,7 @@
 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __version__ = '0.70a1'

Modified: python/branches/release27-maint/Lib/multiprocessing/connection.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/connection.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/connection.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/release27-maint/Lib/multiprocessing/dummy/__init__.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/dummy/__init__.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/dummy/__init__.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/__init__.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/release27-maint/Lib/multiprocessing/dummy/connection.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/dummy/connection.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/dummy/connection.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/dummy/connection.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'Client', 'Listener', 'Pipe' ]

Modified: python/branches/release27-maint/Lib/multiprocessing/forking.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/forking.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/forking.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/forking.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import os

Modified: python/branches/release27-maint/Lib/multiprocessing/heap.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/heap.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/heap.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/heap.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import bisect

Modified: python/branches/release27-maint/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/managers.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/managers.py	Tue Dec 14 02:42:40 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/managers.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]

Modified: python/branches/release27-maint/Lib/multiprocessing/pool.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/pool.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/pool.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/pool.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Pool']

Modified: python/branches/release27-maint/Lib/multiprocessing/process.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/process.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/process.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/process.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Process', 'current_process', 'active_children']

Modified: python/branches/release27-maint/Lib/multiprocessing/queues.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/queues.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/queues.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/queues.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = ['Queue', 'SimpleQueue', 'JoinableQueue']

Modified: python/branches/release27-maint/Lib/multiprocessing/reduction.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/reduction.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/reduction.py	Tue Dec 14 02:42:40 2010
@@ -4,7 +4,33 @@
 #
 # multiprocessing/reduction.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = []

Modified: python/branches/release27-maint/Lib/multiprocessing/sharedctypes.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/sharedctypes.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/sharedctypes.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/sharedctypes.py
 #
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import sys

Modified: python/branches/release27-maint/Lib/multiprocessing/synchronize.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/synchronize.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/synchronize.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 __all__ = [

Modified: python/branches/release27-maint/Lib/multiprocessing/util.py
==============================================================================
--- python/branches/release27-maint/Lib/multiprocessing/util.py	(original)
+++ python/branches/release27-maint/Lib/multiprocessing/util.py	Tue Dec 14 02:42:40 2010
@@ -3,7 +3,33 @@
 #
 # multiprocessing/util.py
 #
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
 #
 
 import itertools

From python-checkins at python.org  Tue Dec 14 03:25:44 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 03:25:44 +0100 (CET)
Subject: [Python-checkins] r87228 -
	python/branches/py3k/Tools/buildbot/test.bat
Message-ID: <20101214022544.1E3A0EE9B1@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 03:25:43 2010
New Revision: 87228

Log:
Turn on regrtest -W (rerun immediately) option for Windows, too.


Modified:
   python/branches/py3k/Tools/buildbot/test.bat

Modified: python/branches/py3k/Tools/buildbot/test.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/test.bat	(original)
+++ python/branches/py3k/Tools/buildbot/test.bat	Tue Dec 14 03:25:43 2010
@@ -1,4 +1,4 @@
 @rem Used by the buildbot "test" step.
 cd PCbuild
-call rt.bat -d -q -uall -rw -n
+call rt.bat -d -q -uall -rwW -n
 

From solipsis at pitrou.net  Tue Dec 14 04:48:55 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Tue, 14 Dec 2010 04:48:55 +0100
Subject: [Python-checkins] Daily py3k reference leaks (r87228): sum=0
Message-ID: 

py3k results for svn r87228 (hg cset dc2ccdd2541b)
--------------------------------------------------



Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogzBrlIj', '-x']

From python-checkins at python.org  Tue Dec 14 14:43:31 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 14:43:31 +0100 (CET)
Subject: [Python-checkins] r87229 - in python/branches/py3k:
	Doc/library/subprocess.rst Lib/subprocess.py
	Lib/test/test_subprocess.py Misc/NEWS Modules/_posixsubprocess.c
Message-ID: <20101214134331.2E159EE9A0@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 14:43:30 2010
New Revision: 87229

Log:
Issue #6559: fix the subprocess.Popen pass_fds implementation. Add a unittest.
Issue #7213: Change the close_fds default on Windows to better match the new
default on POSIX.  True when possible (False if stdin/stdout/stderr are
supplied).

Update the documentation to reflect all of the above.


Modified:
   python/branches/py3k/Doc/library/subprocess.rst
   python/branches/py3k/Lib/subprocess.py
   python/branches/py3k/Lib/test/test_subprocess.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/_posixsubprocess.c

Modified: python/branches/py3k/Doc/library/subprocess.rst
==============================================================================
--- python/branches/py3k/Doc/library/subprocess.rst	(original)
+++ python/branches/py3k/Doc/library/subprocess.rst	Tue Dec 14 14:43:30 2010
@@ -28,7 +28,7 @@
 This module defines one class called :class:`Popen`:
 
 
-.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
+.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
 
    Arguments are:
 
@@ -153,14 +153,22 @@
 
    If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
    :const:`2` will be closed before the child process is executed. (Unix only).
-   The default varies by platform: :const:`False` on Windows and :const:`True`
-   on POSIX and other platforms.
+   The default varies by platform:  Always true on Unix.  On Windows it is
+   true when *stdin*/*stdout*/*stderr* are :const:`None`, false otherwise.
    On Windows, if *close_fds* is true then no handles will be inherited by the
    child process.  Note that on Windows, you cannot set *close_fds* to true and
    also redirect the standard handles by setting *stdin*, *stdout* or *stderr*.
 
-.. versionchanged:: 3.2
-   The default was changed to True on non Windows platforms.
+   .. versionchanged:: 3.2
+      The default for *close_fds* was changed from :const:`False` to
+      what is described above.
+
+   *pass_fds* is an optional sequence of file descriptors to keep open
+   between the parent and child.  Providing any *pass_fds* forces
+   *close_fds* to be :const:`True`.  (Unix only)
+
+   .. versionadded:: 3.2
+      The *pass_fds* parameter was added.
 
    If *cwd* is not ``None``, the child's current directory will be changed to *cwd*
    before it is executed.  Note that this directory is not considered when

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Tue Dec 14 14:43:30 2010
@@ -27,10 +27,10 @@
 
 class Popen(args, bufsize=0, executable=None,
             stdin=None, stdout=None, stderr=None,
-            preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
+            preexec_fn=None, close_fds=True, shell=False,
             cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
-            restore_signals=True, start_new_session=False):
+            restore_signals=True, start_new_session=False, pass_fds=()):
 
 
 Arguments are:
@@ -81,8 +81,11 @@
 
 If close_fds is true, all file descriptors except 0, 1 and 2 will be
 closed before the child process is executed.  The default for close_fds
-varies by platform: False on Windows and True on all other platforms
-such as POSIX.
+varies by platform:  Always true on POSIX.  True when stdin/stdout/stderr
+are None on Windows, false otherwise.
+
+pass_fds is an optional sequence of file descriptors to keep open between the
+parent and child.  Providing any pass_fds implicitly sets close_fds to true.
 
 if shell is true, the specified command will be executed through the
 shell.
@@ -621,17 +624,14 @@
     return getstatusoutput(cmd)[1]
 
 
-if mswindows:
-    _PLATFORM_DEFAULT = False
-else:
-    _PLATFORM_DEFAULT = True
+_PLATFORM_DEFAULT_CLOSE_FDS = object()
 
 
 class Popen(object):
     def __init__(self, args, bufsize=0, executable=None,
                  stdin=None, stdout=None, stderr=None,
-                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
-                 cwd=None, env=None, universal_newlines=False,
+                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
+                 shell=False, cwd=None, env=None, universal_newlines=False,
                  startupinfo=None, creationflags=0,
                  restore_signals=True, start_new_session=False,
                  pass_fds=()):
@@ -648,12 +648,24 @@
             if preexec_fn is not None:
                 raise ValueError("preexec_fn is not supported on Windows "
                                  "platforms")
-            if close_fds and (stdin is not None or stdout is not None or
-                              stderr is not None):
-                raise ValueError("close_fds is not supported on Windows "
-                                 "platforms if you redirect stdin/stdout/stderr")
+            any_stdio_set = (stdin is not None or stdout is not None or
+                             stderr is not None)
+            if close_fds is _PLATFORM_DEFAULT_CLOSE_FDS:
+                if any_stdio_set:
+                    close_fds = False
+                else:
+                    close_fds = True
+            elif close_fds and any_stdio_set:
+                raise ValueError(
+                        "close_fds is not supported on Windows platforms"
+                        " if you redirect stdin/stdout/stderr")
         else:
             # POSIX
+            if close_fds is _PLATFORM_DEFAULT_CLOSE_FDS:
+                close_fds = True
+            if pass_fds and not close_fds:
+                warnings.warn("pass_fds overriding close_fds.", RuntimeWarning)
+                close_fds = True
             if startupinfo is not None:
                 raise ValueError("startupinfo is only supported on Windows "
                                  "platforms")
@@ -661,9 +673,6 @@
                 raise ValueError("creationflags is only supported on Windows "
                                  "platforms")
 
-        if pass_fds and not close_fds:
-            raise ValueError("pass_fds requires close_fds=True.")
-
         self.stdin = None
         self.stdout = None
         self.stderr = None
@@ -876,7 +885,7 @@
                            unused_restore_signals, unused_start_new_session):
             """Execute program (MS Windows version)"""
 
-            assert not pass_fds, "pass_fds not yet supported on Windows"
+            assert not pass_fds, "pass_fds not supported on Windows."
 
             if not isinstance(args, str):
                 args = list2cmdline(args)
@@ -1091,7 +1100,7 @@
             # precondition: fds_to_keep must be sorted and unique
             start_fd = 3
             for fd in fds_to_keep:
-                if fd > start_fd:
+                if fd >= start_fd:
                     os.closerange(start_fd, fd)
                     start_fd = fd + 1
             if start_fd <= MAXFD:

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Tue Dec 14 14:43:30 2010
@@ -1042,6 +1042,37 @@
                          "Some fds were left open")
         self.assertIn(1, remaining_fds, "Subprocess failed")
 
+    def test_pass_fds(self):
+        fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
+
+        open_fds = set()
+
+        for x in range(5):
+            fds = os.pipe()
+            self.addCleanup(os.close, fds[0])
+            self.addCleanup(os.close, fds[1])
+            open_fds.update(fds)
+
+        for fd in open_fds:
+            p = subprocess.Popen([sys.executable, fd_status],
+                                 stdout=subprocess.PIPE, close_fds=True,
+                                 pass_fds=(fd, ))
+            output, ignored = p.communicate()
+
+            remaining_fds = set(map(int, output.split(b',')))
+            to_be_closed = open_fds - {fd}
+
+            self.assertIn(fd, remaining_fds, "fd to be passed not passed")
+            self.assertFalse(remaining_fds & to_be_closed,
+                             "fd to be closed passed")
+
+            # pass_fds overrides close_fds with a warning.
+            with self.assertWarns(RuntimeWarning) as context:
+                self.assertFalse(subprocess.call(
+                        [sys.executable, "-c", "import sys; sys.exit(0)"],
+                        close_fds=False, pass_fds=(fd, )))
+            self.assertIn('overriding close_fds', str(context.warning))
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec 14 14:43:30 2010
@@ -23,8 +23,12 @@
 - Issue #10107: Warn about unsaved files in IDLE on OSX.
 
 - Issue #7213: subprocess.Popen's default for close_fds has been changed.
-  It is now platform specific, keeping its default of False on Windows and
-  changing the default to True on POSIX and other platforms.
+  It is now True in most cases other than on Windows when input, output or
+  error handles are provided.
+
+- Issue #6559: subprocess.Popen has a new pass_fds parameter (actually
+  added in 3.2beta1) to allow specifying a specific list of file descriptors
+  to keep open in the child process.
 
 
 What's New in Python 3.2 Beta 1?

Modified: python/branches/py3k/Modules/_posixsubprocess.c
==============================================================================
--- python/branches/py3k/Modules/_posixsubprocess.c	(original)
+++ python/branches/py3k/Modules/_posixsubprocess.c	Tue Dec 14 14:43:30 2010
@@ -107,7 +107,7 @@
                 errno = 0;  /* We don't want to report an OSError. */
                 goto error;
             }
-            if (keep_fd <= start_fd)
+            if (keep_fd < start_fd)
                 continue;
             for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
                 close(fd_num);

From python-checkins at python.org  Tue Dec 14 15:16:20 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 15:16:20 +0100 (CET)
Subject: [Python-checkins] r87230 - in python/branches/py3k:
	Lib/telnetlib.py Lib/test/test_telnetlib.py Misc/NEWS
Message-ID: <20101214141620.B12BAEE99C@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 15:16:20 2010
New Revision: 87230

Log:
#10695: use %s not %d so that a string 'port' does not cause a debug traceback

Passing the port as a string value works fine in regular mode, but
if you turned debug on it would throw an error trying to print the
port number, which is surprising and confusing.



Modified:
   python/branches/py3k/Lib/telnetlib.py
   python/branches/py3k/Lib/test/test_telnetlib.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/telnetlib.py
==============================================================================
--- python/branches/py3k/Lib/telnetlib.py	(original)
+++ python/branches/py3k/Lib/telnetlib.py	Tue Dec 14 15:16:20 2010
@@ -236,7 +236,7 @@
 
         """
         if self.debuglevel > 0:
-            print('Telnet(%s,%d):' % (self.host, self.port), end=' ')
+            print('Telnet(%s,%s):' % (self.host, self.port), end=' ')
             if args:
                 print(msg % args)
             else:

Modified: python/branches/py3k/Lib/test/test_telnetlib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_telnetlib.py	(original)
+++ python/branches/py3k/Lib/test/test_telnetlib.py	Tue Dec 14 15:16:20 2010
@@ -342,6 +342,16 @@
         expected = "send b'xxx'\n"
         self.assertIn(expected, telnet._messages)
 
+    def test_debug_accepts_str_port(self):
+        # Issue 10695
+        with test_socket([]):
+            telnet = TelnetAlike('dummy', '0')
+            telnet._messages = ''
+        telnet.set_debuglevel(1)
+        telnet.msg('test')
+        self.assertRegex(telnet._messages, r'0.*test')
+
+
 def test_main(verbose=None):
     support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests)
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec 14 15:16:20 2010
@@ -11,6 +11,9 @@
 Library
 -------
 
+- Issue #10695: passing the port as a string value to telnetlib no longer
+  causes debug mode to fail.
+
 - Issue #1078919: add_header now automatically RFC2231 encodes parameters
   that contain non-ascii values.
 

From python-checkins at python.org  Tue Dec 14 15:27:27 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 15:27:27 +0100 (CET)
Subject: [Python-checkins] r87231 - in python/branches/release31-maint:
	Lib/telnetlib.py Lib/test/test_telnetlib.py Misc/NEWS
Message-ID: <20101214142727.F3AF5EE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 15:27:27 2010
New Revision: 87231

Log:
Merged revisions 87230 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87230 | r.david.murray | 2010-12-14 09:16:20 -0500 (Tue, 14 Dec 2010) | 7 lines
  
  #10695: use %s not %d so that a string 'port' does not cause a debug traceback
  
  Passing the port as a string value works fine in regular mode, but
  if you turned debug on it would throw an error trying to print the
  port number, which is surprising and confusing.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/telnetlib.py
   python/branches/release31-maint/Lib/test/test_telnetlib.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/telnetlib.py
==============================================================================
--- python/branches/release31-maint/Lib/telnetlib.py	(original)
+++ python/branches/release31-maint/Lib/telnetlib.py	Tue Dec 14 15:27:27 2010
@@ -236,7 +236,7 @@
 
         """
         if self.debuglevel > 0:
-            print('Telnet(%s,%d):' % (self.host, self.port), end=' ')
+            print('Telnet(%s,%s):' % (self.host, self.port), end=' ')
             if args:
                 print(msg % args)
             else:

Modified: python/branches/release31-maint/Lib/test/test_telnetlib.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_telnetlib.py	(original)
+++ python/branches/release31-maint/Lib/test/test_telnetlib.py	Tue Dec 14 15:27:27 2010
@@ -342,6 +342,16 @@
         expected = "send b'xxx'\n"
         self.assertTrue(expected in telnet._messages)
 
+    def test_debug_accepts_str_port(self):
+        # Issue 10695
+        with test_socket([]):
+            telnet = TelnetAlike('dummy', '0')
+            telnet._messages = ''
+        telnet.set_debuglevel(1)
+        telnet.msg('test')
+        self.assertRegexpMatches(telnet._messages, r'0.*test')
+
+
 def test_main(verbose=None):
     support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests)
 

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Tue Dec 14 15:27:27 2010
@@ -17,6 +17,9 @@
 Library
 -------
 
+- Issue #10695: passing the port as a string value to telnetlib no longer
+  causes debug mode to fail.
+
 - Issue #1078919: add_header now automatically RFC2231 encodes parameters
   that contain non-ascii values.
 

From python-checkins at python.org  Tue Dec 14 15:34:16 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 15:34:16 +0100 (CET)
Subject: [Python-checkins] r87232 - in python/branches/release27-maint:
	Lib/telnetlib.py Misc/NEWS
Message-ID: <20101214143416.ED09CEE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 15:34:16 2010
New Revision: 87232

Log:
Merged revisions 87230 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87230 | r.david.murray | 2010-12-14 09:16:20 -0500 (Tue, 14 Dec 2010) | 7 lines
  
  #10695: use %s not %d so that a string 'port' does not cause a debug traceback
  
  Passing the port as a string value works fine in regular mode, but
  if you turned debug on it would throw an error trying to print the
  port number, which is surprising and confusing.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/telnetlib.py
   python/branches/release27-maint/Misc/NEWS

Modified: python/branches/release27-maint/Lib/telnetlib.py
==============================================================================
--- python/branches/release27-maint/Lib/telnetlib.py	(original)
+++ python/branches/release27-maint/Lib/telnetlib.py	Tue Dec 14 15:34:16 2010
@@ -236,7 +236,7 @@
 
         """
         if self.debuglevel > 0:
-            print 'Telnet(%s,%d):' % (self.host, self.port),
+            print 'Telnet(%s,%s):' % (self.host, self.port),
             if args:
                 print msg % args
             else:

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Tue Dec 14 15:34:16 2010
@@ -18,6 +18,9 @@
 Library
 -------
 
+- Issue #10695: passing the port as a string value to telnetlib no longer
+  causes debug mode to fail.
+
 - Issue #10107: Warn about unsaved files in IDLE on OSX.
 
 - Issue #10406: Enable Rstrip IDLE extension on OSX (just like on other

From python-checkins at python.org  Tue Dec 14 15:38:00 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 15:38:00 +0100 (CET)
Subject: [Python-checkins] r87233 - in python/branches/py3k:
	Lib/subprocess.py Lib/test/subprocessdata/sigchild_ignore.py
	Lib/test/test_subprocess.py Misc/NEWS
Message-ID: <20101214143800.E12A3EE9D4@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 15:38:00 2010
New Revision: 87233

Log:
Issue #1731717: Fixed the problem where subprocess.wait() could cause an
OSError exception when The OS had been told to ignore SIGCLD in our process
or otherwise not wait for exiting child processes.


Added:
   python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py
Modified:
   python/branches/py3k/Lib/subprocess.py
   python/branches/py3k/Lib/test/test_subprocess.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Tue Dec 14 15:38:00 2010
@@ -1295,7 +1295,11 @@
                 os.close(errpipe_read)
 
             if data:
-                _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
                 try:
                     exception_name, hex_errno, err_msg = data.split(b':', 2)
                 except ValueError:
@@ -1358,7 +1362,15 @@
             """Wait for child process to terminate.  Returns returncode
             attribute."""
             if self.returncode is None:
-                pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
+                    # This happens if SIGCLD is set to be ignored or waiting
+                    # for child processes has otherwise been disabled for our
+                    # process.  This child is dead, we can't get the status.
+                    sts = 0
                 self._handle_exitstatus(sts)
             return self.returncode
 

Added: python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 15:38:00 2010
@@ -0,0 +1,6 @@
+import signal, subprocess, sys
+# On Linux this causes os.waitpid to fail with OSError as the OS has already
+# reaped our child process.  The wait() passing the OSError on to the caller
+# and causing us to exit with an error is what we are testing against.
+signal.signal(signal.SIGCLD, signal.SIG_IGN)
+subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Tue Dec 14 15:38:00 2010
@@ -1073,6 +1073,16 @@
                         close_fds=False, pass_fds=(fd, )))
             self.assertIn('overriding close_fds', str(context.warning))
 
+    def test_wait_when_sigchild_ignored(self):
+        # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
+        sigchild_ignore = support.findfile("sigchild_ignore.py",
+                                           subdir="subprocessdata")
+        p = subprocess.Popen([sys.executable, sigchild_ignore],
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        stdout, stderr = p.communicate()
+        self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
+                         " non-zero with this error:\n%s" % stderr)
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec 14 15:38:00 2010
@@ -33,6 +33,10 @@
   added in 3.2beta1) to allow specifying a specific list of file descriptors
   to keep open in the child process.
 
+- Issue #1731717: Fixed the problem where subprocess.wait() could cause an
+  OSError exception when The OS had been told to ignore SIGCLD in our process
+  or otherwise not wait for exiting child processes.
+
 
 What's New in Python 3.2 Beta 1?
 ================================

From python-checkins at python.org  Tue Dec 14 16:02:54 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 16:02:54 +0100 (CET)
Subject: [Python-checkins] r87234 - in python/branches/release27-maint:
	Lib/subprocess.py Lib/test/subprocessdata
	Lib/test/subprocessdata/sigchild_ignore.py
	Lib/test/test_subprocess.py Misc/NEWS
Message-ID: <20101214150254.1579DEE99C@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 16:02:53 2010
New Revision: 87234

Log:
Merged revisions 87233 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87233 | gregory.p.smith | 2010-12-14 06:38:00 -0800 (Tue, 14 Dec 2010) | 4 lines
  
  Issue #1731717: Fixed the problem where subprocess.wait() could cause an
  OSError exception when The OS had been told to ignore SIGCLD in our process
  or otherwise not wait for exiting child processes.
........


Added:
   python/branches/release27-maint/Lib/test/subprocessdata/
   python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py
Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Lib/subprocess.py
   python/branches/release27-maint/Lib/test/test_subprocess.py
   python/branches/release27-maint/Misc/NEWS

Modified: python/branches/release27-maint/Lib/subprocess.py
==============================================================================
--- python/branches/release27-maint/Lib/subprocess.py	(original)
+++ python/branches/release27-maint/Lib/subprocess.py	Tue Dec 14 16:02:53 2010
@@ -1194,7 +1194,11 @@
                 os.close(errpipe_read)
 
             if data != "":
-                _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
                 child_exception = pickle.loads(data)
                 for fd in (p2cwrite, c2pread, errread):
                     if fd is not None:
@@ -1240,7 +1244,15 @@
             """Wait for child process to terminate.  Returns returncode
             attribute."""
             if self.returncode is None:
-                pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
+                    # This happens if SIGCLD is set to be ignored or waiting
+                    # for child processes has otherwise been disabled for our
+                    # process.  This child is dead, we can't get the status.
+                    sts = 0
                 self._handle_exitstatus(sts)
             return self.returncode
 

Added: python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- (empty file)
+++ python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 16:02:53 2010
@@ -0,0 +1,6 @@
+import signal, subprocess, sys
+# On Linux this causes os.waitpid to fail with OSError as the OS has already
+# reaped our child process.  The wait() passing the OSError on to the caller
+# and causing us to exit with an error is what we are testing against.
+signal.signal(signal.SIGCLD, signal.SIG_IGN)
+subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

Modified: python/branches/release27-maint/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_subprocess.py	(original)
+++ python/branches/release27-maint/Lib/test/test_subprocess.py	Tue Dec 14 16:02:53 2010
@@ -778,6 +778,16 @@
         self.assertStderrEqual(stderr, '')
         self.assertEqual(p.wait(), -signal.SIGTERM)
 
+    def test_wait_when_sigchild_ignored(self):
+        # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
+        sigchild_ignore = test_support.findfile("sigchild_ignore.py",
+                                                subdir="subprocessdata")
+        p = subprocess.Popen([sys.executable, sigchild_ignore],
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        stdout, stderr = p.communicate()
+        self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
+                         " non-zero with this error:\n%s" % stderr)
+
 
 @unittest.skipUnless(mswindows, "Windows specific tests")
 class Win32ProcessTestCase(BaseTestCase):

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Tue Dec 14 16:02:53 2010
@@ -34,6 +34,10 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+- Issue #1731717: Fixed the problem where subprocess.wait() could cause an
+  OSError exception when The OS had been told to ignore SIGCLD in our process
+  or otherwise not wait for exiting child processes.
+
 Extension Modules
 -----------------
 

From python-checkins at python.org  Tue Dec 14 16:16:25 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 16:16:25 +0100 (CET)
Subject: [Python-checkins] r87235 - in python/branches/release31-maint:
	Lib/subprocess.py Lib/test/subprocessdata
	Lib/test/subprocessdata/sigchild_ignore.py
	Lib/test/test_subprocess.py Misc/NEWS
Message-ID: <20101214151625.4CAA9EE9EF@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 16:16:24 2010
New Revision: 87235

Log:
Merged revisions 87233 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87233 | gregory.p.smith | 2010-12-14 06:38:00 -0800 (Tue, 14 Dec 2010) | 4 lines
  
  Issue #1731717: Fixed the problem where subprocess.wait() could cause an
  OSError exception when The OS had been told to ignore SIGCLD in our process
  or otherwise not wait for exiting child processes.
........


Added:
   python/branches/release31-maint/Lib/test/subprocessdata/
   python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py
Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/subprocess.py
   python/branches/release31-maint/Lib/test/test_subprocess.py
   python/branches/release31-maint/Misc/NEWS

Modified: python/branches/release31-maint/Lib/subprocess.py
==============================================================================
--- python/branches/release31-maint/Lib/subprocess.py	(original)
+++ python/branches/release31-maint/Lib/subprocess.py	Tue Dec 14 16:16:24 2010
@@ -1149,7 +1149,11 @@
                 os.close(errpipe_read)
 
             if data:
-                _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
                 child_exception = pickle.loads(data)
                 for fd in (p2cwrite, c2pread, errread):
                     if fd is not None:
@@ -1195,7 +1199,15 @@
             """Wait for child process to terminate.  Returns returncode
             attribute."""
             if self.returncode is None:
-                pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                try:
+                    pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+                except OSError as e:
+                    if e.errno != errno.ECHILD:
+                        raise
+                    # This happens if SIGCLD is set to be ignored or waiting
+                    # for child processes has otherwise been disabled for our
+                    # process.  This child is dead, we can't get the status.
+                    sts = 0
                 self._handle_exitstatus(sts)
             return self.returncode
 

Added: python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- (empty file)
+++ python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 16:16:24 2010
@@ -0,0 +1,6 @@
+import signal, subprocess, sys
+# On Linux this causes os.waitpid to fail with OSError as the OS has already
+# reaped our child process.  The wait() passing the OSError on to the caller
+# and causing us to exit with an error is what we are testing against.
+signal.signal(signal.SIGCLD, signal.SIG_IGN)
+subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

Modified: python/branches/release31-maint/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_subprocess.py	(original)
+++ python/branches/release31-maint/Lib/test/test_subprocess.py	Tue Dec 14 16:16:24 2010
@@ -793,6 +793,17 @@
                 stdout = stdout.rstrip(b'\n\r')
                 self.assertEqual(stdout, value_repr)
 
+        def test_wait_when_sigchild_ignored(self):
+            # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
+            sigchild_ignore = support.findfile("sigchild_ignore.py",
+                                               subdir="subprocessdata")
+            p = subprocess.Popen([sys.executable, sigchild_ignore],
+                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            stdout, stderr = p.communicate()
+            self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
+                             " non-zero with this error:\n%s" % stderr)
+
+
     #
     # Windows tests
     #

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Tue Dec 14 16:16:24 2010
@@ -35,6 +35,10 @@
 
 - Issue #10464: netrc now correctly handles lines with embedded '#' characters.
 
+- Issue #1731717: Fixed the problem where subprocess.wait() could cause an
+  OSError exception when The OS had been told to ignore SIGCLD in our process
+  or otherwise not wait for exiting child processes.
+
 Extensions
 ----------
 

From python-checkins at python.org  Tue Dec 14 16:23:02 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 16:23:02 +0100 (CET)
Subject: [Python-checkins] r87236 -
	python/branches/py3k/Lib/test/test_subprocess.py
Message-ID: <20101214152302.A710FEE9AD@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 16:23:02 2010
New Revision: 87236

Log:
Fix "BytesWarning: str() on a bytes instance"


Modified:
   python/branches/py3k/Lib/test/test_subprocess.py

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Tue Dec 14 16:23:02 2010
@@ -1081,7 +1081,8 @@
                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         stdout, stderr = p.communicate()
         self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
-                         " non-zero with this error:\n%s" % stderr)
+                         " non-zero with this error:\n%s" %
+                         stderr.decode('utf8'))
 
 
 @unittest.skipUnless(mswindows, "Windows specific tests")

From python-checkins at python.org  Tue Dec 14 16:25:20 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 16:25:20 +0100 (CET)
Subject: [Python-checkins] r87237 -
	python/branches/release31-maint/Lib/test/test_subprocess.py
Message-ID: <20101214152520.7F406EE9AD@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 16:25:20 2010
New Revision: 87237

Log:
fix "BytesWarning: str() on a bytes instance"


Modified:
   python/branches/release31-maint/Lib/test/test_subprocess.py

Modified: python/branches/release31-maint/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_subprocess.py	(original)
+++ python/branches/release31-maint/Lib/test/test_subprocess.py	Tue Dec 14 16:25:20 2010
@@ -801,7 +801,8 @@
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
             stdout, stderr = p.communicate()
             self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
-                             " non-zero with this error:\n%s" % stderr)
+                             " non-zero with this error:\n%s" %
+                             stderr.decode('utf8'))
 
 
     #

From python-checkins at python.org  Tue Dec 14 17:20:53 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 17:20:53 +0100 (CET)
Subject: [Python-checkins] r87238 - in python/branches/py3k:
	Doc/library/grp.rst Lib/test/test_grp.py Misc/ACKS Misc/NEWS
	Modules/grpmodule.c
Message-ID: <20101214162053.BF394EE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 17:20:53 2010
New Revision: 87238

Log:
#775964: skip YP/NIS entries instead of failing the test

Also includes doc updates mentioning that these entries may not
be retrievable via getgrnam and getgrgid.

Patch by Bobby Impollonia.


Modified:
   python/branches/py3k/Doc/library/grp.rst
   python/branches/py3k/Lib/test/test_grp.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/grpmodule.c

Modified: python/branches/py3k/Doc/library/grp.rst
==============================================================================
--- python/branches/py3k/Doc/library/grp.rst	(original)
+++ python/branches/py3k/Doc/library/grp.rst	Tue Dec 14 17:20:53 2010
@@ -30,7 +30,9 @@
 The gid is an integer, name and password are strings, and the member list is a
 list of strings. (Note that most users are not explicitly listed as members of
 the group they are in according to the password database.  Check both databases
-to get complete membership information.)
+to get complete membership information.  Also note that a ``gr_name`` that
+starts with a ``+`` or ``-`` is likely to be a YP/NIS reference and may not be
+accessible via :func:`getgrnam` or :func:`getgrgid`.)
 
 It defines the following items:
 

Modified: python/branches/py3k/Lib/test/test_grp.py
==============================================================================
--- python/branches/py3k/Lib/test/test_grp.py	(original)
+++ python/branches/py3k/Lib/test/test_grp.py	Tue Dec 14 17:20:53 2010
@@ -33,12 +33,16 @@
             e2 = grp.getgrgid(e.gr_gid)
             self.check_value(e2)
             self.assertEqual(e2.gr_gid, e.gr_gid)
-            e2 = grp.getgrnam(e.gr_name)
+            name = e.gr_name
+            if name.startswith('+') or name.startswith('-'):
+                # NIS-related entry
+                continue
+            e2 = grp.getgrnam(name)
             self.check_value(e2)
             # There are instances where getgrall() returns group names in
             # lowercase while getgrgid() returns proper casing.
             # Discovered on Ubuntu 5.04 (custom).
-            self.assertEqual(e2.gr_name.lower(), e.gr_name.lower())
+            self.assertEqual(e2.gr_name.lower(), name.lower())
 
     def test_errors(self):
         self.assertRaises(TypeError, grp.getgrgid)

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Tue Dec 14 17:20:53 2010
@@ -398,6 +398,7 @@
 Fredrik H??rd
 Mihai Ibanescu
 Lars Immisch
+Bobby Impollonia
 Meador Inge
 Tony Ingraldi
 John Interrante

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Dec 14 17:20:53 2010
@@ -38,6 +38,13 @@
   or otherwise not wait for exiting child processes.
 
 
+Tests
+-----
+
+- Issue #775964: test_grp now skips YP/NIS entries instead of failing when
+  encountering them.
+
+
 What's New in Python 3.2 Beta 1?
 ================================
 

Modified: python/branches/py3k/Modules/grpmodule.c
==============================================================================
--- python/branches/py3k/Modules/grpmodule.c	(original)
+++ python/branches/py3k/Modules/grpmodule.c	Tue Dec 14 17:20:53 2010
@@ -159,7 +159,9 @@
 name is not valid, raise KeyError."},
     {"getgrall",        grp_getgrall,   METH_NOARGS,
      "getgrall() -> list of tuples\n\
-Return a list of all available group entries, in arbitrary order."},
+Return a list of all available group entries, in arbitrary order.\n\
+An entry whose name starts with '+' or '-' represents an instruction\n\
+to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
     {NULL,              NULL}           /* sentinel */
 };
 

From python-checkins at python.org  Tue Dec 14 17:24:18 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 17:24:18 +0100 (CET)
Subject: [Python-checkins] r87239 - in python/branches/release31-maint:
	Doc/library/grp.rst Lib/test/test_grp.py Misc/ACKS Misc/NEWS
	Modules/grpmodule.c
Message-ID: <20101214162418.7EFC1EE9A2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 17:24:18 2010
New Revision: 87239

Log:
Merged revisions 87238 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87238 | r.david.murray | 2010-12-14 11:20:53 -0500 (Tue, 14 Dec 2010) | 7 lines
  
  #775964: skip YP/NIS entries instead of failing the test
  
  Also includes doc updates mentioning that these entries may not
  be retrievable via getgrnam and getgrgid.
  
  Patch by Bobby Impollonia.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Doc/library/grp.rst
   python/branches/release31-maint/Lib/test/test_grp.py
   python/branches/release31-maint/Misc/ACKS
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Modules/grpmodule.c

Modified: python/branches/release31-maint/Doc/library/grp.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/grp.rst	(original)
+++ python/branches/release31-maint/Doc/library/grp.rst	Tue Dec 14 17:24:18 2010
@@ -30,7 +30,9 @@
 The gid is an integer, name and password are strings, and the member list is a
 list of strings. (Note that most users are not explicitly listed as members of
 the group they are in according to the password database.  Check both databases
-to get complete membership information.)
+to get complete membership information.  Also note that a ``gr_name`` that
+starts with a ``+`` or ``-`` is likely to be a YP/NIS reference and may not be
+accessible via :func:`getgrnam` or :func:`getgrgid`.)
 
 It defines the following items:
 

Modified: python/branches/release31-maint/Lib/test/test_grp.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_grp.py	(original)
+++ python/branches/release31-maint/Lib/test/test_grp.py	Tue Dec 14 17:24:18 2010
@@ -33,12 +33,16 @@
             e2 = grp.getgrgid(e.gr_gid)
             self.check_value(e2)
             self.assertEqual(e2.gr_gid, e.gr_gid)
-            e2 = grp.getgrnam(e.gr_name)
+            name = e.gr_name
+            if name.startswith('+') or name.startswith('-'):
+                # NIS-related entry
+                continue
+            e2 = grp.getgrnam(name)
             self.check_value(e2)
             # There are instances where getgrall() returns group names in
             # lowercase while getgrgid() returns proper casing.
             # Discovered on Ubuntu 5.04 (custom).
-            self.assertEqual(e2.gr_name.lower(), e.gr_name.lower())
+            self.assertEqual(e2.gr_name.lower(), name.lower())
 
     def test_errors(self):
         self.assertRaises(TypeError, grp.getgrgid)

Modified: python/branches/release31-maint/Misc/ACKS
==============================================================================
--- python/branches/release31-maint/Misc/ACKS	(original)
+++ python/branches/release31-maint/Misc/ACKS	Tue Dec 14 17:24:18 2010
@@ -369,6 +369,7 @@
 Fredrik H??rd
 Mihai Ibanescu
 Lars Immisch
+Bobby Impollonia
 Meador Inge
 Tony Ingraldi
 John Interrante

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Tue Dec 14 17:24:18 2010
@@ -47,6 +47,9 @@
 Tests
 -----
 
+- Issue #775964: test_grp now skips YP/NIS entries instead of failing when
+  encountering them.
+
 - Issue #7110: regrtest now sends test failure reports and single-failure
   tracebacks to stderr rather than stdout.
 

Modified: python/branches/release31-maint/Modules/grpmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/grpmodule.c	(original)
+++ python/branches/release31-maint/Modules/grpmodule.c	Tue Dec 14 17:24:18 2010
@@ -164,7 +164,9 @@
 name is not valid, raise KeyError."},
     {"getgrall",        grp_getgrall,   METH_NOARGS,
      "getgrall() -> list of tuples\n\
-Return a list of all available group entries, in arbitrary order."},
+Return a list of all available group entries, in arbitrary order.\n\
+An entry whose name starts with '+' or '-' represents an instruction\n\
+to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
     {NULL,              NULL}           /* sentinel */
 };
 

From python-checkins at python.org  Tue Dec 14 17:26:30 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 17:26:30 +0100 (CET)
Subject: [Python-checkins] r87240 - in python/branches/release27-maint:
	Doc/library/grp.rst Lib/test/test_grp.py Misc/ACKS Misc/NEWS
	Modules/grpmodule.c
Message-ID: <20101214162630.CB8F3EE9F2@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 17:26:30 2010
New Revision: 87240

Log:
Merged revisions 87238 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87238 | r.david.murray | 2010-12-14 11:20:53 -0500 (Tue, 14 Dec 2010) | 7 lines
  
  #775964: skip YP/NIS entries instead of failing the test
  
  Also includes doc updates mentioning that these entries may not
  be retrievable via getgrnam and getgrgid.
  
  Patch by Bobby Impollonia.
........


Modified:
   python/branches/release27-maint/   (props changed)
   python/branches/release27-maint/Doc/library/grp.rst
   python/branches/release27-maint/Lib/test/test_grp.py
   python/branches/release27-maint/Misc/ACKS
   python/branches/release27-maint/Misc/NEWS
   python/branches/release27-maint/Modules/grpmodule.c

Modified: python/branches/release27-maint/Doc/library/grp.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/grp.rst	(original)
+++ python/branches/release27-maint/Doc/library/grp.rst	Tue Dec 14 17:26:30 2010
@@ -31,7 +31,9 @@
 The gid is an integer, name and password are strings, and the member list is a
 list of strings. (Note that most users are not explicitly listed as members of
 the group they are in according to the password database.  Check both databases
-to get complete membership information.)
+to get complete membership information.  Also note that a ``gr_name`` that
+starts with a ``+`` or ``-`` is likely to be a YP/NIS reference and may not be
+accessible via :func:`getgrnam` or :func:`getgrgid`.)
 
 It defines the following items:
 

Modified: python/branches/release27-maint/Lib/test/test_grp.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_grp.py	(original)
+++ python/branches/release27-maint/Lib/test/test_grp.py	Tue Dec 14 17:26:30 2010
@@ -33,12 +33,16 @@
             e2 = grp.getgrgid(e.gr_gid)
             self.check_value(e2)
             self.assertEqual(e2.gr_gid, e.gr_gid)
-            e2 = grp.getgrnam(e.gr_name)
+            name = e.gr_name
+            if name.startswith('+') or name.startswith('-'):
+                # NIS-related entry
+                continue
+            e2 = grp.getgrnam(name)
             self.check_value(e2)
             # There are instances where getgrall() returns group names in
             # lowercase while getgrgid() returns proper casing.
             # Discovered on Ubuntu 5.04 (custom).
-            self.assertEqual(e2.gr_name.lower(), e.gr_name.lower())
+            self.assertEqual(e2.gr_name.lower(), name.lower())
 
     def test_errors(self):
         self.assertRaises(TypeError, grp.getgrgid)

Modified: python/branches/release27-maint/Misc/ACKS
==============================================================================
--- python/branches/release27-maint/Misc/ACKS	(original)
+++ python/branches/release27-maint/Misc/ACKS	Tue Dec 14 17:26:30 2010
@@ -375,6 +375,7 @@
 Fredrik H??rd
 Mihai Ibanescu
 Lars Immisch
+Bobby Impollonia
 Meador Inge
 Tony Ingraldi
 John Interrante

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Tue Dec 14 17:26:30 2010
@@ -46,6 +46,9 @@
 Tests
 -----
 
+- Issue #775964: test_grp now skips YP/NIS entries instead of failing when
+  encountering them.
+
 - Issue #7110: regrtest now sends test failure reports and single-failure
   tracebacks to stderr rather than stdout.
 

Modified: python/branches/release27-maint/Modules/grpmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/grpmodule.c	(original)
+++ python/branches/release27-maint/Modules/grpmodule.c	Tue Dec 14 17:26:30 2010
@@ -158,7 +158,9 @@
 name is not valid, raise KeyError."},
     {"getgrall",	grp_getgrall,	METH_NOARGS,
      "getgrall() -> list of tuples\n\
-Return a list of all available group entries, in arbitrary order."},
+Return a list of all available group entries, in arbitrary order.\n\
+An entry whose name starts with '+' or '-' represents an instruction\n\
+to use YP/NIS and may not be accessible via getgrnam or getgrgid."},
     {NULL,		NULL}		/* sentinel */
 };
 

From python-checkins at python.org  Tue Dec 14 19:18:55 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 19:18:55 +0100 (CET)
Subject: [Python-checkins] r87241 -
	python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py
Message-ID: <20101214181855.88A9FEE984@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 19:18:49 2010
New Revision: 87241

Log:
SIGCHLD is a more portable name than SIGCLD.  (OSX has no SIGCLD)


Modified:
   python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py

Modified: python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py	(original)
+++ python/branches/py3k/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 19:18:49 2010
@@ -2,5 +2,5 @@
 # On Linux this causes os.waitpid to fail with OSError as the OS has already
 # reaped our child process.  The wait() passing the OSError on to the caller
 # and causing us to exit with an error is what we are testing against.
-signal.signal(signal.SIGCLD, signal.SIG_IGN)
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

From python-checkins at python.org  Tue Dec 14 19:20:45 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 19:20:45 +0100 (CET)
Subject: [Python-checkins] r87242 -
	python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py
Message-ID: <20101214182045.35B7DEE984@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 19:20:45 2010
New Revision: 87242

Log:
SIGCHLD is a more portable name than SIGCLD (OSX has no SIGCLD).


Modified:
   python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py

Modified: python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py	(original)
+++ python/branches/release31-maint/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 19:20:45 2010
@@ -2,5 +2,5 @@
 # On Linux this causes os.waitpid to fail with OSError as the OS has already
 # reaped our child process.  The wait() passing the OSError on to the caller
 # and causing us to exit with an error is what we are testing against.
-signal.signal(signal.SIGCLD, signal.SIG_IGN)
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

From python-checkins at python.org  Tue Dec 14 19:21:59 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Tue, 14 Dec 2010 19:21:59 +0100 (CET)
Subject: [Python-checkins] r87243 -
	python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py
Message-ID: <20101214182159.C8515EE984@mail.python.org>

Author: gregory.p.smith
Date: Tue Dec 14 19:21:59 2010
New Revision: 87243

Log:
SIGCHLD is a more portable name than SIGCLD (OSX has no SIGCLD).


Modified:
   python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py

Modified: python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py
==============================================================================
--- python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py	(original)
+++ python/branches/release27-maint/Lib/test/subprocessdata/sigchild_ignore.py	Tue Dec 14 19:21:59 2010
@@ -2,5 +2,5 @@
 # On Linux this causes os.waitpid to fail with OSError as the OS has already
 # reaped our child process.  The wait() passing the OSError on to the caller
 # and causing us to exit with an error is what we are testing against.
-signal.signal(signal.SIGCLD, signal.SIG_IGN)
+signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()

From python-checkins at python.org  Tue Dec 14 20:28:26 2010
From: python-checkins at python.org (ezio.melotti)
Date: Tue, 14 Dec 2010 20:28:26 +0100 (CET)
Subject: [Python-checkins] r87244 - in tracker/instances:
	jython/html/style.css meta/html/style.css python-dev/html/style.css
Message-ID: <20101214192826.C550BEE9F8@mail.python.org>

Author: ezio.melotti
Date: Tue Dec 14 20:28:26 2010
New Revision: 87244

Log:
#364: specify foreground color when the background color is set

Modified:
   tracker/instances/jython/html/style.css
   tracker/instances/meta/html/style.css
   tracker/instances/python-dev/html/style.css

Modified: tracker/instances/jython/html/style.css
==============================================================================
--- tracker/instances/jython/html/style.css	(original)
+++ tracker/instances/jython/html/style.css	Tue Dec 14 20:28:26 2010
@@ -449,6 +449,7 @@
 input[type="radio"]:focus,
 input[type="password"]:focus,
 textarea:focus, select:focus {
+  color: #000000;
   background-color: #ffffc0;
 }
 

Modified: tracker/instances/meta/html/style.css
==============================================================================
--- tracker/instances/meta/html/style.css	(original)
+++ tracker/instances/meta/html/style.css	Tue Dec 14 20:28:26 2010
@@ -436,6 +436,7 @@
 input[type="radio"]:focus,
 input[type="password"]:focus,
 textarea:focus, select:focus {
+  color: #000000;
   background-color: #ffffc0;
 }
 

Modified: tracker/instances/python-dev/html/style.css
==============================================================================
--- tracker/instances/python-dev/html/style.css	(original)
+++ tracker/instances/python-dev/html/style.css	Tue Dec 14 20:28:26 2010
@@ -451,6 +451,7 @@
 input[type="radio"]:focus,
 input[type="password"]:focus,
 textarea:focus, select:focus {
+  color: #000000;
   background-color: #ffffc0;
 }
 

From python-checkins at python.org  Tue Dec 14 20:40:21 2010
From: python-checkins at python.org (vinay.sajip)
Date: Tue, 14 Dec 2010 20:40:21 +0100 (CET)
Subject: [Python-checkins] r87245 -
	python/branches/py3k/Doc/library/logging.rst
Message-ID: <20101214194021.E638BEE9A0@mail.python.org>

Author: vinay.sajip
Date: Tue Dec 14 20:40:21 2010
New Revision: 87245

Log:
Logging documentation update.

Modified:
   python/branches/py3k/Doc/library/logging.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Tue Dec 14 20:40:21 2010
@@ -42,32 +42,33 @@
 +-------------------------------------+--------------------------------------+
 | Task you want to perform            | The best tool for the task           |
 +=====================================+======================================+
-| Display console output for ordinary | print()                              |
+| Display console output for ordinary | :func:`print`                        |
 | usage of a command line script or   |                                      |
 | program                             |                                      |
 +-------------------------------------+--------------------------------------+
-| Report events that occur during     | logging.info() (or logging.debug()   |
-| normal operation of a program (e.g. | for very detailed output for         |
-| for status monitoring or fault      | diagnostic purposes)                 |
-| investigation)                      |                                      |
+| Report events that occur during     | :func:`logging.info` (or             |
+| normal operation of a program (e.g. | :func:`logging.debug` for very       |
+| for status monitoring or fault      | detailed output for diagnostic       |
+| investigation)                      | purposes)                            |
 +-------------------------------------+--------------------------------------+
-| Issue a warning regarding a         | warnings.warn() in library code      |
-| particular runtime event            | if the issue is avoidable and the    |
-|                                     | client application should be         |
+| Issue a warning regarding a         | :func:`warnings.warn` in library     |
+| particular runtime event            | code if the issue is avoidable and   |
+|                                     | the client application should be     |
 |                                     | modified to eliminate the warning    |
 |                                     |                                      |
-|                                     | logging.warn() if there is nothing   |
-|                                     | the client application can do about  |
-|                                     | the situation, but the event should  |
-|                                     | still be noted                       |
+|                                     | :func:`logging.warning` if there is  |
+|                                     | nothing the client application can do|
+|                                     | about the situation, but the event   |
+|                                     | should still be noted                |
 +-------------------------------------+--------------------------------------+
 | Report an error regarding a         | Raise an exception                   |
 | particular runtime event            |                                      |
 +-------------------------------------+--------------------------------------+
-| Report suppression of an error      | logging.error(), logging.exception(),|
-| without raising an exception (e.g.  | or logging.critical() as appropriate |
-| error handler in a long-running     | for the specific error and           |
-| server process)                     | application domain                   |
+| Report suppression of an error      | :func:`logging.error`,               |
+| without raising an exception (e.g.  | :func:`logging.exception` or         |
+| error handler in a long-running     | :func:`logging.critical` as          |
+| server process)                     | appropriate for the specific error   |
+|                                     | and application domain               |
 +-------------------------------------+--------------------------------------+
 
 The logging functions are named after the level or severity of the events
@@ -85,7 +86,7 @@
 +--------------+---------------------------------------------+
 | ``WARNING``  | An indication that something unexpected     |
 |              | happened, or indicative of some problem in  |
-|              | the near future (e.g. "disk space low").    |
+|              | the near future (e.g. 'disk space low').    |
 |              | The software is still working as expected.  |
 +--------------+---------------------------------------------+
 | ``ERROR``    | Due to a more serious problem, the software |
@@ -214,7 +215,7 @@
    def do_something():
        logging.info('Doing something')
 
-If you run myapp.py, you should see this in myapp.log::
+If you run *myapp.py*, you should see this in *myapp.log*::
 
    INFO:root:Started
    INFO:root:Doing something
@@ -279,7 +280,7 @@
 Displaying the date/time in messages
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-To display the date and time of an event, you would place "%(asctime)s" in
+To display the date and time of an event, you would place '%(asctime)s' in
 your format string::
 
    import logging
@@ -337,17 +338,20 @@
 ---------------------
 
 The logging library takes a modular approach and offers several categories
-of components: loggers, handlers, filters, and formatters.  Loggers expose the
-interface that application code directly uses.  Handlers send the log records
-(created by loggers) to the appropriate destination. Filters provide a finer
-grained facility for determining which log records to output. Formatters
-specify the layout of the resultant log record in the final output.
+of components: loggers, handlers, filters, and formatters.
+
+* Loggers expose the interface that application code directly uses.
+* Handlers send the log records (created by loggers) to the appropriate
+  destination.
+* Filters provide a finer grained facility for determining which log records
+  to output.
+* Formatters specify the layout of log records in the final output.
 
 Logging is performed by calling methods on instances of the :class:`Logger`
 class (hereafter called :dfn:`loggers`). Each instance has a name, and they are
 conceptually arranged in a namespace hierarchy using dots (periods) as
-separators. For example, a logger named "scan" is the parent of loggers
-"scan.text", "scan.html" and "scan.pdf". Logger names can be anything you want,
+separators. For example, a logger named 'scan' is the parent of loggers
+'scan.text', 'scan.html' and 'scan.pdf'. Logger names can be anything you want,
 and indicate the area of an application in which a logged message originates.
 
 A good convention to use when naming loggers is to use a module-level logger,
@@ -365,11 +369,11 @@
 root logger's name is printed as 'root' in the logged output.
 
 It is, of course, possible to log messages to different destinations. Support
-for writing log messages to files, HTTP GET/POST locations, email via SMTP,
-generic sockets, or OS-specific logging mechanisms is included in the package.
-Destinations are served by :dfn:`handler` classes. You can create your own log
-destination class if you have special requirements not met by any of the
-built-in handler classes.
+is included in the package for writing log messages to files, HTTP GET/POST
+locations, email via SMTP, generic sockets, queues, or OS-specific logging
+mechanisms such as syslog or the Windows NT event log. Destinations are served
+by :dfn:`handler` classes. You can create your own log destination class if
+you have special requirements not met by any of the built-in handler classes.
 
 By default, no destination is set for any logging messages. You can specify
 a destination (such as console or file) by using :func:`basicConfig` as in the
@@ -537,7 +541,7 @@
 format, the severity of the message, and the contents of the message, in that
 order::
 
-    "%(asctime)s - %(levelname)s - %(message)s"
+    '%(asctime)s - %(levelname)s - %(message)s'
 
 Formatters use a user-configurable function to convert the creation time of a
 record to a tuple. By default, :func:`time.localtime` is used; to change this
@@ -566,7 +570,7 @@
     import logging
 
     # create logger
-    logger = logging.getLogger("simple_example")
+    logger = logging.getLogger('simple_example')
     logger.setLevel(logging.DEBUG)
 
     # create console handler and set level to debug
@@ -574,7 +578,7 @@
     ch.setLevel(logging.DEBUG)
 
     # create formatter
-    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
     # add formatter to ch
     ch.setFormatter(formatter)
@@ -582,12 +586,12 @@
     # add ch to logger
     logger.addHandler(ch)
 
-    # "application" code
-    logger.debug("debug message")
-    logger.info("info message")
-    logger.warn("warn message")
-    logger.error("error message")
-    logger.critical("critical message")
+    # 'application' code
+    logger.debug('debug message')
+    logger.info('info message')
+    logger.warn('warn message')
+    logger.error('error message')
+    logger.critical('critical message')
 
 Running this module from the command line produces the following output::
 
@@ -605,17 +609,17 @@
     import logging
     import logging.config
 
-    logging.config.fileConfig("logging.conf")
+    logging.config.fileConfig('logging.conf')
 
     # create logger
-    logger = logging.getLogger("simpleExample")
+    logger = logging.getLogger('simpleExample')
 
-    # "application" code
-    logger.debug("debug message")
-    logger.info("info message")
-    logger.warn("warn message")
-    logger.error("error message")
-    logger.critical("critical message")
+    # 'application' code
+    logger.debug('debug message')
+    logger.info('info message')
+    logger.warn('warn message')
+    logger.error('error message')
+    logger.critical('critical message')
 
 Here is the logging.conf file::
 
@@ -720,11 +724,11 @@
   silently dropped.
 
 * If *logging.raiseExceptions* is *True* (development mode), a message
-  "No handlers could be found for logger X.Y.Z" is printed once.
+  'No handlers could be found for logger X.Y.Z' is printed once.
 
 In Python 3.2 and later, the behaviour is as follows:
 
-* The event is output using a 'handler of last resort", stored in
+* The event is output using a 'handler of last resort', stored in
   ``logging.lastResort``. This internal handler is not associated with any
   logger, and acts like a :class:`StreamHandler` which writes the event
   description message to the current value of ``sys.stderr`` (therefore
@@ -776,7 +780,7 @@
 configuration of handlers is the prerogative of the application developer who
 uses your library. The application developer knows their target audience and
 what handlers are most appropriate for their application: if you add handlers
-"under the hood", you might well interfere with their ability to carry out
+'under the hood', you might well interfere with their ability to carry out
 unit tests and deliver logs which suit their requirements.
 
 
@@ -910,8 +914,8 @@
 .. currentmodule:: logging
 
 #. :class:`NullHandler` instances do nothing with error messages. They are used
-   by library developers who want to use logging, but want to avoid the "No
-   handlers could be found for logger XXX" message which can be displayed if
+   by library developers who want to use logging, but want to avoid the 'No
+   handlers could be found for logger XXX' message which can be displayed if
    the library user has not configured logging. See :ref:`library-config` for
    more information.
 
@@ -957,7 +961,7 @@
 
    Return a logger with the specified name or, if name is ``None``, return a
    logger which is the root logger of the hierarchy. If specified, the name is
-   typically a dot-separated hierarchical name like *"a"*, *"a.b"* or *"a.b.c.d"*.
+   typically a dot-separated hierarchical name like *'a'*, *'a.b'* or *'a.b.c.d'*.
    Choice of these names is entirely up to the developer who is using logging.
 
    All calls to this function with a given name return the same logger instance.
@@ -1025,10 +1029,10 @@
    be used as you like. For example, they could be incorporated into logged
    messages. For example::
 
-      FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
+      FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
       logging.basicConfig(format=FORMAT)
       d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
-      logging.warning("Protocol problem: %s", "connection reset", extra=d)
+      logging.warning('Protocol problem: %s', 'connection reset', extra=d)
 
    would print something like::
 
@@ -1130,7 +1134,7 @@
    have associated levels with names using :func:`addLevelName` then the name you
    have associated with *lvl* is returned. If a numeric value corresponding to one
    of the defined levels is passed in, the corresponding string representation is
-   returned. Otherwise, the string "Level %s" % lvl is returned.
+   returned. Otherwise, the string 'Level %s' % lvl is returned.
 
 
 .. function:: makeLogRecord(attrdict)
@@ -1225,7 +1229,7 @@
 
    The factory has the following signature:
 
-   ``factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, \*\*kwargs)``
+   ``factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)``
 
       :name: The logger name.
       :level: The logging level (numeric).
@@ -1279,7 +1283,7 @@
    the root logger, or delegation to the parent when the logger is a non-root
    logger). Note that the root logger is created with level :const:`WARNING`.
 
-   The term "delegation to the parent" means that if a logger has a level of
+   The term 'delegation to the parent' means that if a logger has a level of
    NOTSET, its chain of ancestor loggers is traversed until either an ancestor with
    a level other than NOTSET is found, or the root is reached.
 
@@ -1355,11 +1359,11 @@
    be used as you like. For example, they could be incorporated into logged
    messages. For example::
 
-      FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
+      FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
       logging.basicConfig(format=FORMAT)
       d = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' }
-      logger = logging.getLogger("tcpserver")
-      logger.warning("Protocol problem: %s", "connection reset", extra=d)
+      logger = logging.getLogger('tcpserver')
+      logger.warning('Protocol problem: %s', 'connection reset', extra=d)
 
    would print something like  ::
 
@@ -1475,7 +1479,7 @@
    Checks to see if this logger has any handlers configured. This is done by
    looking for handlers in this logger and its parents in the logger hierarchy.
    Returns True if a handler was found, else False. The method stops searching
-   up the hierarchy whenever a logger with the "propagate" attribute set to
+   up the hierarchy whenever a logger with the 'propagate' attribute set to
    False is found - that will be the last logger which is checked for the
    existence of handlers.
 
@@ -1549,7 +1553,7 @@
 +-------------------+-----------------------------------------------+
 | ``%(asctime)s``   | Human-readable time when the                  |
 |                   | :class:`LogRecord` was created.  By default   |
-|                   | this is of the form "2003-07-08 16:49:45,896" |
+|                   | this is of the form '2003-07-08 16:49:45,896' |
 |                   | (the numbers after the comma are millisecond  |
 |                   | portion of the time).                         |
 +-------------------+-----------------------------------------------+
@@ -1705,7 +1709,7 @@
 You will notice that these log messages all have ``root`` embedded in them.  The
 logging module supports a hierarchy of loggers with different names.  An easy
 way to tell where a specific log message comes from is to use a separate logger
-object for each of your modules.  Each new logger "inherits" the configuration
+object for each of your modules.  Each new logger 'inherits' the configuration
 of its parent, and log messages sent to a logger include the name of that
 logger.  Optionally, each logger can be configured differently, so that messages
 from different modules are handled in different ways.  Let's look at a simple
@@ -1873,11 +1877,11 @@
 keyword arguments of the logging call, and it passes back (potentially)
 modified versions of these to use in the call to the underlying logger. The
 default implementation of this method leaves the message alone, but inserts
-an "extra" key in the keyword argument whose value is the dict-like object
-passed to the constructor. Of course, if you had passed an "extra" keyword
+an 'extra' key in the keyword argument whose value is the dict-like object
+passed to the constructor. Of course, if you had passed an 'extra' keyword
 argument in the call to the adapter, it will be silently overwritten.
 
-The advantage of using "extra" is that the values in the dict-like object are
+The advantage of using 'extra' is that the values in the dict-like object are
 merged into the :class:`LogRecord` instance's __dict__, allowing you to use
 customized strings with your :class:`Formatter` instances which know about
 the keys of the dict-like object. If you need a different method, e.g. if you
@@ -1885,7 +1889,7 @@
 you just need to subclass :class:`LoggerAdapter` and override :meth:`process`
 to do what you need. Here's an example script which uses this class, which
 also illustrates what dict-like behaviour is needed from an arbitrary
-"dict-like" object for use in the constructor::
+'dict-like' object for use in the constructor::
 
    import logging
 
@@ -1900,12 +1904,12 @@
            To allow this instance to look like a dict.
            """
            from random import choice
-           if name == "ip":
-               result = choice(["127.0.0.1", "192.168.0.1"])
-           elif name == "user":
-               result = choice(["jim", "fred", "sheila"])
+           if name == 'ip':
+               result = choice(['127.0.0.1', '192.168.0.1'])
+           elif name == 'user':
+               result = choice(['jim', 'fred', 'sheila'])
            else:
-               result = self.__dict__.get(name, "?")
+               result = self.__dict__.get(name, '?')
            return result
 
        def __iter__(self):
@@ -1913,24 +1917,24 @@
            To allow iteration over keys, which will be merged into
            the LogRecord dict before formatting and output.
            """
-           keys = ["ip", "user"]
+           keys = ['ip', 'user']
            keys.extend(self.__dict__.keys())
            return keys.__iter__()
 
-   if __name__ == "__main__":
+   if __name__ == '__main__':
        from random import choice
        levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
-       a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
-                                  { "ip" : "123.231.231.123", "user" : "sheila" })
+       a1 = logging.LoggerAdapter(logging.getLogger('a.b.c'),
+                                  { 'ip' : '123.231.231.123', 'user' : 'sheila' })
        logging.basicConfig(level=logging.DEBUG,
-                           format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s")
-       a1.debug("A debug message")
-       a1.info("An info message with %s", "some parameters")
-       a2 = logging.LoggerAdapter(logging.getLogger("d.e.f"), ConnInfo())
+                           format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+       a1.debug('A debug message')
+       a1.info('An info message with %s', 'some parameters')
+       a2 = logging.LoggerAdapter(logging.getLogger('d.e.f'), ConnInfo())
        for x in range(10):
            lvl = choice(levels)
            lvlname = logging.getLevelName(lvl)
-           a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters")
+           a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
 
 When this script is run, the output should look something like this::
 
@@ -1987,24 +1991,24 @@
             record.user = choice(ContextFilter.USERS)
             return True
 
-    if __name__ == "__main__":
+    if __name__ == '__main__':
        levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
-       a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
-                                  { "ip" : "123.231.231.123", "user" : "sheila" })
+       a1 = logging.LoggerAdapter(logging.getLogger('a.b.c'),
+                                  { 'ip' : '123.231.231.123', 'user' : 'sheila' })
        logging.basicConfig(level=logging.DEBUG,
-                           format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s")
-       a1 = logging.getLogger("a.b.c")
-       a2 = logging.getLogger("d.e.f")
+                           format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
+       a1 = logging.getLogger('a.b.c')
+       a2 = logging.getLogger('d.e.f')
 
        f = ContextFilter()
        a1.addFilter(f)
        a2.addFilter(f)
-       a1.debug("A debug message")
-       a1.info("An info message with %s", "some parameters")
+       a1.debug('A debug message')
+       a1.info('An info message with %s', 'some parameters')
        for x in range(10):
            lvl = choice(levels)
            lvlname = logging.getLevelName(lvl)
-           a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters")
+           a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
 
 which, when run, produces something like::
 
@@ -2231,7 +2235,7 @@
                chunk = self.connection.recv(4)
                if len(chunk) < 4:
                    break
-               slen = struct.unpack(">L", chunk)[0]
+               slen = struct.unpack('>L', chunk)[0]
                chunk = self.connection.recv(slen)
                while len(chunk) < slen:
                    chunk = chunk + self.connection.recv(slen - len(chunk))
@@ -2257,7 +2261,8 @@
            logger.handle(record)
 
    class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
-       """simple TCP socket-based logging receiver suitable for testing.
+       """
+       Simple TCP socket-based logging receiver suitable for testing.
        """
 
        allow_reuse_address = 1
@@ -2283,12 +2288,12 @@
 
    def main():
        logging.basicConfig(
-           format="%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s")
+           format='%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s')
        tcpserver = LogRecordSocketReceiver()
-       print("About to start TCP server...")
+       print('About to start TCP server...')
        tcpserver.serve_until_stopped()
 
-   if __name__ == "__main__":
+   if __name__ == '__main__':
        main()
 
 First run the server, and then the client. On the client side, nothing is
@@ -2395,7 +2400,7 @@
 created by the Logger for that level of call. You can write code like this::
 
     if logger.isEnabledFor(logging.DEBUG):
-        logger.debug("Message with %s, %s", expensive_func1(),
+        logger.debug('Message with %s, %s', expensive_func1(),
                                             expensive_func2())
 
 so that if the logger's threshold is set above ``DEBUG``, the calls to
@@ -2563,7 +2568,7 @@
 
 .. versionchanged:: 3.2
    The ``StreamHandler`` class now has a ``terminator`` attribute, default
-   value ``"\n"``, which is used as the terminator when writing a formatted
+   value ``'\n'``, which is used as the terminator when writing a formatted
    record to a stream. If you don't want this newline termination, you can
    set the handler instance's ``terminator`` attribute to the empty string.
 
@@ -2604,7 +2609,7 @@
 .. versionadded:: 3.1
 
 The :class:`NullHandler` class, located in the core :mod:`logging` package,
-does not do any formatting or output. It is essentially a "no-op" handler
+does not do any formatting or output. It is essentially a 'no-op' handler
 for use by library developers.
 
 .. class:: NullHandler()
@@ -2690,7 +2695,7 @@
    the file is closed and a new file is silently opened for output. Rollover occurs
    whenever the current log file is nearly *maxBytes* in length; if *maxBytes* is
    zero, rollover never occurs.  If *backupCount* is non-zero, the system will save
-   old log files by appending the extensions ".1", ".2" etc., to the filename. For
+   old log files by appending the extensions '.1', '.2' etc., to the filename. For
    example, with a *backupCount* of 5 and a base file name of :file:`app.log`, you
    would get :file:`app.log`, :file:`app.log.1`, :file:`app.log.2`, up to
    :file:`app.log.5`. The file being written to is always :file:`app.log`.  When
@@ -2887,7 +2892,7 @@
    the form of a ``(host, port)`` tuple.  If *address* is not specified,
    ``('localhost', 514)`` is used.  The address is used to open a socket.  An
    alternative to providing a ``(host, port)`` tuple is providing an address as a
-   string, for example "/dev/log". In this case, a Unix domain socket is used to
+   string, for example '/dev/log'. In this case, a Unix domain socket is used to
    send the message to the syslog. If *facility* is not specified,
    :const:`LOG_USER` is used. The type of socket opened depends on the
    *socktype* argument, which defaults to :const:`socket.SOCK_DGRAM` and thus
@@ -2897,8 +2902,8 @@
    Note that if your server is not listening on UDP port 514,
    :class:`SysLogHandler` may appear not to work. In that case, check what
    address you should be using for a domain socket - it's system dependent.
-   For example, on Linux it's usually "/dev/log" but on OS/X it's
-   "/var/run/syslog". You'll need to check your platform and use the
+   For example, on Linux it's usually '/dev/log' but on OS/X it's
+   '/var/run/syslog'. You'll need to check your platform and use the
    appropriate address (you may need to do this check at runtime if your
    application needs to run on several platforms). On Windows, you pretty
    much have to use the UDP option.
@@ -3002,7 +3007,7 @@
       if the default algorithm is not suitable for your needs. The
       default algorithm maps ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` and
       ``CRITICAL`` to the equivalent syslog names, and all other level
-      names to "warning".
+      names to 'warning'.
 
 .. _nt-eventlog-handler:
 
@@ -3326,7 +3331,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 You can use a :class:`QueueHandler` subclass to send messages to other kinds
-of queues, for example a ZeroMQ "publish" socket. In the example below,the
+of queues, for example a ZeroMQ 'publish' socket. In the example below,the
 socket is created separately and passed to the handler (as its 'queue')::
 
     import zmq # using pyzmq, the Python binding for ZeroMQ
@@ -3366,7 +3371,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 You can also subclass :class:`QueueListener` to get messages from other kinds
-of queues, for example a ZeroMQ "subscribe" socket. Here's an example::
+of queues, for example a ZeroMQ 'subscribe' socket. Here's an example::
 
     class ZeroMQSocketListener(QueueListener):
         def __init__(self, uri, *handlers, **kwargs):
@@ -3466,8 +3471,8 @@
 ``Filters`` can be used by ``Handlers`` and ``Loggers`` for more sophisticated
 filtering than is provided by levels. The base filter class only allows events
 which are below a certain point in the logger hierarchy. For example, a filter
-initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C",
-"A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the
+initialized with 'A.B' will allow events logged by loggers 'A.B', 'A.B.C',
+'A.B.C.D', 'A.B.D' etc. but not 'A.BB', 'B.A.B' etc. If initialized with the
 empty string, all events are passed.
 
 
@@ -3619,7 +3624,7 @@
 +----------------+-------------------------+-----------------------------------------------+
 | asctime        | ``%(asctime)s``         | Human-readable time when the                  |
 |                |                         | :class:`LogRecord` was created.  By default   |
-|                |                         | this is of the form "2003-07-08 16:49:45,896" |
+|                |                         | this is of the form '2003-07-08 16:49:45,896' |
 |                |                         | (the numbers after the comma are millisecond  |
 |                |                         | portion of the time).                         |
 +----------------+-------------------------+-----------------------------------------------+
@@ -3749,7 +3754,7 @@
    If *capture* is ``True``, warnings issued by the :mod:`warnings` module will
    be redirected to the logging system. Specifically, a warning will be
    formatted using :func:`warnings.formatwarning` and the resulting string
-   logged to a logger named "py.warnings" with a severity of `WARNING`.
+   logged to a logger named 'py.warnings' with a severity of `WARNING`.
 
    If *capture* is ``False``, the redirection of warnings to the logging system
    will stop, and warnings will be redirected to their original destinations
@@ -3852,8 +3857,8 @@
 
 Describing a logging configuration requires listing the various
 objects to create and the connections between them; for example, you
-may create a handler named "console" and then say that the logger
-named "startup" will send its messages to the "console" handler.
+may create a handler named 'console' and then say that the logger
+named 'startup' will send its messages to the 'console' handler.
 These objects aren't limited to those provided by the :mod:`logging`
 module because you might write your own formatter or handler class.
 The parameters to these classes may also need to include external
@@ -4316,7 +4321,7 @@
 
 The ``class`` entry indicates the handler's class (as determined by :func:`eval`
 in the ``logging`` package's namespace). The ``level`` is interpreted as for
-loggers, and ``NOTSET`` is taken to mean "log everything".
+loggers, and ``NOTSET`` is taken to mean 'log everything'.
 
 The ``formatter`` entry indicates the key name of the formatter for this
 handler. If blank, a default formatter (``logging._defaultFormatter``) is used.
@@ -4387,7 +4392,7 @@
 The ``format`` entry is the overall format string, and the ``datefmt`` entry is
 the :func:`strftime`\ -compatible date/time format string.  If empty, the
 package substitutes ISO8601 format date/times, which is almost equivalent to
-specifying the date format string ``"%Y-%m-%d %H:%M:%S"``.  The ISO8601 format
+specifying the date format string ``'%Y-%m-%d %H:%M:%S'``.  The ISO8601 format
 also specifies milliseconds, which are appended to the result of using the above
 format string, with a comma separator.  An example time in ISO8601 format is
 ``2003-01-23 00:29:50,411``.
@@ -4409,23 +4414,23 @@
     import os
 
     # read initial config file
-    logging.config.fileConfig("logging.conf")
+    logging.config.fileConfig('logging.conf')
 
     # create and start listener on port 9999
     t = logging.config.listen(9999)
     t.start()
 
-    logger = logging.getLogger("simpleExample")
+    logger = logging.getLogger('simpleExample')
 
     try:
         # loop through logging calls to see the difference
         # new configurations make, until Ctrl+C is pressed
         while True:
-            logger.debug("debug message")
-            logger.info("info message")
-            logger.warn("warn message")
-            logger.error("error message")
-            logger.critical("critical message")
+            logger.debug('debug message')
+            logger.info('info message')
+            logger.warn('warn message')
+            logger.error('error message')
+            logger.critical('critical message')
             time.sleep(5)
     except KeyboardInterrupt:
         # cleanup
@@ -4439,18 +4444,18 @@
     #!/usr/bin/env python
     import socket, sys, struct
 
-    data_to_send = open(sys.argv[1], "r").read()
+    data_to_send = open(sys.argv[1], 'r').read()
 
     HOST = 'localhost'
     PORT = 9999
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    print("connecting...")
+    print('connecting...')
     s.connect((HOST, PORT))
-    print("sending config...")
-    s.send(struct.pack(">L", len(data_to_send)))
+    print('sending config...')
+    s.send(struct.pack('>L', len(data_to_send)))
     s.send(data_to_send)
     s.close()
-    print("complete")
+    print('complete')
 
 
 More examples
@@ -4469,30 +4474,30 @@
 
     import logging
 
-    logger = logging.getLogger("simple_example")
+    logger = logging.getLogger('simple_example')
     logger.setLevel(logging.DEBUG)
     # create file handler which logs even debug messages
-    fh = logging.FileHandler("spam.log")
+    fh = logging.FileHandler('spam.log')
     fh.setLevel(logging.DEBUG)
     # create console handler with a higher log level
     ch = logging.StreamHandler()
     ch.setLevel(logging.ERROR)
     # create formatter and add it to the handlers
-    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     ch.setFormatter(formatter)
     fh.setFormatter(formatter)
     # add the handlers to logger
     logger.addHandler(ch)
     logger.addHandler(fh)
 
-    # "application" code
-    logger.debug("debug message")
-    logger.info("info message")
-    logger.warn("warn message")
-    logger.error("error message")
-    logger.critical("critical message")
+    # 'application' code
+    logger.debug('debug message')
+    logger.info('info message')
+    logger.warn('warn message')
+    logger.error('error message')
+    logger.critical('critical message')
 
-Notice that the "application" code does not care about multiple handlers.  All
+Notice that the 'application' code does not care about multiple handlers.  All
 that changed was the addition and configuration of a new handler named *fh*.
 
 The ability to create new handlers with higher- or lower-severity filters can be
@@ -4519,51 +4524,51 @@
     import logging
     import auxiliary_module
 
-    # create logger with "spam_application"
-    logger = logging.getLogger("spam_application")
+    # create logger with 'spam_application'
+    logger = logging.getLogger('spam_application')
     logger.setLevel(logging.DEBUG)
     # create file handler which logs even debug messages
-    fh = logging.FileHandler("spam.log")
+    fh = logging.FileHandler('spam.log')
     fh.setLevel(logging.DEBUG)
     # create console handler with a higher log level
     ch = logging.StreamHandler()
     ch.setLevel(logging.ERROR)
     # create formatter and add it to the handlers
-    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     fh.setFormatter(formatter)
     ch.setFormatter(formatter)
     # add the handlers to the logger
     logger.addHandler(fh)
     logger.addHandler(ch)
 
-    logger.info("creating an instance of auxiliary_module.Auxiliary")
+    logger.info('creating an instance of auxiliary_module.Auxiliary')
     a = auxiliary_module.Auxiliary()
-    logger.info("created an instance of auxiliary_module.Auxiliary")
-    logger.info("calling auxiliary_module.Auxiliary.do_something")
+    logger.info('created an instance of auxiliary_module.Auxiliary')
+    logger.info('calling auxiliary_module.Auxiliary.do_something')
     a.do_something()
-    logger.info("finished auxiliary_module.Auxiliary.do_something")
-    logger.info("calling auxiliary_module.some_function()")
+    logger.info('finished auxiliary_module.Auxiliary.do_something')
+    logger.info('calling auxiliary_module.some_function()')
     auxiliary_module.some_function()
-    logger.info("done with auxiliary_module.some_function()")
+    logger.info('done with auxiliary_module.some_function()')
 
 Here is the auxiliary module::
 
     import logging
 
     # create logger
-    module_logger = logging.getLogger("spam_application.auxiliary")
+    module_logger = logging.getLogger('spam_application.auxiliary')
 
     class Auxiliary:
         def __init__(self):
-            self.logger = logging.getLogger("spam_application.auxiliary.Auxiliary")
-            self.logger.info("creating an instance of Auxiliary")
+            self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
+            self.logger.info('creating an instance of Auxiliary')
         def do_something(self):
-            self.logger.info("doing something")
+            self.logger.info('doing something')
             a = 1 + 1
-            self.logger.info("done doing something")
+            self.logger.info('done doing something')
 
     def some_function():
-        module_logger.info("received a call to \"some_function\"")
+        module_logger.info('received a call to "some_function"')
 
 The output looks like this::
 
@@ -4584,7 +4589,7 @@
     2005-03-23 23:47:11,671 - spam_application - INFO -
        calling auxiliary_module.some_function()
     2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO -
-       received a call to "some_function"
+       received a call to 'some_function'
     2005-03-23 23:47:11,673 - spam_application - INFO -
        done with auxiliary_module.some_function()
 

From python-checkins at python.org  Tue Dec 14 22:12:03 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 14 Dec 2010 22:12:03 +0100 (CET)
Subject: [Python-checkins] r87246 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20101214211203.AAC1FEE9A9@mail.python.org>

Author: raymond.hettinger
Date: Tue Dec 14 22:12:03 2010
New Revision: 87246

Log:
Nits

Modified:
   python/branches/py3k/Doc/whatsnew/3.2.rst

Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst	Tue Dec 14 22:12:03 2010
@@ -47,9 +47,9 @@
    This saves the maintainer the effort of going through the SVN log
    when researching a change.
 
-This article explains the new features in Python 3.2, compared to 3.1.
-It focuses on a few highlights and gives a few examples.  For full details,
-see the :file:`Misc/NEWS` file.
+This article explains the new features in Python 3.2 as compared to 3.1.  It
+focuses on a few highlights and gives a few examples.  For full details, see the
+:source:`Misc/NEWS ` file.
 
 
 PEP 384: Defining a Stable ABI
@@ -396,7 +396,7 @@
   :class:`~email.message.Message` object and can optionally obtain the
   *from_addr* and *to_addrs* addresses directly from the object.
 
-.. XXX Update before 3.2rc1 to reflect all of the last work and add examples.
+.. XXX Update before 3.2rc1 to reflect all of the latest work and add examples.
 
   (Proposed and implemented by R. David Murray, :issue:`4661` and :issue:`10321`.)
 
@@ -619,7 +619,7 @@
   `_ and the new
   :meth:`~collections.Counter.subtract` method for regular subtraction.  The
   former is suitable for `multisets `_
-  which only have positive counts, and the latter is more suitable for counters
+  which only have positive counts, and the latter is more suitable for use cases
   that allow negative counts:
 
   >>> tally = Counter(dogs=5, cat=3)
@@ -813,8 +813,9 @@
   ...     legacy_function('XYZ')
 
   Another new method, :meth:`~unittest.TestCase.assertCountEqual` is used to
-  compare two iterables to determine if their element counts are equal (are the
-  same elements present the same number of times::
+  compare two iterables to determine if their element counts are equal (whether
+  the same elements are present with the same number of occurrences regardless
+  of order)::
 
      def test_anagram(self):
          self.assertCountEqual('algorithm', 'logarithm')
@@ -906,7 +907,7 @@
 
 * The new :mod:`sysconfig` module makes it straight-forward to discover
   installation paths and configuration variables which vary across platforms and
-  installs.
+  installations.
 
   The module offers access simple access functions for platform and version
   information:
@@ -1031,7 +1032,7 @@
   and the Unladen Swallow team in :issue:`9410` and :issue:`3873`.)
 
 * The `Timsort algorithm `_ used in
-  :meth:`list.sort` and :func:`sorted` now runs faster and used less memory
+  :meth:`list.sort` and :func:`sorted` now runs faster and uses less memory
   when called with a :term:`key function`.  Previously, every element of
   a list was wrapped with a temporary object that remembered the key value
   associated with each element.  Now, an array of keys and values are

From python-checkins at python.org  Tue Dec 14 23:06:10 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Dec 2010 23:06:10 +0100 (CET)
Subject: [Python-checkins] r87247 - python/branches/py3k/README
Message-ID: <20101214220610.E5214EE98D@mail.python.org>

Author: antoine.pitrou
Date: Tue Dec 14 23:06:10 2010
New Revision: 87247

Log:
Freshen README contents



Modified:
   python/branches/py3k/README

Modified: python/branches/py3k/README
==============================================================================
--- python/branches/py3k/README	(original)
+++ python/branches/py3k/README	Tue Dec 14 23:06:10 2010
@@ -97,10 +97,7 @@
 left by the previous test run).  The test set produces some output.  You can
 generally ignore the messages about skipped tests due to optional features which
 can't be imported.  If a message is printed about a failed test or a traceback
-or core dump is produced, something is wrong.  On some Linux systems (those that
-are not yet using glibc 6), test_strftime fails due to a non-standard
-implementation of strftime() in the C library. Please ignore this, or upgrade to
-glibc version 6.
+or core dump is produced, something is wrong.
 
 By default, tests are prevented from overusing resources like disk space and
 memory.  To enable these tests, run "make testall".
@@ -109,7 +106,7 @@
 include the output of "make test".  It is useless.  Run the failing test
 manually, as follows:
 
-        ./python Lib/test/regrtest.py -v test_whatever
+        ./python -m test -v test_whatever
 
 (substituting the top of the source tree for '.' if you built in a different
 directory).  This runs the test in verbose mode.

From python-checkins at python.org  Tue Dec 14 23:32:51 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 23:32:51 +0100 (CET)
Subject: [Python-checkins] r87248 - in python/branches/py3k/Lib:
	compileall.py test/test_compileall.py
Message-ID: <20101214223251.51BBBEE98B@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 23:32:50 2010
New Revision: 87248

Log:
More comprehensive compileall cli tests, and fixes.


Modified:
   python/branches/py3k/Lib/compileall.py
   python/branches/py3k/Lib/test/test_compileall.py

Modified: python/branches/py3k/Lib/compileall.py
==============================================================================
--- python/branches/py3k/Lib/compileall.py	(original)
+++ python/branches/py3k/Lib/compileall.py	Tue Dec 14 23:32:50 2010
@@ -181,24 +181,29 @@
                               'of the file'))
     parser.add_argument('-i', metavar='FILE', dest='flist',
                         help='expand the list with the content of FILE.')
-    parser.add_argument('compile_dest', metavar='FILE|DIR', nargs='?')
+    parser.add_argument('compile_dest', metavar='FILE|DIR', nargs='*')
     args = parser.parse_args()
 
-    if (args.ddir and args.compile_dest != 1 and
-        not os.path.isdir(args.compile_dest)):
-        raise argparse.ArgumentError(
-            "-d destdir requires exactly one directory argument")
+    compile_dests = args.compile_dest
+
+    if (args.ddir and (len(compile_dests) != 1
+            or not os.path.isdir(compile_dests[0]))):
+        parser.exit('-d destdir requires exactly one directory argument')
     if args.rx:
         import re
         args.rx = re.compile(args.rx)
 
     # if flist is provided then load it
-    compile_dests = [args.compile_dest]
     if args.flist:
-        with open(args.flist) as f:
-            files = f.read().split()
-            compile_dests.extend(files)
+        try:
+            with (sys.stdin if args.flist=='-' else open(args.flist)) as f:
+                for line in f:
+                    compile_dests.append(line.strip())
+        except EnvironmentError:
+            print("Error reading file list {}".format(args.flist))
+            return False
 
+    success = True
     try:
         if compile_dests:
             for dest in compile_dests:
@@ -206,17 +211,18 @@
                     if not compile_dir(dest, args.maxlevels, args.ddir,
                                        args.force, args.rx, args.quiet,
                                        args.legacy):
-                        return 0
+                        success = False
                 else:
                     if not compile_file(dest, args.ddir, args.force, args.rx,
                                         args.quiet, args.legacy):
-                        return 0
+                        success = False
+            return success
         else:
             return compile_path(legacy=args.legacy)
     except KeyboardInterrupt:
         print("\n[interrupted]")
-        return 0
-    return 1
+        return False
+    return True
 
 
 if __name__ == '__main__':

Modified: python/branches/py3k/Lib/test/test_compileall.py
==============================================================================
--- python/branches/py3k/Lib/test/test_compileall.py	(original)
+++ python/branches/py3k/Lib/test/test_compileall.py	Tue Dec 14 23:32:50 2010
@@ -11,7 +11,7 @@
 import unittest
 import io
 
-from test import support
+from test import support, script_helper
 
 class CompileallTests(unittest.TestCase):
 
@@ -124,16 +124,31 @@
 class CommandLineTests(unittest.TestCase):
     """Test compileall's CLI."""
 
+    def assertRunOK(self, *args):
+        rc, out, err = script_helper.assert_python_ok('-m', 'compileall', *args)
+        self.assertEqual(b'', err)
+        return out
+
+    def assertRunNotOK(self, *args):
+        rc, out, err = script_helper.assert_python_failure(
+                         '-m', 'compileall', *args)
+        return rc, out, err
+
+    def assertCompiled(self, fn):
+        self.assertTrue(os.path.exists(imp.cache_from_source(fn)))
+
+    def assertNotCompiled(self, fn):
+        self.assertFalse(os.path.exists(imp.cache_from_source(fn)))
+
     def setUp(self):
         self.addCleanup(self._cleanup)
         self.directory = tempfile.mkdtemp()
         self.pkgdir = os.path.join(self.directory, 'foo')
         os.mkdir(self.pkgdir)
-        # Touch the __init__.py and a package module.
-        with open(os.path.join(self.pkgdir, '__init__.py'), 'w'):
-            pass
-        with open(os.path.join(self.pkgdir, 'bar.py'), 'w'):
-            pass
+        self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__')
+        # Create the __init__.py and a package module.
+        self.initfn = script_helper.make_script(self.pkgdir, '__init__', '')
+        self.barfn = script_helper.make_script(self.pkgdir, 'bar', '')
         sys.path.insert(0, self.directory)
 
     def _cleanup(self):
@@ -149,103 +164,169 @@
         ('doubleoptimize', 'pyo', ['-OO']),
     ]:
         def f(self, ext=ext, switch=switch):
-            retcode = subprocess.call(
-                [sys.executable] + switch +
-                ['-m', 'compileall', '-q', self.pkgdir])
-            self.assertEqual(retcode, 0)
+            script_helper.assert_python_ok(*(switch +
+                ['-m', 'compileall', '-q', self.pkgdir]))
             # Verify the __pycache__ directory contents.
-            cachedir = os.path.join(self.pkgdir, '__pycache__')
-            self.assertTrue(os.path.exists(cachedir))
+            self.assertTrue(os.path.exists(self.pkgdir_cachedir))
             expected = sorted(base.format(imp.get_tag(), ext) for base in
                               ('__init__.{}.{}', 'bar.{}.{}'))
-            self.assertEqual(sorted(os.listdir(cachedir)), expected)
+            self.assertEqual(sorted(os.listdir(self.pkgdir_cachedir)), expected)
             # Make sure there are no .pyc files in the source directory.
-            self.assertFalse([pyc_file for pyc_file in os.listdir(self.pkgdir)
-                              if pyc_file.endswith(ext)])
+            self.assertFalse([fn for fn in os.listdir(self.pkgdir)
+                              if fn.endswith(ext)])
         locals()['test_pep3147_paths_' + name] = f
 
     def test_legacy_paths(self):
         # Ensure that with the proper switch, compileall leaves legacy
         # pyc/pyo files, and no __pycache__ directory.
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-b', '-q', self.pkgdir))
-        self.assertEqual(retcode, 0)
+        self.assertRunOK('-b', '-q', self.pkgdir)
         # Verify the __pycache__ directory contents.
-        cachedir = os.path.join(self.pkgdir, '__pycache__')
-        self.assertFalse(os.path.exists(cachedir))
+        self.assertFalse(os.path.exists(self.pkgdir_cachedir))
         expected = sorted(['__init__.py', '__init__.pyc', 'bar.py', 'bar.pyc'])
         self.assertEqual(sorted(os.listdir(self.pkgdir)), expected)
 
     def test_multiple_runs(self):
         # Bug 8527 reported that multiple calls produced empty
         # __pycache__/__pycache__ directories.
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-q', self.pkgdir))
-        self.assertEqual(retcode, 0)
+        self.assertRunOK('-q', self.pkgdir)
         # Verify the __pycache__ directory contents.
-        cachedir = os.path.join(self.pkgdir, '__pycache__')
-        self.assertTrue(os.path.exists(cachedir))
-        cachecachedir = os.path.join(cachedir, '__pycache__')
+        self.assertTrue(os.path.exists(self.pkgdir_cachedir))
+        cachecachedir = os.path.join(self.pkgdir_cachedir, '__pycache__')
         self.assertFalse(os.path.exists(cachecachedir))
         # Call compileall again.
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-q', self.pkgdir))
-        self.assertEqual(retcode, 0)
-        self.assertTrue(os.path.exists(cachedir))
+        self.assertRunOK('-q', self.pkgdir)
+        self.assertTrue(os.path.exists(self.pkgdir_cachedir))
         self.assertFalse(os.path.exists(cachecachedir))
 
     def test_force(self):
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-q', self.pkgdir))
-        self.assertEqual(retcode, 0)
-        pycpath = imp.cache_from_source(os.path.join(self.pkgdir, 'bar.py'))
+        self.assertRunOK('-q', self.pkgdir)
+        pycpath = imp.cache_from_source(self.barfn)
         # set atime/mtime backward to avoid file timestamp resolution issues
         os.utime(pycpath, (time.time()-60,)*2)
-        access = os.stat(pycpath).st_mtime
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-q', '-f', self.pkgdir))
-        self.assertEqual(retcode, 0)
-        access2 = os.stat(pycpath).st_mtime
-        self.assertNotEqual(access, access2)
-
-    def test_legacy(self):
-        # create a new module  XXX could rewrite using self.pkgdir
-        newpackage = os.path.join(self.pkgdir, 'spam')
-        os.mkdir(newpackage)
-        with open(os.path.join(newpackage, '__init__.py'), 'w'):
-            pass
-        with open(os.path.join(newpackage, 'ham.py'), 'w'):
-            pass
-        sourcefile = os.path.join(newpackage, 'ham.py')
-
-        retcode = subprocess.call(
-                (sys.executable, '-m', 'compileall',  '-q', '-l', self.pkgdir))
-        self.assertEqual(retcode, 0)
-        self.assertFalse(os.path.exists(imp.cache_from_source(sourcefile)))
-
-        retcode = subprocess.call(
-                (sys.executable, '-m', 'compileall', '-q', self.pkgdir))
-        self.assertEqual(retcode, 0)
-        self.assertTrue(os.path.exists(imp.cache_from_source(sourcefile)))
+        mtime = os.stat(pycpath).st_mtime
+        # without force, no recompilation
+        self.assertRunOK('-q', self.pkgdir)
+        mtime2 = os.stat(pycpath).st_mtime
+        self.assertEqual(mtime, mtime2)
+        # now force it.
+        self.assertRunOK('-q', '-f', self.pkgdir)
+        mtime2 = os.stat(pycpath).st_mtime
+        self.assertNotEqual(mtime, mtime2)
+
+    def test_recursion_control(self):
+        subpackage = os.path.join(self.pkgdir, 'spam')
+        os.mkdir(subpackage)
+        subinitfn = script_helper.make_script(subpackage, '__init__', '')
+        hamfn = script_helper.make_script(subpackage, 'ham', '')
+        self.assertRunOK('-q', '-l', self.pkgdir)
+        self.assertNotCompiled(subinitfn)
+        self.assertFalse(os.path.exists(os.path.join(subpackage, '__pycache__')))
+        self.assertRunOK('-q', self.pkgdir)
+        self.assertCompiled(subinitfn)
+        self.assertCompiled(hamfn)
 
     def test_quiet(self):
-        noise = subprocess.check_output(
-             [sys.executable, '-m', 'compileall', self.pkgdir],
-             stderr=subprocess.STDOUT)
-        quiet = subprocess.check_output(
-            [sys.executable, '-m', 'compileall', '-f', '-q', self.pkgdir],
-            stderr=subprocess.STDOUT)
-        self.assertGreater(len(noise), len(quiet))
+        noisy = self.assertRunOK(self.pkgdir)
+        quiet = self.assertRunOK('-q', self.pkgdir)
+        self.assertNotEqual(b'', noisy)
+        self.assertEqual(b'', quiet)
 
     def test_regexp(self):
-        retcode = subprocess.call(
-            (sys.executable, '-m', 'compileall', '-q', '-x', 'bar.*', self.pkgdir))
-        self.assertEqual(retcode, 0)
-
-        sourcefile = os.path.join(self.pkgdir, 'bar.py')
-        self.assertFalse(os.path.exists(imp.cache_from_source(sourcefile)))
-        sourcefile = os.path.join(self.pkgdir, '__init__.py')
-        self.assertTrue(os.path.exists(imp.cache_from_source(sourcefile)))
+        self.assertRunOK('-q', '-x', 'ba.*', self.pkgdir)
+        self.assertNotCompiled(self.barfn)
+        self.assertCompiled(self.initfn)
+
+    def test_multiple_dirs(self):
+        pkgdir2 = os.path.join(self.directory, 'foo2')
+        os.mkdir(pkgdir2)
+        init2fn = script_helper.make_script(pkgdir2, '__init__', '')
+        bar2fn = script_helper.make_script(pkgdir2, 'bar2', '')
+        self.assertRunOK('-q', self.pkgdir, pkgdir2)
+        self.assertCompiled(self.initfn)
+        self.assertCompiled(self.barfn)
+        self.assertCompiled(init2fn)
+        self.assertCompiled(bar2fn)
+
+    def test_d_takes_exactly_one_dir(self):
+        rc, out, err = self.assertRunNotOK('-d', 'foo')
+        self.assertEqual(out, b'')
+        self.assertRegex(err, b'-d')
+        rc, out, err = self.assertRunNotOK('-d', 'foo', 'bar')
+        self.assertEqual(out, b'')
+        self.assertRegex(err, b'-d')
+
+    def test_d_compile_error(self):
+        script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax')
+        rc, out, err = self.assertRunNotOK('-q', '-d', 'dinsdale', self.pkgdir)
+        self.assertRegex(out, b'File "dinsdale')
+
+    def test_d_runtime_error(self):
+        bazfn = script_helper.make_script(self.pkgdir, 'baz', 'raise Exception')
+        self.assertRunOK('-q', '-d', 'dinsdale', self.pkgdir)
+        fn = script_helper.make_script(self.pkgdir, 'bing', 'import baz')
+        pyc = imp.cache_from_source(bazfn)
+        os.rename(pyc, os.path.join(self.pkgdir, 'baz.pyc'))
+        os.remove(bazfn)
+        rc, out, err = script_helper.assert_python_failure(fn)
+        self.assertRegex(err, b'File "dinsdale')
+
+    def test_include_bad_file(self):
+        rc, out, err = self.assertRunNotOK(
+            '-i', os.path.join(self.directory, 'nosuchfile'), self.pkgdir)
+        self.assertRegex(out, b'rror.*nosuchfile')
+        self.assertNotRegex(err, b'Traceback')
+        self.assertFalse(os.path.exists(imp.cache_from_source(
+                                            self.pkgdir_cachedir)))
+
+    def test_include_file_with_arg(self):
+        f1 = script_helper.make_script(self.pkgdir, 'f1', '')
+        f2 = script_helper.make_script(self.pkgdir, 'f2', '')
+        f3 = script_helper.make_script(self.pkgdir, 'f3', '')
+        f4 = script_helper.make_script(self.pkgdir, 'f4', '')
+        with open(os.path.join(self.directory, 'l1'), 'w') as l1:
+            l1.write(os.path.join(self.pkgdir, 'f1.py')+os.linesep)
+            l1.write(os.path.join(self.pkgdir, 'f2.py')+os.linesep)
+        self.assertRunOK('-i', os.path.join(self.directory, 'l1'), f4)
+        self.assertCompiled(f1)
+        self.assertCompiled(f2)
+        self.assertNotCompiled(f3)
+        self.assertCompiled(f4)
+
+    def test_include_file_no_arg(self):
+        f1 = script_helper.make_script(self.pkgdir, 'f1', '')
+        f2 = script_helper.make_script(self.pkgdir, 'f2', '')
+        f3 = script_helper.make_script(self.pkgdir, 'f3', '')
+        f4 = script_helper.make_script(self.pkgdir, 'f4', '')
+        with open(os.path.join(self.directory, 'l1'), 'w') as l1:
+            l1.write(os.path.join(self.pkgdir, 'f2.py')+os.linesep)
+        self.assertRunOK('-i', os.path.join(self.directory, 'l1'))
+        self.assertNotCompiled(f1)
+        self.assertCompiled(f2)
+        self.assertNotCompiled(f3)
+        self.assertNotCompiled(f4)
+
+    def test_include_on_stdin(self):
+        f1 = script_helper.make_script(self.pkgdir, 'f1', '')
+        f2 = script_helper.make_script(self.pkgdir, 'f2', '')
+        f3 = script_helper.make_script(self.pkgdir, 'f3', '')
+        f4 = script_helper.make_script(self.pkgdir, 'f4', '')
+        p = script_helper.spawn_python('-m', 'compileall', '-i', '-')
+        p.stdin.write((f3+os.linesep).encode('ascii'))
+        script_helper.kill_python(p)
+        self.assertNotCompiled(f1)
+        self.assertNotCompiled(f2)
+        self.assertCompiled(f3)
+        self.assertNotCompiled(f4)
+
+    def test_compiles_as_much_as_possible(self):
+        bingfn = script_helper.make_script(self.pkgdir, 'bing', 'syntax(error')
+        rc, out, err = self.assertRunNotOK('nosuchfile', self.initfn,
+                                           bingfn, self.barfn)
+        self.assertRegex(b'rror', err)
+        self.assertNotCompiled(bingfn)
+        self.assertCompiled(self.initfn)
+        self.assertCompiled(self.barfn)
+
 
 
 def test_main():

From python-checkins at python.org  Tue Dec 14 23:34:12 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 23:34:12 +0100 (CET)
Subject: [Python-checkins] r87249 - python/branches/release31-maint
Message-ID: <20101214223412.46FF5EE98B@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 23:34:12 2010
New Revision: 87249

Log:
Blocked revisions 87248 via svnmerge

........
  r87248 | r.david.murray | 2010-12-14 17:32:50 -0500 (Tue, 14 Dec 2010) | 2 lines
  
  More comprehensive compileall cli tests, and fixes.
........


Modified:
   python/branches/release31-maint/   (props changed)

From python-checkins at python.org  Tue Dec 14 23:35:07 2010
From: python-checkins at python.org (r.david.murray)
Date: Tue, 14 Dec 2010 23:35:07 +0100 (CET)
Subject: [Python-checkins] r87250 - python/branches/release27-maint
Message-ID: <20101214223507.86819EE98B@mail.python.org>

Author: r.david.murray
Date: Tue Dec 14 23:35:07 2010
New Revision: 87250

Log:
Blocked revisions 87248 via svnmerge

........
  r87248 | r.david.murray | 2010-12-14 17:32:50 -0500 (Tue, 14 Dec 2010) | 2 lines
  
  More comprehensive compileall cli tests, and fixes.
........


Modified:
   python/branches/release27-maint/   (props changed)

From python-checkins at python.org  Wed Dec 15 00:06:26 2010
From: python-checkins at python.org (r.david.murray)
Date: Wed, 15 Dec 2010 00:06:26 +0100 (CET)
Subject: [Python-checkins] r87251 - in python/branches/py3k:
	Lib/test/test_import.py Misc/NEWS Objects/moduleobject.c
Message-ID: <20101214230626.212B6EE98C@mail.python.org>

Author: r.david.murray
Date: Wed Dec 15 00:06:25 2010
New Revision: 87251

Log:
#4236: avoid possible Fatal Error when import is called from __del__

Patch by Simon Cross, crasher test code by Martin von L?wis.


Modified:
   python/branches/py3k/Lib/test/test_import.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/moduleobject.c

Modified: python/branches/py3k/Lib/test/test_import.py
==============================================================================
--- python/branches/py3k/Lib/test/test_import.py	(original)
+++ python/branches/py3k/Lib/test/test_import.py	Wed Dec 15 00:06:25 2010
@@ -9,11 +9,13 @@
 import stat
 import sys
 import unittest
+import textwrap
 
 from test.support import (
     EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
     make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask,
     unlink, unload)
+from test import script_helper
 
 
 def remove_files(name):
@@ -284,6 +286,17 @@
         self.assertEqual("Import by filename is not supported.",
                          c.exception.args[0])
 
+    def test_import_in_del_does_not_crash(self):
+        # Issue 4236
+        testfn = script_helper.make_script('', TESTFN, textwrap.dedent("""\
+            import sys
+            class C:
+               def __del__(self):
+                  import imp
+            sys.argv.insert(0, C())
+            """))
+        script_helper.assert_python_ok(testfn)
+
 
 class PycRewritingTests(unittest.TestCase):
     # Test that the `co_filename` attribute on code objects always points

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Dec 15 00:06:25 2010
@@ -7,6 +7,12 @@
 
 *Release date: XXXX-XX-XX*
 
+Core and Builtins
+-----------------
+
+- Issue #4236: PyModule_Create2 now checks the import machinery directly
+  rather than the Py_IsInitialized flag, avoiding a Fatal Python
+  error in certain circumstances when an import is done in __del__.
 
 Library
 -------

Modified: python/branches/py3k/Objects/moduleobject.c
==============================================================================
--- python/branches/py3k/Objects/moduleobject.c	(original)
+++ python/branches/py3k/Objects/moduleobject.c	Wed Dec 15 00:06:25 2010
@@ -63,8 +63,9 @@
     PyMethodDef *ml;
     const char* name;
     PyModuleObject *m;
-    if (!Py_IsInitialized())
-        Py_FatalError("Interpreter not initialized (version mismatch?)");
+    PyInterpreterState *interp = PyThreadState_Get()->interp;
+    if (interp->modules == NULL)
+        Py_FatalError("Python import machinery not initialized");
     if (PyType_Ready(&moduledef_type) < 0)
         return NULL;
     if (module->m_base.m_index == 0) {

From python-checkins at python.org  Wed Dec 15 00:30:42 2010
From: python-checkins at python.org (r.david.murray)
Date: Wed, 15 Dec 2010 00:30:42 +0100 (CET)
Subject: [Python-checkins] r87252 - in python/branches/release31-maint:
	Lib/test/test_import.py Misc/NEWS Objects/moduleobject.c
Message-ID: <20101214233042.363F8EE982@mail.python.org>

Author: r.david.murray
Date: Wed Dec 15 00:30:42 2010
New Revision: 87252

Log:
Merged revisions 87251 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/branches/py3k

........
  r87251 | r.david.murray | 2010-12-14 18:06:25 -0500 (Tue, 14 Dec 2010) | 4 lines
  
  #4236: avoid possible Fatal Error when import is called from __del__
  
  Patch by Simon Cross, crasher test code by Martin von L?wis.
........


Modified:
   python/branches/release31-maint/   (props changed)
   python/branches/release31-maint/Lib/test/test_import.py
   python/branches/release31-maint/Misc/NEWS
   python/branches/release31-maint/Objects/moduleobject.c

Modified: python/branches/release31-maint/Lib/test/test_import.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_import.py	(original)
+++ python/branches/release31-maint/Lib/test/test_import.py	Wed Dec 15 00:30:42 2010
@@ -9,10 +9,12 @@
 import sys
 import unittest
 import warnings
+import textwrap
 
 from test.support import (
     EnvironmentVarGuard, TESTFN, forget, is_jython,
     rmtree, run_unittest, unlink, unload)
+from test import script_helper
 
 
 def remove_files(name):
@@ -284,6 +286,17 @@
         else:
             self.fail("import by path didn't raise an exception")
 
+    def test_import_in_del_does_not_crash(self):
+        # Issue 4236
+        testfn = script_helper.make_script('', TESTFN, textwrap.dedent("""\
+            import sys
+            class C:
+               def __del__(self):
+                  import imp
+            sys.argv.insert(0, C())
+            """))
+        script_helper.assert_python_ok(testfn)
+
 
 class PycRewritingTests(unittest.TestCase):
     # Test that the `co_filename` attribute on code objects always points

Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Wed Dec 15 00:30:42 2010
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #4236: PyModule_Create2 now checks the import machinery directly
+  rather than the Py_IsInitialized flag, avoiding a Fatal Python
+  error in certain circumstances when an import is done in __del__.
+
 - Issue #10596: Fix float.__mod__ to have the same behaviour as
   float.__divmod__ with respect to signed zeros.  -4.0 % 4.0 should be
   0.0, not -0.0.

Modified: python/branches/release31-maint/Objects/moduleobject.c
==============================================================================
--- python/branches/release31-maint/Objects/moduleobject.c	(original)
+++ python/branches/release31-maint/Objects/moduleobject.c	Wed Dec 15 00:30:42 2010
@@ -67,8 +67,9 @@
     PyMethodDef *ml;
     const char* name;
     PyModuleObject *m;
-    if (!Py_IsInitialized())
-        Py_FatalError("Interpreter not initialized (version mismatch?)");
+    PyInterpreterState *interp = PyThreadState_Get()->interp;
+    if (interp->modules == NULL)
+        Py_FatalError("Python import machinery not initialized");
     if (PyType_Ready(&moduledef_type) < 0)
         return NULL;
     if (module->m_base.m_index == 0) {

From python-checkins at python.org  Wed Dec 15 01:53:37 2010
From: python-checkins at python.org (ezio.melotti)
Date: Wed, 15 Dec 2010 01:53:37 +0100 (CET)
Subject: [Python-checkins] r87253 -
	tracker/instances/python-dev/detectors/autonosy.py
Message-ID: <20101215005337.D91D4EE9EF@mail.python.org>

Author: ezio.melotti
Date: Wed Dec 15 01:53:37 2010
New Revision: 87253

Log:
#363: add automatically release managers to the nosy list for release blockers. Initial patch by Georg Brandl.

Modified:
   tracker/instances/python-dev/detectors/autonosy.py

Modified: tracker/instances/python-dev/detectors/autonosy.py
==============================================================================
--- tracker/instances/python-dev/detectors/autonosy.py	(original)
+++ tracker/instances/python-dev/detectors/autonosy.py	Wed Dec 15 01:53:37 2010
@@ -4,13 +4,15 @@
 # Python 2.3 ... 2.6 compatibility:
 from roundup.anypy.sets_ import set
 
-def autonosy(db, cl, nodeid, newvalues):
+RELEASE_MANAGERS = {
+    'Python 2.6': '19',   # barry
+    'Python 2.7': '4455', # benjamin.peterson
+    'Python 3.1': '4455', # benjamin.peterson
+    'Python 3.2': '93',   # georg.brandl
+}
 
-    if 'components' not in newvalues:
-        # Without components, nobody needs to be added as nosy
-        return
-    else:
-        components = newvalues['components']
+def autonosy(db, cl, nodeid, newvalues):
+    components = newvalues.get('components', [])
 
     nosy = set()
     if 'nosy' in newvalues:
@@ -26,6 +28,13 @@
         users = db.component.get(component, 'add_as_nosy')
         nosy |= set(users)
 
+    if 'priority' in newvalues:
+        if db.priority.get(newvalues['priority'], 'name') == 'release blocker':
+            for version in db.issue.get(nodeid, 'versions'):
+                name = db.version.get(version, 'name')
+                if name in RELEASE_MANAGERS:
+                    nosy.add(RELEASE_MANAGERS[name])
+
     newvalues['nosy'] = list(nosy)
 
 

From python-checkins at python.org  Wed Dec 15 02:11:35 2010
From: python-checkins at python.org (ezio.melotti)
Date: Wed, 15 Dec 2010 02:11:35 +0100 (CET)
Subject: [Python-checkins] r87254 - tracker/instances/jython/html/page.html
Message-ID: <20101215011135.73A64EE982@mail.python.org>

Author: ezio.melotti
Date: Wed Dec 15 02:11:35 2010
New Revision: 87254

Log:
Remove obsolete link

Modified:
   tracker/instances/jython/html/page.html

Modified: tracker/instances/jython/html/page.html
==============================================================================
--- tracker/instances/jython/html/page.html	(original)
+++ tracker/instances/jython/html/page.html	Wed Dec 15 02:11:35 2010
@@ -257,9 +257,6 @@
               User Guide
             
             
-